In this blog post I aim to discuss how you could go about using OpenStack-Ansible as a development environment for OpenStack. Since all OpenStack services are built from source within OpenStack-Ansible, this has been a consistently requested feature for quite some time.
At the recent OpenStack Summit in Boston, I spoke a bit about the developer mode work we've been working on within the OpenStack-Ansible project.
To begin, we had a singular way to achieve this. But it was manual, and long-winded:
- Setup your own private git repository for your project or service.
- Commit your changes to your private git_repo.
- Adjust the repos specific git_repo variable (e.g. nova_git_repo: https://github.com/andymcc/nova)
- Adjust the repos specific git_install_branch variable, if on a specific branch (e.g. nova_git_install_branch: my_test_branch)
- Run the setup plays.
This works, and is fine, but it's not particularly agile. It also means you have to continually commit and push to a remote location, re-run the install, rinse and repeat. Additionally, it was limited to projects with a "*_git_repo" variable already setup. For example, if you wanted to test a change you are writing to python-memcached, you would not be able to, since we installed this directly from PyPi (in developer mode).
Version 1: Keystone Proof of Concept for local developer mode.
Before the summit, we had proposed a Proof of Concept developer mode test for Keystone, which would allow you to clone the Keystone repository locally, write some code, and then push the changes from your local directory to the containers.
This worked fine, but had a few limitations.
- It works for Keystone only, and is not generic.
- This still requires code to be committed. For example, you can write some patch locally, but if you don't do a "git add" and a "git commit" it won't be included in the build on the containers.
- Only works with Keystone.
Since then, we've spent some time improving that and making it more generic as a whole, and we've finally got that merged and working. So, without further ado!
All NEW developer mode for OpenStack-Ansible
The new approach is simpler and far more generic, and allows you to test local patches to any upstream repositories for projects that are installed via pip.
"That sounds great, but how do I do that?", I hear you say! Well... I'm glad you asked!
To use this, all you need to do is the following:
- Get yourself an Ubuntu 16.04 or CentOS 7 testing server (for example a suitable VM or Cloud Instance).
- Select and use git to clone the role for which you want to test, for example nova would be the openstack-ansible-os_nova role, which you could get clone from "https://github.com/openstack/openstack-ansible-os_nova"
- Clone the upstream repository you want to test or develop on, into ~/git/openstack/.
- Make your changes and develop away.
- Run the scenario using tox, or the run_tests.sh in the openstack-ansible-os_nova role directory.
If the ~/git/openstack/ directory doesn't seem suitable for your purposes you can set the directory by setting the development_repo_directory variable inside the os-rolename_overrides.yml file inside the role repositories tests directory. For example, adding development_repo_directory: /path/to/my/repo_dir to the openstack-ansible-os_nova\tests\os-nova_overrides.yml file.
Note: You need to do this before your first run, and ideally don't change it afterwards (unless you plan on doing a full run, which will delete and recreate containers).
This will work for any pip package that are installed, for example, if you want to develop on libvirt-python, ensure that you clone it as the ~/git/openstack/libvirt-python directory, and develop there. This will also work with multiple packages, as long as they are all cloned into ~/git/openstack/. This also means you can develop on Keystone with your Nova deployment, by cloning Keystone into the ~/git/openstack/- directory.
It's also important to note, once you have a setup configured, for example you are testing Nova, you don't need to do a full re-deploy, you can just run the specific playbook for deploying nova, and skip redeploying all containers.
How does it work?
OpenStack-Ansible already has the functionality to install pip packages with constraints files. Using constraints files we can specify the location of a package as being file based, for example: file:///my/path/keystone#egg=keystone. This will ensure that if the constraints file is applied, and the Keystone package is installed, it will be installed from the file path specified instead of from an upstream git repository.
At this point, we loop through all the directories we find in the development_repo_directory directory, and generate a constraints file based on the directories we find. In this way, when you go to install any package that has a directory in development_repo_directory with the same name as the package, it will use the local file location as the location to install the package from.
This constraints file is then applied as the first constraints file (which will mean it takes precedence over any other constraints or options) when doing any pip installs and as a result, any packages listed in the constraints file will be installed from the file location.
The only other step is to mount the development_repo_directory into the containers at the same location. In other words, if it's /opt/repos on your host, it'll be /opt/repo in the containers - this is to ensure that services such as Nova (which will deploy compute onto localhost) use the same location as services in containers. The aim is that you don't have to log into the container.
All the OpenStack-Ansible roles are now ready to go, with the exception of the Monasca role (which is currently being reworked).
We'll be adding some documentation to the official OpenStack-Ansible docs to explain how to use the developer mode.
But most importantly - give it a go! If you have any questions, or need feedback jump into the #openstack-ansible IRC channel on freenode, or reach out to andymccr (me) on Freenode and let me know your thoughts and feedback!