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:
parent
2116458693
commit
ed21fa1748
@ -73,7 +73,7 @@ Pool Manager Section
|
|||||||
nova_keyname = default
|
nova_keyname = default
|
||||||
nova_secgroup = default
|
nova_secgroup = default
|
||||||
nova_image = 12345
|
nova_image = 12345
|
||||||
nova_image_size = 102
|
nova_image_size = standard.medium
|
||||||
api_server = 10.0.0.1:8889 10.0.0.2:8889
|
api_server = 10.0.0.1:8889 10.0.0.2:8889
|
||||||
nodes = 10
|
nodes = 10
|
||||||
check_interval = 5
|
check_interval = 5
|
||||||
@ -230,12 +230,12 @@ Pool Manager Command Line Options
|
|||||||
|
|
||||||
.. option:: --nova_image <NOVA_IMAGE>
|
.. 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>
|
.. option:: --nova_image_size <NOVA_IMAGE_SIZE>
|
||||||
|
|
||||||
The flavor ID (image size ID) to use for new nodes spun up in the Nova
|
The flavor ID (image size ID) or name to use for new nodes spun up in
|
||||||
API
|
the Nova API
|
||||||
|
|
||||||
.. option:: -p <PID>, --pid <PID>
|
.. option:: -p <PID>, --pid <PID>
|
||||||
|
|
||||||
|
@ -69,8 +69,8 @@ Node Class
|
|||||||
:param region: The Nova region
|
:param region: The Nova region
|
||||||
:param keyaname: The Nova key name for new nodes
|
:param keyaname: The Nova key name for new nodes
|
||||||
:param secgroup: The Nova security group for new nodes
|
:param secgroup: The Nova security group for new nodes
|
||||||
:param image: The Nova image ID for new nodes
|
:param image: The Nova image ID or name for new nodes
|
||||||
:param node_type: The flavor ID for new nodes
|
:param node_type: The flavor ID or name for new nodes
|
||||||
|
|
||||||
.. py:method:: build()
|
.. py:method:: build()
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ nova_region = region
|
|||||||
nova_keyname = default
|
nova_keyname = default
|
||||||
nova_secgroup = default
|
nova_secgroup = default
|
||||||
nova_image = 12345
|
nova_image = 12345
|
||||||
nova_image_size = 102
|
nova_image_size = standard.medium
|
||||||
api_server = 10.0.0.1:8889 10.0.0.2:8889
|
api_server = 10.0.0.1:8889 10.0.0.2:8889
|
||||||
nodes = 10
|
nodes = 10
|
||||||
check_interval = 5
|
check_interval = 5
|
||||||
|
@ -97,17 +97,23 @@ class Server(object):
|
|||||||
self.ct.start()
|
self.ct.start()
|
||||||
|
|
||||||
def build_nodes(self, count, api):
|
def build_nodes(self, count, api):
|
||||||
nova = Node(
|
try:
|
||||||
self.args.nova_user,
|
nova = Node(
|
||||||
self.args.nova_pass,
|
self.args.nova_user,
|
||||||
self.args.nova_tenant,
|
self.args.nova_pass,
|
||||||
self.args.nova_auth_url,
|
self.args.nova_tenant,
|
||||||
self.args.nova_region,
|
self.args.nova_auth_url,
|
||||||
self.args.nova_keyname,
|
self.args.nova_region,
|
||||||
self.args.nova_secgroup,
|
self.args.nova_keyname,
|
||||||
self.args.nova_image,
|
self.args.nova_secgroup,
|
||||||
self.args.nova_image_size
|
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:
|
while count > 0:
|
||||||
status, data = nova.build()
|
status, data = nova.build()
|
||||||
if not status:
|
if not status:
|
||||||
@ -200,12 +206,13 @@ def main():
|
|||||||
)
|
)
|
||||||
options.parser.add_argument(
|
options.parser.add_argument(
|
||||||
'--nova_image',
|
'--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(
|
options.parser.add_argument(
|
||||||
'--nova_image_size',
|
'--nova_image_size',
|
||||||
help='the image size ID (flavor ID) to use for new nodes spun up in'
|
help='the image size ID (flavor ID) or name to use for new nodes spun'
|
||||||
' the Nova API'
|
' up in the Nova API'
|
||||||
)
|
)
|
||||||
|
|
||||||
args = options.run()
|
args = options.run()
|
||||||
|
@ -15,10 +15,15 @@
|
|||||||
import uuid
|
import uuid
|
||||||
import time
|
import time
|
||||||
import sys
|
import sys
|
||||||
|
import urllib
|
||||||
|
|
||||||
from novaclient import client
|
from novaclient import client
|
||||||
|
|
||||||
|
|
||||||
|
class NotFound(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Node(object):
|
class Node(object):
|
||||||
def __init__(self, username, password, tenant, auth_url, region, keyname,
|
def __init__(self, username, password, tenant, auth_url, region, keyname,
|
||||||
secgroup, image, node_type):
|
secgroup, image, node_type):
|
||||||
@ -32,8 +37,15 @@ class Node(object):
|
|||||||
)
|
)
|
||||||
self.keyname = keyname
|
self.keyname = keyname
|
||||||
self.secgroup = secgroup
|
self.secgroup = secgroup
|
||||||
self.image = image
|
if image.isdigit():
|
||||||
self.node_type = node_type
|
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):
|
def build(self):
|
||||||
""" create a node, test it is running """
|
""" create a node, test it is running """
|
||||||
@ -75,7 +87,7 @@ class Node(object):
|
|||||||
|
|
||||||
if resp['status'] != '204':
|
if resp['status'] != '204':
|
||||||
return False, 'Error deleting node {nid} status {stat}'.format(
|
return False, 'Error deleting node {nid} status {stat}'.format(
|
||||||
node=node_id, stat=status['status']
|
node=node_id, stat=resp['status']
|
||||||
)
|
)
|
||||||
|
|
||||||
return True, ''
|
return True, ''
|
||||||
@ -108,3 +120,34 @@ class Node(object):
|
|||||||
resp, body = self.nova.delete(url)
|
resp, body = self.nova.delete(url)
|
||||||
|
|
||||||
return resp
|
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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user