Power Of C - Micro Cloud Init(mcinit)
I've been exploring packet.net, which is a Hardware-As-A-Service. A HaaS, appears to be the user or administrator like a cloud. You can "create" machines, delete them, and do a variety of task, just like you do in Amazon, Azure, and other providers, except, there is one big difference. In HaaS you are actually allocating physical boxes, while in more traditional IaaS, your creating virtual machines.
So in my exploration of packet.net, I wanted to be able to use RHEL (Red Hat Enterprise Linux). Packet.net has a nice ipxe implementation, which I managed to get my RHEL image installed and auto-installed. But then I was forced to use a user name and password. I needed to use packet.net metadata service. I ask there wonderful customer service, which did help me alot thru this journey, but how to use the metadata service was beyond their support scope.
So I looked at the traditional cloudinit, to do the job, and noticed it was written in python, and was not in the main RHEL channels. I was trying to make my installs as fast as possible, and as lean, so pulling a large number of dependencies was a killer.
So I decided, that writing my own, was a faster way of getting it done. After all, this is read some data in json format via rest, and update a few files. My 2017 goto language is nodejs, which I've very productive in. So I created that really quick. It was all of 36 lines of code. Then, thinking how do I get this "inside" my RHEL box early in the process. My thought process was "make it a executable", as I didnt want to pull nodejs install for a utility that was going to last seconds.
So I tried several tools to package my nodejs into a executable. Such as pkg. The big problem is, the executable generated was 30-50 Gigabytes of data. A small linux distro is that size. So that turned into a non-starter.
So thinking, what language framework is in the minimal install. C or Python. The problem I'd have if using python, is while its installed, I would end up with more python libraries installed, slowing things down more. So then the choice is "C".
So I have done some primitive "C" REST work, that prove's it is feasible to do, but this needed to be even more intense that the prevous work. So decided to look for rest client libraries. After looking for a bit, I realized I just could use curl lib, and for the json data, use the json-c library. After this it was pretty easy. The result was 192 lines of code. While a bit more "wordy" than nodejs, the compiled version was 33.3KB. YES, that is what I called optimal.
I wrapped it in a RPM, using the excellent togo rpm builder, and gave it a whirl. The result was a secure RHEL physical machine, with my ssh keys automatically set, from the packet.net web page.
So checkout mcinit at https://github.com/glennswest/mcinit
With a bit of work, could easily wrap curl and json-c into a easy to use rest client framework. And the linecount would drop to the same as nodejs. The executable size wins every time.
C wins again.
Happy to hear that.
Hey Glenn, thanks for the writeup! We hope to have RHEL as a 1st class OS in the next few weeks (pending some licensing work). Awesome to see you leverage our iPXE feature + cloudinit.
Sure - it's in my next article - drop me a mail and I can even help u set up a complete environment - micro service dns plus microservices ipxe server and the scripts and kickstarts