Hacking on Juju

Last Updated:
tags: juju golang git
categories: juju


Whilst at Canonical, in the BootStack team, I worked a lot with juju. We used juju for orchestrating and managing OpenStack and Kubernetes clouds for customers, and internally.

Juju is a modelling tool that allows workloads with many moving parts to be described, deployed and managed on baremetal (with MaaS), containers (with LXD) and/or up to public cloud providers (it supports a whole bunch of them).

People often liken Juju to tools like Puppet, Chef, Ansible, but the truth is it's not just useful for managing the configuration of your services. Juju is designed to be the tool that you use to manage the entire lifecycle of your services, as it covers deployment, scaling, management, upgrades and eventual teardown of services, and the relationships between them.

Once a service is charmed, juju is your go-to tool for managing that service. There's a good guide on getting started with Juju on LXD and ZFS, too.

That's all pretty cool, but you said something about hacking

I recently started hacking on the Juju code itself, and after following the documentation, thought to distil what I learned into a quick-start.

Making sure you have golang installed and your $GOPATH set somewhere useful.

apt-get install golang git will install golang and git under Ubuntu, both of which are required for checking out and building juju.

export GOPATH=~/.go will set your $GOPATH to the .go directory in your home folder.

$GOPATH is basically a user-accessible working directory. Source code is stored here for dependencies when installing via go get, and go install and go build will also store data needed by your golang project here. Full reference.

I use a single $GOPATH for all of my golang projects, so I set export GOPATH=~/.go in my .bashrc.

Getting Juju checked out and fetching dependencies

Get a copy of the latest development Juju code by running go get -d -v github.com/juju/juju/...

This will resolve and checkout https://github.com/juju/juju to $GOPATH/src/github.com/juju/juju, and will do the same for any packages used in the go code within the juju package, which have not already been checked out.

Juju requires an extra step, in order to get all required development dependencies at the appropriate versions.

Firstly, get the godeps utility with go get github.com/rogpeppe/godeps.

Then, from the $GOPATH/src/github.com/juju/juju directory run godeps -u dependencies.tsv

Finally, you will want to run make install-dependencies to get the remaining supporting tools installed.

Set up your forked repository.

Create a repository called 'juju' under your own GitHub account.

You then need to configure your Git remotes.

cd $GOPATH/src/github.com/juju/juju
git remote add upstream https://github.com/juju/juju.git
# replace devec0 with your account below
git remote set-url origin git@github.com:devec0/juju.git
# This sets up a Git Hook
# The hook keeps your branch synced with upstream.
ln -s ../../scripts/pre-push.bash .git/hooks/pre-push

*Some further reading on Git hooks.

Push the current code to your forked repo with git push -u upstream master. The -u tells Git to track this branch, making it your default for push and pull operations.

Hack away! You are now ready to make changes.

Tip - to build juju you can run go build github.com/juju/juju/... - but you can also just run make as shorthand.

make install will also install your juju binary to your local $GOPATH/bin folder, just as go install github.com/juju/juju/... would.

So once you have your deps sorted out per above, you just need to run make and make install from the $GOPATH/src/github.com/juju/juju directory to get your modified juju compiled and installed to your local $GOPATH

You should be able to do the following. The version will vary on your machine if you are not running Ubuntu 17.04.

At time of writing the development series of Juju is 2.2, so that is the version a checkout of master will give you.

$ ~/.go/bin/juju --version 2.2-beta1-zesty-amd64