Skip to content

Instantly share code, notes, and snippets.

@sc68cal
Last active August 29, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sc68cal/ca6e134cf050ab2e3aec to your computer and use it in GitHub Desktop.
Save sc68cal/ca6e134cf050ab2e3aec to your computer and use it in GitHub Desktop.
docs runtests: PYTHONHASHSEED='2794469160'
docs runtests: commands[0] | python setup.py build_sphinx
running build_sphinx
Running Sphinx v1.1.3
loading pickled environment... done
building [html]: all source files
updating environment: 0 added, 1 changed, 0 removed
reading sources... [100%] section1
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
preparing documents... done
writing output... [100%] section9
writing additional files... genindex search
copying images... [100%] images/work_queue.png
copying static files... done
dumping search index... done
dumping object inventory... done
build succeeded.
Running Sphinx v1.1.3
loading pickled environment... done
building [man]: all source files
updating environment: 0 added, 0 changed, 0 removed
looking for now-outdated files... none found
writing... firstapp.1 { section1 section2 section3 section4 section5 section6 section7 section8 section9 appendix } Traceback (most recent call last):
File "setup.py", line 6, in <module>
pbr=True)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/core.py", line 152, in setup
dist.run_commands()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py", line 953, in run_commands
self.run_command(cmd)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py", line 972, in run_command
cmd_obj.run()
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/pbr/builddoc.py", line 175, in run
self._sphinx_run()
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/pbr/builddoc.py", line 136, in _sphinx_run
app.build(force_all=self.all_files)
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/sphinx/application.py", line 200, in build
self.builder.build_all()
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/sphinx/builders/__init__.py", line 159, in build_all
self.build(None, summary='all source files', method='all')
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/sphinx/builders/__init__.py", line 252, in build
self.write(docnames, list(updated_docnames), method)
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/sphinx/builders/manpage.py", line 88, in write
docwriter.write(largetree, destination)
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/writers/__init__.py", line 80, in write
self.translate()
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/sphinx/writers/manpage.py", line 35, in translate
self.document.walkabout(visitor)
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py", line 174, in walkabout
if child.walkabout(visitor):
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py", line 174, in walkabout
if child.walkabout(visitor):
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py", line 174, in walkabout
if child.walkabout(visitor):
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py", line 174, in walkabout
if child.walkabout(visitor):
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py", line 174, in walkabout
if child.walkabout(visitor):
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py", line 174, in walkabout
if child.walkabout(visitor):
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py", line 174, in walkabout
if child.walkabout(visitor):
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py", line 187, in walkabout
visitor.dispatch_departure(self)
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py", line 1895, in dispatch_departure
return method(node)
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/writers/manpage.py", line 411, in depart_admonition
self.depart_block_quote(node)
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/writers/manpage.py", line 449, in depart_block_quote
self.dedent()
File "/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/writers/manpage.py", line 865, in dedent
self._indent.pop()
IndexError: pop from empty list
ERROR: InvocationError: '/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/bin/python setup.py build_sphinx'
______________________________________________ summary ______________________________________________
ERROR: docs: commands failed
-> self.body.append(self.defs['indent'][1])
(Pdb) w
/Users/scollins/src/openstack/openstack-firstapp/setup.py(6)<module>()
-> pbr=True)
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/core.py(152)setup()
-> dist.run_commands()
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py(953)run_commands()
-> self.run_command(cmd)
/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py(972)run_command()
-> cmd_obj.run()
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/pbr/builddoc.py(175)run()
-> self._sphinx_run()
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/pbr/builddoc.py(136)_sphinx_run()
-> app.build(force_all=self.all_files)
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/sphinx/application.py(200)build()
-> self.builder.build_all()
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/sphinx/builders/__init__.py(159)build_all()
-> self.build(None, summary='all source files', method='all')
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/sphinx/builders/__init__.py(252)build()
-> self.write(docnames, list(updated_docnames), method)
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/sphinx/builders/manpage.py(88)write()
-> docwriter.write(largetree, destination)
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/writers/__init__.py(80)write()
-> self.translate()
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/sphinx/writers/manpage.py(35)translate()
-> self.document.walkabout(visitor)
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py(174)walkabout()
-> if child.walkabout(visitor):
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py(174)walkabout()
-> if child.walkabout(visitor):
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py(174)walkabout()
-> if child.walkabout(visitor):
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py(174)walkabout()
-> if child.walkabout(visitor):
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py(174)walkabout()
-> if child.walkabout(visitor):
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py(174)walkabout()
-> if child.walkabout(visitor):
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py(174)walkabout()
-> if child.walkabout(visitor):
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py(187)walkabout()
-> visitor.dispatch_departure(self)
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/nodes.py(1895)dispatch_departure()
-> return method(node)
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/writers/manpage.py(411)depart_admonition()
-> self.depart_block_quote(node)
/Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/writers/manpage.py(449)depart_block_quote()
-> self.dedent()
> /Users/scollins/src/openstack/openstack-firstapp/.tox/docs/lib/python2.7/site-packages/docutils/writers/manpage.py(869)dedent()
-> self.body.append(self.defs['indent'][1])
(Pdb) self._indent
[]

