(Or: How I Learned to Stop WSLing and Love the VM)
In an earlier Hacktoberfest post, I noted how new open source contributors typically find it more challenging to configure the development environment necessary to work on an open source project than to actually resolve an issue that project has (especially in the absence of beginner-friendly documentation).
In my last Hacktoberfest post, I stated that my next pull request would be to Comcast‘s Go-based RestfulHttpsProxy project—and it was! I am proud to say that I managed to tackle an issue that I found quite intimidating and challenging throughout the time I spent working on it.
On the surface, a fix for this issue appeared simple: I was very much accustomed implementing command line arguments (e.g. in C++).
However, my task was complicated by several factors:
- The project is written in Go, a language with which I had no prior experience.
- Because the project is built and run via the
makecommand, command line arguments must be sent to the makefile—and possibly passed back-and-forth between the makefile and dockerfile—from which they are received by the project’s main function.
- Although I used
makewhen working on Layer5.io, I had no prior experience actually writing makefiles (or dockerfiles).
- I also had no prior experience building and running Docker containers (which was evidently needed to fully test my changes).
- Although I used
- The project is quite highly-technical, dealing with proxy rewrite rules. I still cannot pretend to fully understand its scope or purpose.
- The project also appears to be quite new and is relatively small: apart from the sole repository manager, I appear to be (at the time of writing) the only outside (non-Comcast) contributor!
- Unfortunately, this meant that I had no highly-responsive community that I could fall back on for support, like I had when working on Layer5.
I prefer to code on my laptop. Although it runs Windows 10 Home Edition, I had yet to encounter any issues setting up any Linux-based development environment through the use of Windows Subsystem for Linux (WSL) Ubuntu… until this project.
I had heard great things about Docker, and when I realized that I would have to set it up to test my work, I was eager to get it running on my machine. Unfortunately, it was not easy.
I learned quickly learned that Docker for Windows is not compatible with Windows 10 Home Edition.
Sure, no problem: I could just run Docker Engine for Ubuntu via WSL, right?
Well, I discovered that that is not possible, either. (WSL2 may be able to do so, but is only available to ‘Windows Insiders’.)
I realized that at this point, my only option would be to run Docker from within a Linux virtual machine. However, I found myself too stubborn to let go of including my beloved WSL in my development environment (I was perhaps annoyed about needing to virtualize Linux when I was already using WSL). This stubbornness ended up costing me a lot of wasted time.
I found two great blog posts detailing how to connect WSL to a remote Docker daemon running on either Docker for Windows or a Linux virtual machine. I followed the advice in the posts, Unfortunately, I was ultimately not successful in doing so. The good news is that I didn’t actually need to do this: I only had to install Docker Engine in the virtual machine. After doing so, I was able to move on to actually work on the issue!
(Unfortunately, I found myself unable to copy and paste from my host OS to my Ubuntu Server guest. I typed my development environment into existence and resolved this issue keystroke by keystroke… I now virtualize Ubuntu Desktop instead.)
After wading through a fair bit of documentation on Golang,
make and Docker, I learned how to pass command line variables to, from and between makefiles and dockerfiles, to ultimately be captured into the main Go function.
My task necessitated that I learn some interesting things about dockerfiles, such as the difference between a dockerfile’s build-time variables (ARG) versus its environment variables (ENV):
Ultimately, I was able to implement command line argument passing for each of the possible use cases (i.e. makefile targets). More importantly, I was able to test my work by building and running the project both within and without a Docker container. After accomplishing this, I opened a pull request:
By tackling this issue, I believe that I have met my stated goal of challenging myself during this Hacktoberfest.
However, the challenge does not end here: the fourth and final issue I plan to tackle this Hacktoberfest will not only be quite challenging, but will also seek to meet my final goal of contributing to a “close-to-home” project.