create / delete an OpenStack instance with python-openstackclient

The python-openstackclient library has an example that provides the basic structure for a new command (the auth_url problem workaround may be needed). To create a virtual machine with 1GB RAM, 1CPU, ubuntu-14.04, using the teuthology keypair on the fsf-lan network, the matching flavor, image, keypair and network objects can be found with:

    for flavor in client_manager.compute.flavors.list():
        if flavor.ram == 1024 and flavor.vcpus == 1:
            break
    for network in client_manager.compute.networks.list():
        if network.label == 'fsf-lan':
            break
    for image in client_manager.compute.images.list():
        if 'ubuntu' in image.name and '14.04' in image.name:
            break
    for keypair in client_manager.compute.keypairs.list():
        if keypair.name == 'teuthology':
            break

The test instance can then be created

   server = client_manager.compute.servers.create('test',
                        image, flavor,
                        key_name=keypair.name,
                        nics=[{'net-id': network.id}])

but it won’t be immediately active and the wait_for_status can be used to block until it is:

from openstackclient.common import utils
...
    utils.wait_for_status(
        client_manager.compute.servers.get,
        server.id)

Deleting the instance is simpler:

    client_manager.compute.servers.delete(server.id)
    utils.wait_for_delete(client_manager.compute.servers.get, server.id)

See create-delete.py for a standalone script including the above lines that can be run as:

$ python create-server.py --help
usage: create-server.py [-h] [--os-compute-api-version ]
...
$ python create-server.py
FLAVOR: {'name': u'm1.small', ...
NETWORK: {'cidr_v6': None, 'dns2': None, 'dns1': None, 'netmask': None, 'label': u'fsf-lan',...
IMAGE: {'status': u'ACTIVE', 'updated': u'2014-05-19T11:43:00Z', 'name': u'ubuntu-trusty-14.04',...
KEYPAIR: {'public_key': u'ssh-rsa AAAAB3...


As of python-openstackclient version 1.3.0 the utils.wait_for_delete helper does not exist yet and can be replaced with

def wait_for_delete(get_f,
                    res_id,
                    status_field='status',
                    sleep_time=5,
                    timeout=300,
                    callback=None):
    total_time = 0
    while total_time < timeout:
        try:
            # might not be a bad idea to re-use find_resource here if it was
            # a bit more friendly in the exceptions it raised so we could just
            # handle a NotFound exception here without parsing the message
            res = get_f(res_id)
        except Exception as ex:
            if type(ex).__name__ == 'NotFound':
                return True
            raise

        status = getattr(res, status_field, '').lower()
        if status == 'error':
            return False

        if callback:
            progress = getattr(res, 'progress', None) or 0
            callback(progress)
        time.sleep(sleep_time)
        total_time += sleep_time

    # if we got this far we've timed out
    return False

It may be necessary to work around

$ openstack image list
ERROR: openstack No module named cryptography.hazmat.bindings.openssl.binding

with the following

apt-get install libssl-dev
pip install 'pyOpenSSL<=0.13'
pip install python-openstackclient

on Ubuntu 14.04.
Many thanks to Mehdi Abaakouk for his guidance.

2 Replies to “create / delete an OpenStack instance with python-openstackclient”

Comments are closed.