This page gives examples of using the Python OpenStack SDK to perform some common workflows on Jetstream2. Before continuing, make sure you have installed and configured the Python OpenStack SDK. The workflows in this example are comprised of code snippets that build upon the results from previous snippets. The first bit of code discovers your configuration and connects to the named cloud, returning an object of type Connection.


import openstack

connection = openstack.connect("envvars")
Finding an Image

In many cases, it is easier to create entities that will be reused many times (such as networks, routers, security groups and key pairs) using Horizon or the CLI rather than using the APIs or SDKs. For that reason, these examples focus on actions that are often needed while an application is running. Here, we locate an image and other required entities, then use them to create a new instance.

While the Jetstream2 regions contain numerous images, it is recommended that only those whose names begin with "Featured-" be used for creating instances through the OpenStack API and SDKs. You can access image-related functionality through the image member of a Connection object. This includes listing all images and finding an image by name or ID, as well as uploading, downloading and deleting images. The following Python code gets the Image object that exactly matches a text name or ID:


image = connection.image.find_image("Featured-Ubuntu22")
Creating an Instance

A Connection object also provides access through its members to other OpenStack services. These include the members compute, network and volume (i.e. block storage), among others. We will need to use methods of these members to retrieve objects that represent the entities we need when creating an instance.

The following example finds these objects by their names, which can be accessed through other SDK methods, the Horizon UI or the CLI. Some of these names are taken from the objects we created in the CLI examples, and the IP address value must be one that is allocated in the project. The example then creates an instance (called a "server" in the SDK) using these objects as parameters.


NETWORK_NAME = "auto_allocated_network"
SECURITY_NAME = "johndoe-security"
KEYPAIR_NAME = "johndoe-key"
SERVER_NAME = "johndoe-sdk-instance"
IP_ADDRESS = "149.165.152.166"

network = connection.network.find_network(NETWORK_NAME)
security = connection.network.find_security_group(SECURITY_NAME)

keypair = connection.compute.find_keypair(KEYPAIR_NAME)
flavor = connection.compute.find_flavor("m3.small")

server = connection.compute.create_server(name=SERVER_NAME, image_id=image.id,
    flavor_id=flavor.id, key_name=keypair.name, networks=[{"uuid": network.id}])

connection.compute.wait_for_server(server)

connection.compute.add_security_group_to_server(server, security)
connection.compute.add_floating_ip_to_server(server, IP_ADDRESS)

Some notes on the code sample above:

  • The create_server method accepts many more parameters, whose names match the members of the Server class. Parameters like networks are passed in lists to allow multiple assignments at once.
  • Because create_server returns as soon as the creation process is fully initiated, you will want to call wait_for_server afterwards to block your code until the instance reaches a desired state ('ACTIVE' is the default).
  • The last two lines associate a security group and a floating IP address with the instance that is now running.
Managing an Instance

Once an image has been created, you can easily manage its state from the SDK. Assuming you know its name, you can find the instance in order to unshelve or shelve it, or perform any of the other operations provided by the Compute service. Here are a few examples:


server = connection.compute.find_server(SERVER_NAME)

connection.compute.shelve_server(server)

connection.compute.unshelve_server(server)
connection.compute.wait_for_server(server)

connection.delete_server(server);

Some notes on the code sample above:

  • The example finds the instance (server) using its name.
  • When unshelving a server you will want to wait for it to regain the 'ACTIVE' status, in the same way as was done when creating it. A shelved instance does not seem to achieve a valid status value, so waiting for that operation to complete shouldn't be attempted.
 
©   Cornell University  |  Center for Advanced Computing  |  Copyright Statement  |  Inclusivity Statement