It has been quite a while since I've posted anything here - almost an entire year, which doesn't normally happen. Things have been pretty busy, though. I got married, changed jobs, and found plenty of trouble along the way. There was a 3-month period where life was happening and I did almost nothing in the open source world, which is clearly visible on my github profile activity stream.
However, in the last year, I have a few interesting things in technology that I think are worth mentioning.
Oaf
Oaf is the ruby framework I developed and mentioned in my previous post. Although it hasn't seen any major popularity, the tool has definitely been helpful to me on a number of occasions where I wanted to slap down a mock API really quick that actually performed some function. As an example, I used it to prototype an orchestration REST API which wrapped fabric. I think I probably wrote about 50 lines of bash scripts to make what I wanted happen. I definitely don't regret the time I spent making Oaf, especially with the continuous test lessons that I learned from it.
yum-rocket
I played around with parallelizing YUM downloads in RHEL6 with a small plugin
called yum-rocket. It substituted
urllib
in place of URLGrabber
to allow parallel downloads at the cost of two
things: single-file progress indication, and HTTP keepalive's. The progress
indication I really did not care about so much as I could see how many files had
downloaded / how many total downloads. The keepalive connections, however, were
an interesting thing to observe. Even though
yum-rocket could be downloading using
as many threads as possible, in some cases the original URLGrabber
interface
performed better. I think it really came down to the mirrors which were selected
for the particular session. yum-rocket
would also pull from multiple source repositories, which in some cases would get
around QOS/bandwidth limitations enforced on a per-connection level from remote
hosts. At times this proved to be extremely helpful, especially in conjunction
with the yum-fastestmirror
plugin, which would essentially allow you to
download from the "fastest-N" mirrors concurrently. There are definitely cases
where this hurt performance though, for instance if you have a local mirror with
everything you need but you have configured yum-rocket to span up to 5 mirrors,
you would probably get worse performance than just sticking to your one local
mirror. All in all, good learning experience in plugin systems for interpreted
languages.
slide.sh
This one was really me going off on a tangent with a little idea I had to create slide decks in my terminal. At the time, I worked for Cisco Systems, and while my role there didn't ordinarily have me creating slide decks, I loathed powerpoint so much that I made a shell script to display some text, pause, and advance to the next slide when I was ready. I used it a few times at Cisco, and it worked well. Having some initial success with it, I added things like horizontal rules, color text, in-slide pause, and more. I presented at PuppetConf 2013 with slide.sh, which went well, despite spilling over into GitHub's timeslot. Sorry, dudes.
pakrat
pakrat is a YUM repo snapshotter tool for use with RHEL6 (almost exclusively).
For a while, Keith Chambers and I were really into snapshotting package repositories as a way of version controlling an entire operating system. RightScale was doing it pretty much how we wanted to do it, so we made a ghetto prototype using a curl script with a few loops in it. It worked surprisingly well, and even when we didn't check on it for a few months, whenever we would come back to it, it was chugging along, doing it's thing. I decided to make a more formal implementation, although I made a few mistakes in doing so. My first mistake was insisting on using the existing YUM libraries. This worked great on RHEL distributions, but anywhere outside of RHEL, it was pretty much impossible to use. And now that RHEL6 and its version of the YUM libraries will soon be obsolete, the library would make little sense to use anywhere else. The other mistakes were more minor, things like the command line syntax and whatnot. Nonetheless, pakrat was another good learning experience and actually had a fairly decent progress indication subsystem.
serf
Since early this year, I have been helping @hashicorp implement some features in their peer discovery/orchestration framework known as serf. Hashicorp (both @armon and @mitchellh) are just awesome to work with. I helped with a few things like the key rotation feature, among other things. The time I've spent working on serf and learning from the team has definitely not been mis-spent.
go-otp
While working on serf, @armon and I discussed the idea of using "one-time pads" as a way of ensuring perfect forward security during Serf's key exchange. The final design ended up a little different, but the conversation led me to create go-otp, which is a very small reference implementation of the OTP concept and how it can be applied using golang.
columnize
Also while working on serf, I cleaned up
some of the command-line output by writing a simple little library called
columnize for golang. It will take a
list of strings, and produce perfectly aligned columns of output without relying
on tabs (\t
). I've used it in a number of side projects and it is still
currently in use in both serf and
consul.
go-semver
go-semver is a library providing easy access to semantic versioning logic in golang. It allows you to parse version numbers and compare them.
ruby-aptly
I spent about 6 months trying to work with Ubuntu as a base operating system, as
the product I was working on at the time was running OpenStack and the
enterprise support was best for Ubuntu. I really hated using .deb
packages,
and found the standard tooling to be nauseating, but thankfully a smart guy
@smira realized the same and did something about it
with aptly. While young in its life, aptly
offers some impressive features, including repository snapshots and snapshot
merging. I worked briefly with @smira on aptly, and
eventually created a quick ruby wrapper around its cli, called
ruby-aptly. While not the most elegant
thing I've written, it made writing higher-level logic around how to compose our
release of debian packages much easier than it could have been.
go-glob
While developing a new project in golang, I found it odd that POSIX basic (non-ERE) regualr expressions were not implemented anywhere that I could find. This didn't bother me until I wanted to provide a command-line interface that allows passing a string glob in using the '*' character as a wildcard. There were a few IO-related packages that had functionality close to what I wanted, but no exact matches. I ended up implementing just the globbing part as part of a new golang package called go-glob.
go-license
During development of another project, I found the need to scan license text for different software packages and guess what license type the text described. I also saw a need for a standardized set if string identifiers for license types which just doesn't exist right now. I ended up created go-license in golang to satisfy both use cases.
huck
After making a career change and joining a team of engineers who think purely in cloud concepts, I saw a fairly common pattern in some things we were doing that could be standardized, so I spent a week over nights and weekends creating huck, which is a pretty small ruby framework for tossing messages into a queue and executing logic based on it from the remote end. I debated open sourcing the framework to myself, as I know there are probably better ways for some of huck's use cases to be implemented, but nonetheless, I decided to realease it because a framework is better than re-implementing something 5 different times using different sets of scripts that are all doing something similar.
So all in all, summer 2013 to summer 2014 was a pretty okay year in code for me, but I still think I can do better and hopefully can prove that during this year. I have been hacking away on a new project which I plan to open source sometime in the coming months, and there will likely be more small golang libraries to support it as I develop more on it.