Section One: Getting Started

Who should read this book

This book has been written for software developers who wish to deploy applications to OpenStack clouds.

We've assumed that you're an experienced programmer, but that you haven't necessarily created an application for cloud in general, or for OpenStack in particular.

If you're already familiar with OpenStack, you'll save time learning about the general concepts, and you'll still find value in learning how to work programmatically with it's components.

What you will learn

Deploying applications in a cloud environment can be very different from the traditional siloed approach you see in traditional IT, so in addition to learning to deploy applications on OpenStack, you will also learn some best practices for cloud application development. Overall, this guide covers the following:

  • The most basic cloud application -- creating and destroying virtual resources
  • The architecture of a sample cloud-based application
  • The importance of message queues
  • Scaling up and down in response to changes in application load
  • Using object or block storage to create persistance
  • Orchestrating your cloud for better control of the environment
  • Networking choices and actions to help relieve potential congestion
  • Advice for developers who may not have been exposed to operations tasks before
  • Taking your application to the next level by spreading it across multiple regions or clouds

A general overview

This tutorial actually involves two applications; the first, a fractal generator, simply uses mathematical equations to generate images. We'll provide that application to you in its entirety, because really, it's just an excuse; the real application we will be showing you is the code that enables you to make use of OpenStack to run it. That application includes:

