Bootstrapping developer environments for OpenStack

When I first joined OpenStack, it was incredibly hard to get a development environment working. Its better now in some ways, but not in others.

There are three key things.

Firstly, if you’re going to run devstack (or equally tempest-on-devstack), make a dedicated VM to do it. Use whatever hypervisor you want, but don’t you dare run it on baremetal. Yes it can work on baremetal, but you’ll spend way more time learning about quirks than getting stuff done. Once you’re familiar with devstack you can make an educated choice.

Secondly, if you’re not running devstack [e.g. you’re just hacking on an oslo library or gertty or something] there are a bunch of system packages that will need installing to let various Python packages compile. This was one of the places that was hardest to get going on when I started, and still is pretty hard. I started the bindep project to address this, and its in the process of being rolled out now within OpenStack projects. If the project you’re hacking on has an other-requirements.txt file, then you can just do sudo apt-get install $(bindep -b) – but you’ll need bindep installed first, and its not in distros yet. If there is no such file there is a master fallback one which brings in everything maintained by the OpenStack Infra team. Download it somewhere and add the -f bindep-fallback.txt to your bindep call.

Which brings me to the last point. How do you get bootstrapped with bindep and tox and all the other things that you’ll need. The OpenStack developer docs tell you to install system-wide using apt-get install, and then system-wide install tox. This usually works, but isn’t suitable for multi-user machines, and some distributions don’t include enough metadata for pip to do the right thing, and its confusing to have two different systems managing the same packages.

I prefer to use virtualenv directly, with no reliance on system packages other than truely global things like Python itself. virtualenv is a lovely thing, and it bundles three other important Python tools – pip, wheel and setuptools. All combined this will let you get a fully up to date development environment going without root access – and without confusing your package manager. I still use it even with Python versions that include the venv module, because having the bundled components be up to date is important.

With a virtualenv to host tox and bindep and any other globally-relevant tools, you can run those tools without interacting with your system package manager at all[except when you finally remove the version of Python they use from the system].

Here is how I accomplish this.

  1. Start with Python [any version (2.7 or newer)] installed.
  2. pick a place to make the virtualenv. E.g. ~/devtools
  3. Get a copy of virtualenv to run locally from source. 13.1.0 is a good safe version (at time of writing).
  4. cd into virtualenv-13.1.0 (or whatever number)
  5. Run python ./virtualenv.py ~/devtools
  6. Activate the virtualenv
  7. Install bindep and tox and anything else you need globally using pip. The pip in the virtualenv will be nice and fresh so you’ll get full caching and so on.
  8. (optional) symlink those tools into your user specific path. E.g. from ~/devtools/bin to ~/bin, or some similar directory.
    There are two key gotchas here. Firstly, if you use a bind-dir mounted home in containers, you won’t want this in your user path, since venvs are not very portable. Instead make a per-container path directory you can symlink into.
    Secondly, there is cruft in ~/devtools/bin, so don’t even for a second think of just adding it to your PATH: you’ll end up running the python within the virtualenv by mistake at some point and deeply regretting it.
    If you don’t do this, then just activate the virtualenv any time you want to use the tools.

And now you can circle back, use bindep to install binary dependencies, and off you go!