Accept names for flavor and image

If a name is specified for flavor or image this is used to search for the
relevant IDs

Also fix type on Nova delete handler

Fixes bug #1076912

Change-Id: Ia891e20a1a7a09715fb69df64246e339c1145d3c
This commit is contained in:
Andrew Hutchings 2012-11-14 12:29:42 +00:00
parent 2116458693
commit ed21fa1748
5 changed files with 74 additions and 24 deletions

View File

@ -73,7 +73,7 @@ Pool Manager Section
nova_keyname = default
nova_secgroup = default
nova_image = 12345
nova_image_size = 102
nova_image_size = standard.medium
api_server = 10.0.0.1:8889 10.0.0.2:8889
nodes = 10
check_interval = 5
@ -230,12 +230,12 @@ Pool Manager Command Line Options
.. option:: --nova_image <NOVA_IMAGE>
The image ID to use on new nodes spun up in the Nova API
The image ID or name to use on new nodes spun up in the Nova API
.. option:: --nova_image_size <NOVA_IMAGE_SIZE>
The flavor ID (image size ID) to use for new nodes spun up in the Nova
API
The flavor ID (image size ID) or name to use for new nodes spun up in
the Nova API
.. option:: -p <PID>, --pid <PID>

View File

@ -69,8 +69,8 @@ Node Class
:param region: The Nova region
:param keyaname: The Nova key name for new nodes
:param secgroup: The Nova security group for new nodes
:param image: The Nova image ID for new nodes
:param node_type: The flavor ID for new nodes
:param image: The Nova image ID or name for new nodes
:param node_type: The flavor ID or name for new nodes
.. py:method:: build()

View File

@ -46,7 +46,7 @@ nova_region = region
nova_keyname = default
nova_secgroup = default
nova_image = 12345
nova_image_size = 102
nova_image_size = standard.medium
api_server = 10.0.0.1:8889 10.0.0.2:8889
nodes = 10
check_interval = 5

View File

@ -97,17 +97,23 @@ class Server(object):
self.ct.start()
def build_nodes(self, count, api):
nova = Node(
self.args.nova_user,
self.args.nova_pass,
self.args.nova_tenant,
self.args.nova_auth_url,
self.args.nova_region,
self.args.nova_keyname,
self.args.nova_secgroup,
self.args.nova_image,
self.args.nova_image_size
)
try:
nova = Node(
self.args.nova_user,
self.args.nova_pass,
self.args.nova_tenant,
self.args.nova_auth_url,
self.args.nova_region,
self.args.nova_keyname,
self.args.nova_secgroup,
self.args.nova_image,
self.args.nova_image_size
)
except Exception as exc:
self.logger.error('Error initialising Nova connection {exc}'
.format(exc=exc)
)
return
while count > 0:
status, data = nova.build()
if not status:
@ -200,12 +206,13 @@ def main():
)
options.parser.add_argument(
'--nova_image',
help='the image ID to use for new nodes spun up in the Nova API'
help='the image ID or name to use for new nodes spun up in the'
' Nova API'
)
options.parser.add_argument(
'--nova_image_size',
help='the image size ID (flavor ID) to use for new nodes spun up in'
' the Nova API'
help='the image size ID (flavor ID) or name to use for new nodes spun'
' up in the Nova API'
)
args = options.run()

View File

@ -15,10 +15,15 @@
import uuid
import time
import sys
import urllib
from novaclient import client
class NotFound(Exception):
pass
class Node(object):
def __init__(self, username, password, tenant, auth_url, region, keyname,
secgroup, image, node_type):
@ -32,8 +37,15 @@ class Node(object):
)
self.keyname = keyname
self.secgroup = secgroup
self.image = image
self.node_type = node_type
if image.isdigit():
self.image = image
else:
self.image = self._get_image(image)
if node_type.isdigit():
self.node_type = node_type
else:
self.node_type = self._get_flavor(node_type)
def build(self):
""" create a node, test it is running """
@ -75,7 +87,7 @@ class Node(object):
if resp['status'] != '204':
return False, 'Error deleting node {nid} status {stat}'.format(
node=node_id, stat=status['status']
node=node_id, stat=resp['status']
)
return True, ''
@ -108,3 +120,34 @@ class Node(object):
resp, body = self.nova.delete(url)
return resp
def _get_image(self, image_name):
""" tries to find an image from the name """
args = {'name': image_name}
url = "/images?{0}".format(urllib.urlencode(args))
resp, body = self.nova.get(url)
if resp['status'] not in ['200', '203']:
msg = "Error {0} searching for image with name {1}".format(
resp['status'], image_name
)
raise NotFound(msg)
if len(body['images']) != 1:
print body['images']
msg = "Could not find image with name {0}".format(image_name)
raise NotFound(msg)
return body['images'][0]['id']
def _get_flavor(self, flavor_name):
""" tries to find a flavor from the name """
url = "/flavors"
resp, body = self.nova.get(url)
if resp['status'] not in ['200', '203']:
msg = "Error {0} searching for flavor with name {1}".format(
resp['status'], flavor_name
)
raise NotFound(msg)
for flavor in body['flavors']:
if flavor['name'] == flavor_name:
return flavor['id']
msg = "Could not find flavor with name {0}".format(flavor_name)
raise NotFound(msg)