(include a list of what features we're going to cover)

Choosing your OpenStack SDK

Future versions of this book will cover completing these tasks with various toolkits, such as the OpenStack SDK, and using various languages, such as Java or C++. For now, however, this initial incarnation focuses on using Python with Apache Libcloud. That said, if you're not a master Python programmer, don't despair; the code is fairly straightforward, and should be readable to anyone with a programming background.

If you're a developer for an alternate toolkit and would like to see this book support it, great! Please feel free to submit alternate code snippets, or to contact any of the authors or members of the Documentation team to coordinate.

Although this guide (initially) covers only libcloud, you actually have several choices when it comes to building an application for an OpenStack cloud. These choices include:

NOTE(berendt): I would prefer to use a table instead of a listing here.

Language Name Description URL

Python

Libcloud

A Python-based library managed by the Apache Foundation. This library enables you to work with multiple types of clouds.

https://libcloud.apache.org

Python OpenStack SDK A python-based libary specifically developed for OpenStack. https://github.com/stackforge/python-openstacksdk

Java

jClouds

A Java-based library. Like libcloud, it's also managed by the Apache Foundation and works with multiple types of clouds.

https://jclouds.apache.org

Ruby fog A Ruby-based SDK for multiple clouds. http://www.fogproject.org
node.js pkgcloud A Node.js-based SDK. https://github.com/pkgcloud/pkgcloud
PHP php-opencloud A library for developers using PHP to work with OpenStack clouds. http://php-opencloud.com/

NET Framework

OpenStack SDK for Microsoft .NET

A .NET based library that can be used to write C++ applications.

https://www.nuget.org/packages/OpenStack-SDK-DotNet

A list of all available SDKs is available on wiki.openstack.org <https://wiki.openstack.org/wiki/SDKs>.

What you need to have (leave for Nick)

We assume you already have access to an OpenStack cloud with a quota of at least 3 servers, and have

openstacksdk

the OpenStack SDK installed.

You will need the following 5 pieces of information, which you can obtain from your cloud provider.

  • auth URL
  • username
  • password
  • project id or name (Projects are also known as tenants.)
  • cloud region

How you'll interact with OpenStack

Throughout this tutorial, you'll be interacting with your OpenStack cloud through code, using one of the SDKs listed in section "Choosing your OpenStack SDK".

Using code

libcloud

The following Python code can be put directly into a Python script, or you can use an interactive iPython shell.

from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver

OpenStack = get_driver(Provider.OPENSTACK)
conn = OpenStack('your_auth_username', 'your_auth_password',
                  ex_force_auth_url='http://10.0.0.11:5000',
                  ex_force_auth_version='2.0_password',
                  ex_tenant_name='your_project_name_or_id',
                  ex_force_service_region='your_region_name')

openstacksdk

from openstack import connection
conn = connection.Connection(auth_url="https://myopenstack:5000/v3",
                             user_name="me", password="secretsecret", ...)

Note

We'll use the conn object throughout the tutorial, so ensure you always have one handy

Flavors and Images

In order to launch an instance, you will need to choose a flavor and an image. The flavor is essentially the size of the instance, such as its number of CPUs, amount of RAM and disk. An image is a prepared OS instalation from which your instance is cloned. Keep in mind when booting instances that larger flavors can be more expensive (in terms of resources, and therefore monetary cost, if you're working in a public cloud) than smaller ones.

You can easily find out the images and flavors available in your cloud by running some API calls:

libcloud

images = conn.list_images()
for image in images:
   print(image)
<NodeImage: id=2cccbea0-cea9-4f86-a3ed-065c652adda5, name=ubuntu-14.04, driver=OpenStack  ...>
<NodeImage: id=f2a8dadc-7c7b-498f-996a-b5272c715e55, name=cirros-0.3.3-x86_64, driver=OpenStack  ...>
sizes = conn.list_sizes()
for size in sizes:
    print(size)
<OpenStackNodeSize: id=1, name=m1.tiny, ram=512, disk=1, bandwidth=None, price=0.0, driver=OpenStack, vcpus=1,  ...>
<OpenStackNodeSize: id=3, name=m1.medium, ram=4096, disk=40, bandwidth=None, price=0.0, driver=OpenStack, vcpus=2,  ...>
<OpenStackNodeSize: id=4, name=m1.large, ram=8192, disk=80, bandwidth=None, price=0.0, driver=OpenStack, vcpus=4,  ...>
<OpenStackNodeSize: id=5, name=m1.xlarge, ram=16384, disk=160, bandwidth=None, price=0.0, driver=OpenStack, vcpus=8,  ...>

Your images and flavors will be different. Choose an image and flavor to use for your first server. To start with, we only need about 1GB of RAM, 1 CPU and a GB of disk. So, the m1.medium flavor exceeds this and the ubuntu image is a safe choice. These will be used throughout this guide, so you will need to change use the IDs in the following tutorial sections to correspond to your desired flavor and image.

Set the image and size variables to appropriate values for your cloud. We'll use these in later sections:

libcloud

image = conn.get_image('2cccbea0-cea9-4f86-a3ed-065c652adda5')
size = conn.ex_get_size('3')

Booting an instance

Now that you have selected an image and flavor, use it to create an instance:

libcloud

Note

The following instance creation assumes that you only have one tenant network. If you have multiple tenant networks defined, you will need to add a networks parameter to the create_node call. See /appendix for details.

testing =  conn.create_node(name='testing', image=image, size=flavor)
print testing
<Node: uuid=1242d56cac5bcd4c110c60d57ccdbff086515133, name=testing, state=PENDING, public_ips=[], private_ips=[], provider=OpenStack ...>
servers = conn.list_nodes()
for server in servers:
    print(server)
NOTE(berendt): Missing output here.

openstacksdk

args = {
    "name": "my_server",
    "flavorRef": "big",
    "imageRef": "asdf-1234-qwer-5678",
    "key_name": "my_ssh_key",
}
server = conn.compute.create_server(**args)
servers = conn.compute.list_servers()
for server in servers:
    print(server)
NOTE(berendt): Missing output here.

Destroying an instance

It is important to keep in mind that cloud resources (including running instances) can cost money. Learning to remove cloud resources will help you avoid any unexpected costs incurred by unnecessary cloud resources.

libcloud

conn.destroy_node(testing)

Deploy the application to a new instance

Now that you are familiar with how to create and destroy instances, it is time to build a new instance and deploy the application at the same time.

libcloud

SCRIPT = '''#!/usr/bin/env bash
pip install faafo
faafo-run demo-mode
'''

server = conn.deploy_node(name='app1', image=images[0], size=sizes[0],
                          deploy=ScriptDeployment(SCRIPT))

Let's wait for the server to launch:

libcloud

[(Node, ip_addresses)] = wait_until_running(nodes)
print (http://%s) % ip_address

NOTE(berendt): We have to generate some fractals here. The webinterface is a blank page with no generated fractals. make-a-fractal-please aka demo-mode ^_^

Now visit the awesome graphic interface at the link provided.

Don't worry if you don't understand every part of what just happened - this will be covered, and more in the next section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment