Expediting local isolation with Docker and Juju

Docker containersAs a Juju charmer, I often find myself irate at the level of dependencies I’m installing on my workstation just to review OPC (Other Peoples Code). Though there are usually systems to isolate these dependencies like virtualenv and tools of this nature – nothing really beats having your own isolated system to catch all these dependencies and nuke them from orbit when you’re done with them.

Charmbox – a chapter from my workflow

A couple weeks ago we announced the GA of our experimental Docker images for testing the latest TRUNK and to isolate your charm development experience. The docker images are much lighter weight than the vagrant counterpart (even though most systems that are not linux leverage a middleware solution of virtualization in some fashion – boot2docker is actually spinning up docker containers in a VM – nifty right?)

Leveraging charmbox has helped alleviate me from tainting my system with all the testing dependencies introduced by the review queue. Each charm can run the 00-setup script as root and install whatever unholiness is required to really leverage the charm. Most often this is as simple as just the amulet packages but some charms go even further and install full API SDK’s so they can really root around in the deployed service and validate we have a good configuration.

While this is excellent in theory – in practice – I wound up with > 8 GB of extra cruft installed, that I won’t be using in my own every-day charm development.

Workflow enhancement

Since we have this nifty isolation story – lets look at how we can somewhat supercharge the workflow, and what this looks like. I’ll only make 3 assumptions here.

  1. you’re using bash
  2. you have docker installed
  3. you want to manage charm context (Review, Work, Personal)

I have 3 particular contexts in which I will be focused on charms.

  • My personal network of services (in home services)
  • My obligations to canonical to develop interesting new workload charms
  • My obligations as a charmer to review incoming charms

With these clearly defined “scopes” of charms, I find it often handy to keep a repository of charms isolated in each context, and to work out of that particular repository until I have reached the end of my objective, and then I can switch contexts.

Show me the code

# This goes in .bashrc
# Load my custom exports
# Load my custom exports
if [ -f $HOME/.bash_exports ]; then	
	. $HOME/.bash_exports
fi
 
if [ -f ~/.bash_aliases ]; then
	. ~/.bash_aliases
fi 


# Check for which juju environment is loaded and execute based on contents 
if [ -f $HOME/.juju_repository_env ]; then 

	JEN=`cat $HOME/.juju_repository_env`
	if [ $JEN = 'work' ]; then
		jwork
	fi
	if [ $JEN = 'personal' ]; then
		jhome
	fi
	if [ $JEN = 'review' ]; then
		jreview
	fi
fi 
# This goes in .bash_aliases
# Move between work and personal juju context
# Depends on some special vars I have in bash_exports,
# and thats not tracked in my dotfiles repo
	jujuwork() 
	{
		export JUJU_REPOSITORY=$JUJU_WORK_REPO;
		echo "work" > $HOME/.juju_repository_env;
	} 
	
	jujupersonal()
	{
		export JUJU_REPOSITORY=$JUJU_PERSONAL_REPO;
		echo "personal" > $HOME/.juju_repository_env;
	}
	jujureview()
	{
		export JUJU_REPOSITORY=$JUJU_REVIEW_REPO;
		echo "review" > $HOME/.juju_repository_env;
	}

	alias jwork=jujuwork
	alias jhome=jujupersonal
	alias jreview=jujureview 

# This goes in .bash_exports, but can live in .bash_aliases or .bashrc
JUJU_WORK_REPO="$HOME/projects/work/charms"
JUJU_PERSONAL_REPO="$HOME/projects/charms"
JUJU_REVIEW_REPO="$HOME/tmp/charms"

How this works

The repositories setup in $HOME/.bash_exports manage the pointers to my charm repository directories, and resemble any other charm repo, separated out by series/service

The methods declared allow me to run a single command to switch the context of my exported $JUJU_REPOSITORY – and set a sentinel file that is read on each new shell execution.

The bits in $HOME/.bashrc are run on each new shell, and correctly set the context of my $JUJU_REPOSITORY without any manual intervention. What I set as my last context, will be the context of my next shell.

Thats great, but what does this have to do with Docker?

Really glad you asked! I spoke to the isolation, and contexts earlier – now lets see how we can bridge the gap here to make this as seamless as possible.

alias charmbox='docker run --rm -v $HOME/.juju:/home/ubuntu/.juju -v
$JUJU_REPOSITORY/trusty:/home/ubuntu/trusty -v $JUJU_REPOSITORY/precise:/home/ubuntu/precise -ti johnsca/charmbox'

The following alias when added to ~/.bash_aliases will give you the charmbox command. Which will spin up the appropriate docker container, and mount your charm archives in the charmbox environment. Whats nice is you didn’t have to do any further fuddling with commands, and you automatically get the context you’re in mounted into the charmbox. With the –rm passed to docker, anything we have done in the image is immediately removed once we exit the context of the docker container, so we get fresh results, every time.

Deploy happy 🙂

[Original post]

Ubuntu cloud

Ubuntu offers all the training, software infrastructure, tools, services and support you need for your public and private clouds.

Newsletter signup

Select topics you’re
interested in

In submitting this form, I confirm that I have read and agree to Canonical’s Privacy Notice and Privacy Policy.

Related posts

DevOps tools in 2020: Why consider Juju?

Many DevOps tools struggle as deployments change. Juju excels. 2020 heralds a decade for a divided technology industry. Software delivery is diversifying....

Infrastructure-as-Code mistakes and how to avoid them

Two industry trends point to a gap in DevOps tooling chosen by many. Operations teams need more than an Infrastructure-as-Code approach, but a complete...

Data Ops at petabyte scale

Should you deploy Apache Spark to Kubernetes? Learn how model-driven operations have enabled one data engineering team to evaluate several options and come to...