History

It feels like a lifetime ago, well, 3 years is a lifetime in tech, that I wrote a blog post explaining how we rewrote our API server from Golang to Ruby on Rails. Here we are and I'm about to explain about how we've been back and forth doing the same thing for our CLI.

Just after that time, I wrote the first version of our CLI utility in Golang. However, with only me knowing Golang on the team, we weren't able to achieve the velocity and pace of adding features within the CLI as I'd like. So we rewrote it as a Rubygem and everything went swimmingly well, launching the first version in on the 20th of February 2019.

However, when we launched our Kube100 beta (the world's first k3s managed service, check it out if you haven't already) we had quite a few in our community express a clear opinion of "why do I have to install Ruby to use your CLI?", "it doesn't work with the version of Ruby we have installed!", etc. The first step was to make a Docker container version, to isolate its requirements from the rest of the system. This was launched on the 3rd of December 2019 and a lot of the issues/problems were resolved.

Civo Go CLI

This still didn't quieten a nagging voice I had in the back of my head when using the CLI personally. "Wow, it's really slow to start up!" A quick test of it using time civo apikeys ls says it took 4.533 seconds to run. That command doesn't make any API calls, just reads a local JSON configuration file, parses it and displays it.

What to do?

If we go back to the old Golang-based version there would be a LOT to do to bring it up to scratch. We'd also made the decision within the company to standardise on Ruby and Ruby on Rails, as that's our core competence. Also, if we were to resurrect that old client, I'm fairly sure that early code was written more "Ruby using Go syntax" style rather than idiomatic Go.

We're in a different place now though, to where we were when we decided to rewrite our API server to Ruby (early 2017) and to where we even were when we wrote the first Rubygem version (early 2019). We are now a Kubernetes company, focused on that platform and carving out our own niche within the ecosystem. Kubernetes is Go-based, all the tooling around it, the core platform itself, everything is Go-based. So now we're in a world where our team needs to write Go code anyway.

We need a decent Go client library for our API (so our Kubernetes extensions can interact with it), so we started with that. Then one of our community (now a member of our team) started work on the Terraform module for us (again, Go-based) that uses that client library, while at the same time I started the task of rewriting our CLI from Ruby to Go. There were things I wanted to improve on while we did it, for example, the ability to have custom formatted output for piping in to other scripts.

And goodness knows, I wanted it to be faster to run!

And the new...

So today we are officially announcing the old Rubygem-based CLI is deprecated and has been replaced with our new Go-based version. This means it's a smaller download, easier to install, quicker to run and has some cool features for easier integration in to your own scripts.

To install it on your system, the two easiest ways are using Homebrew if you're using a Mac:

brew tap civo/tools
brew install civo

Or to use a fairly standard curl | sh type mechanism if you're either not running Homebrew on your Mac, or are running Linux (or Windows):

curl -sL https://civo.com/get | sh

After that, you can run it exactly the same as you did before. The same commands work, the same aliases are in place, it uses the same key configuration you already have saved, etc. We've updated the Docker image too, so if you still prefer to use Docker and keep your system clean, that still works.

The time to run that time civo apikeys ls command has reduced from 4.533 seconds to 0.113 seconds. You now also can specify a custom output format. So if you just want a list of the IDs of your k3s clusters, under Ruby you'd have to do this:

civo k3s ls | tail -n -3 | grep -v "+----------" | cut -d" " -f2 

This ignores the first few lines as they're headers, removes the trailing table formatting, then splits out the fields on spaces and returns the second one (because the first one is again table formatting |). That's a pain in the butt!!

Now you can do:

civo k3s ls -o custom -f "ID:Name"

Or if you prefer to use Stephen Dolan's jq utility for more advanced chopping/munging:

civo k3s ls -o json | jq -r ".[].ID"

Screenshot of GitHub Action

If you want to use the civo command line client during a CI run on GitHub Actions, we have also built this in to a custom action ready for use - Civo GitHub Action

So, speed, ease of install, more flexible output - and this is only the first production release! We definitely welcome any of our beta testers trying it out and sharing comments in our community Slack. And if you don't already have access to the beta, apply to join today - you'll get $70 of credit every month to test us out.