Hacking on Juju
June 26, 2017
Working at Canonical, in the BootStack team, I work a lot with juju. We use juju for orchestrating and managing OpenStack 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.
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
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 resolved 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.
git remote add upstream https://github.com/juju/juju.git
git remote set-url origin firstname.lastname@example.org:devec0/juju.git. Replace
devec0 (my GitHub handle) with your own.
ln -s ../../scripts/pre-push.bash .git/hooks/pre-push This sets up a Git hook which keeps your branch synced up with upstream.
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.
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 install from the
$GOPATH/src/github.com/juju/juju directory to get your modified juju compiled and installed to your local
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