One of the nice features of Docker 1.13 is the rationalisation of their CLI. Now the `docker` arguments are all neatly organised around a common schema making it easier to work out what command you need to use. The benefits of a well thought out CLI are enormous, particularly when automating tasks for CI pipelines or scheduled operations tasks. However the main drawback with textual interfaces like the command-line has always been discoverability. With a GUI the options are there in front of you, or at most hidden behind the click of a mouse on a menu or drop-down list. Sometimes it can feel like you are stuck back in the seventies with the worst of Unix elitism: what do you mean you didn't know that the -B flag can't be used when you set the depth to seven with the -S option, obviously you should have been using -Q 3 to force compatibility mode!
Fortunately, modern shells have the answer with tab completion. This is available for most of the built-in commands and usually supported by third party tools via a completion script that is either installed at the same time as the tool or can be downloaded or generated afterwards. So, let's look at improving things for users of Brooklyn and Cloudsoft AMP, with maybe some extra help for a few common container management systems as well.
Brooklyn has now been shipping with a command-line interface for the past few releases, written in Go and talking to our REST API. Due to the shared open-source heritage, all Brooklyn commands are also compatible with Cloudsoft AMP so assume that I am referring to both for the rest of this post.
The command-line client can be installed on Linux, OSX or Windows, and is available for download on the Brooklyn website. For example, to install on a Linux machine use the following commands:
% wget https://s.apache.org/VFt1 \ -O apache-brooklyn-0.10.0-client-cli-linux.tar.gz % tar zxf apache-brooklyn-0.10.0-client-cli-linux.tar.gz % cd apache-brooklyn-0.10.0-client-cli-linux % sudo cp br /usr/local/bin % sudo chmod 755 /usr/local/bin/br
Once that is done, you can log in to a running Brooklyn server and perform all the tasks that the UI makes available, such as listing entities, starting and stopping applications, retrieving sensor values and executing effectors. For example, here we are connecting to Brooklyn and finding the host name and port number for connecting to a running web application:
% br login http://brooklyn.example.org:8081/ guest Enter Password: Connected to Brooklyn version 0.11.0-SNAPSHOT at http://brooklyn.example.org:8081 % br application Id | Name | Status | Location t2nk41gcqg | wordpress | RUNNING | xdvtwoprye % br application t2nk41gcqg entity Id | Name | Type ve7qrj46zk | mysql | org.apache.brooklyn.entity.database.mysql.MySqlNode aqapl0919b | tomcat | org.apache.brooklyn.entity.webapp.tomcat.TomcatServer % br application t2nk41gcqg entity aqapl0919b sensor host.address 10.250.0.104 % br application t2nk41gcqg entity aqapl0919b sensor http.port 8080 % br application t2nk41gcqg entity aqapl0919b http.port.mapped.public 184.108.40.206:30456
Note that the last line was required because this application happened to be running on Docker, so we need to know the correct address to connect over the Internet, not the IP address and port the container is using internally.
Once we are happy that the application is working, perhaps by using this information
curl and retrieve some HTML, we might no longer need to keep this instance
running. Again, we can perform any task that is possible from the UI, in this
case calling the stop effector:
% br application t2nk41gcqg stop % br application t2nk41gcqg Application 't2nk41gcqg' not found 404
So, this is all good so far, but we are not doing well on the discoverability
side. There is help text available, as seen by running
which outputs the following:
% br help NAME: br - A Brooklyn command line client application USAGE: br [global options] command [command options] [arguments...] VERSION: 0.10.0 ...
But as well as this we can add bash auto-completion. This is not yet part of the Brooklyn codebase, and is strictly experimental at present, so the usual caveats apply. In fact, I created this project to learn more about how bash auto-completion technology works, so it is my very first implementation of one. The code is available on GitHub at brooklyncentral/brooklyn-bash-completion and consists of a single file, also named br.
The completion script is probably in need of some expert attention, and I
would also like to add support for more of the Brooklyn commands, but it
is definitely usable and I find it invaluable. I have also discovered
that there are some features that could be added to
br itself that would
make implementing auto-completion much simpler. For instance, options for all
the commands that cause it to return unadorned text, such as a list of entity
IDs one per line, or being able to pass in Go template strings that would
allow formatting lines of output in this way. Looking at the way that tools
kubectl works is instructive here, as it also support this
feature and uses it in its completion script.
With all that said, here's how to get started with
br auto-completion script
for bash. First, make sure that auto-completion is supported, and actually installed!
This means installing using MacPorts or HomeBrew on OSX; with Linux use your
distribution's usual package manager. Install the
package, which should create a directory where completion scripts can be installed.
This is usually something like
/etc/bash_completion.d or on OSX
/opt/local/etc/bash_completion.d but check the documentation or
one of the many tutorials to be sure. Once you have determined the correct
location, you simply copy the `br.sh` script there, and source it if you want
to be able to use it without logging in again:
% wget https://git.io/vDzkZ -O br % sudo cp br /etc/bash_completion.d % . /etc/bash_completion.d/br
Although nothing seems to have happened, you now have the power! Implemented completions include command names, application and entity ids, sensor names and catalog and blueprint files. For example, this is how a deployment of a YAML blueprint to AWS would look:
% br dep<TAB>loy exam<TAB>ple.yaml Id: | i85xkp9i2c Name: | example Status: | In progress % br app<TAB>lication i8<TAB>5xkp9i2c Id: | i85xkp9i2c Name: | example Status: | RUNNING ServiceUp: | true Type: | org.apache.brooklyn.entity.stock.BasicApplication CatalogItemId: | centos7-software-process:0.11.0-SNAPSHOT LocationId: | xdvtwoprye LocationName: | AWS Europe Central 1 with CentOS 7 LocationSpec: | jclouds:aws-ec2 LocationType: | org.apache.brooklyn.location.jclouds.JcloudsLocation % br app<TAB>lication i8<TAB>5xkp9i2c se<TAB>nsor ser<TAB>vice.<TAB> service.isUp service.notUp.indicators service.problems service.state service.state.expected % br application i85xkp9i2c sensor service.is<TAB>Up true
So, there we have it. As mentioned earlier, this was my first attempt at writing a completion helper script, and I think it needs a LOT more work. However, even in the rudimentary state it is in now, it makes my life a lot easier when using Brooklyn, and I hope that by getting more people to use it bugs will be discovered and fixed much faster.
And here are the promised Kubernetes instructions. The
actually comes with a self-installing bash completion script, which can be
enabled for the current shell as follows:
% . <(kubectl completion bash)
To keep it around for your next login, save the output of the command and copy it to your completion directory as with the `br` instructions above, like this:
% kubectl completion bash > kubectl.sh % sudo cp kubectl.sh /etc/bash_completion.d/kubectl.sh
I find this a huge time saver when debugging Kubernetes issues.
Finally, as we all know, The perfect is the enemy of the good and the
script is definitely not perfect, but I hope this post will encourage someone
to take a look at the code, and perhaps move it somewhat closer to good
territory... Simply clone the brooklyncental/brooklyn-bash-completion
repository and file an issue or create a pull request! Eventually, I even hope that
it could even improve to a state where it can be
included with the Brooklyn command-line client.