Monday 10 October 2016

How To Boot from a Volume on Rackspace Public Cloud using pyrax or the rack cli

For reasons too long to go into I recently had a need to create a VM that booted from a volume on the Rackspace Public Cloud.

This is fairly easy to achieve from the web interface - a couple of mouse clicks and you're done.

It's also possible from the rack cli tool. Something like:

rack servers instance create --name=test-yy \
  --flavor-id=io1-15 \
  --block-device="source-type=image,source-id=<uuid>,destination-type=volume,volume-size=150"
will do the trick.

None of these perfectly acceptable methods were quite what I wanted so I ended up poking at pyrax and the nova client until I got a solution I could use from python.

 1 import pyrax
 2
 3 def create_server(name, keypair):
 4     pyrax.set_credential_file("/path/to/pyraxcreds")
 5     nova = pyrax.cloudservers
 6     bdm = {
 7         'source_type': 'image',
 8         'uuid': '1d3ea64f-1ead-4042-8cb6-8ceb523b6149',
 9         'destination_type': 'volume',
10         'volume_size': '150',
11         'boot_index': '0'
12     }
13     
14     my_server = nova.servers.create(
15         name=name,
16         image=None,
17         flavor='io1-15',
18         key_name=keypair,
19         block_device_mapping_v2=[bdm]
20     )
21     
22     print(my_server.status)
23 
24 
25 def main():
26     create_server('test-xx', 'neill')
27 
28 main()

Taking this apart, the important bits are:

Line 4: Before you can use pyrax you need to provide some configuration.  Most of it can live in ~/.pyrax.cfg (see for an explanation of what belongs in this file), but your credentials must live elsewhere and you must tell pyrax where to find them before using pyrax to do anything. The credentials file needs to supply a username and for the Rackspace public cloud an API key.

Line 7-11 are where the magic really happens.  This sets up a nova block device mapping to tell it how to boot the VM. We are booting from an image with the UUID 1d3e...6149 (which specifies an Ubuntu Xenial image in the Rackspace public cloud), the boot destination is a volume 150GB in size, and it has boot index zero (meaning it is the first boot device).

Line 16: Even though we are supplying a boot device mapping nova requires an image parameter to be passed in here, but it will ignore the actual value.

Line 17: is the flavor-id for the VM we are creating.  This will vary by cloud.  On the Rackspace public cloud you can get a list of flavors by running:

rack servers flavor list

Line 18: The name of a keypair known to the Rackspace public cloud so you don't need to remember the root password.

Line 19: The nova client expects the block device mapping to be a list (presumably you can have more than one block device, but I only need the one).

Note: as presented here this code will spew InsecureRequestWarning exceptions from the requests library. To ignore these (probably not wise) you can add the following two lines to the code:

from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)


Hope this saves the next person some time!

No comments:

Post a Comment