Commit c466b755 authored by Ilias Tsitsimpis's avatar Ilias Tsitsimpis

ci: Improve flavors/images finder

Allow for search both by name (using regular
expressions) or by id.
parent 19851f10
......@@ -32,11 +32,14 @@ temporary_config = /tmp/ci_temp_conf
kamaki_cloud =
# Server name to use for our machine
server_name = Synnefo Deployment
# Flavor name (reg expression) to use
# This is a list of flavor_names (comma seperated) to try
flavor_name = C8R8...D100drbd
# Image to use (name must contain this)
image_name = OldStable
# A list of flavors (comma seperated) to choose from
# The user can specify a flavor name (reg expression)
# with "name:" or a flavor id with "id:".
flavors = name:C8R8...D100drbd, id:1
# A list of images (comma seperated) to choose from
# The user can specify an image name (reg expression)
# with "name:" or an image id with "id:".
images = name:Debian Base \(OldStable\), id:72d9844f-1024-4a07-a3c3-60d650b8f5cd
# File containing the ssh keys to upload/install to server
# If not set, no ssh keys will be installed
ssh_keys =
......
......@@ -55,9 +55,15 @@ def main(): # Too many branches. pylint: disable-msg=R0912
parser.add_option("--cloud", dest="kamaki_cloud", default=None,
help="Use specified cloud, as is in .kamakirc")
parser.add_option("-f", "--flavor", dest="flavor", default=None,
help="Name of flavor to use for the server.")
help="Flavor to use for the server."
" Supports both search by name (reg expression)"
" with \"name:flavor name\" or by id with"
" \"id:flavor id\".")
parser.add_option("-i", "--image", dest="image", default=None,
help="UUID of image to use for the server.")
help="Image to use for the server."
" Supports both search by name (reg expression)"
" with \"name:image name\" or by id with"
" \"id:image id\".")
parser.add_option("--ssh-keys", dest="ssh_keys", default=None,
help="Upload/Install the public ssh keys contained"
" in this file to the server")
......@@ -112,8 +118,8 @@ def main(): # Too many branches. pylint: disable-msg=R0912
cloud=options.kamaki_cloud)
if getattr(options, CREATE_SERVER_CMD, False):
synnefo_ci.create_server(flavor_name=options.flavor,
image_id=options.image,
synnefo_ci.create_server(flavor=options.flavor,
image=options.image,
ssh_keys=options.ssh_keys)
synnefo_ci.clone_repo(local_repo=options.local_repo)
if getattr(options, BUILD_SYNNEFO_CMD, False):
......
......@@ -242,7 +242,7 @@ class SynnefoCI(object):
self._wait_transition(server_id, "ACTIVE", "DELETED")
@_check_kamaki
def create_server(self, image_id=None, flavor_name=None, ssh_keys=None):
def create_server(self, image=None, flavor=None, ssh_keys=None):
"""Create slave server"""
self.logger.info("Create a new server..")
......@@ -260,13 +260,11 @@ class SynnefoCI(object):
% _green(self.build_id))
# Find an image to use
if image_id is None:
image = self._find_image()
self.logger.debug("Will use image \"%s\"" % _green(image['name']))
image_id = image["id"]
self.logger.debug("Image has id %s" % _green(image_id))
image_id = self._find_image(image)
# Find a flavor to use
flavor_id = self._find_flavor(flavor_name)
flavor_id = self._find_flavor(flavor)
# Create Server
server = self.cyclades_client.create_server(
self.config.get('Deployment', 'server_name'),
flavor_id,
......@@ -317,44 +315,90 @@ class SynnefoCI(object):
""".format(self.config.get('Global', 'apt_repo'))
_run(cmd, False)
def _find_flavor(self, flavor_name):
"""Given a flavor_name (reg expression) find a flavor id to use"""
# Get a list of flavor names from config file
flavor_names = self.config.get('Deployment', 'flavor_name').split(",")
if flavor_name is not None:
def _find_flavor(self, flavor=None):
"""Find a suitable flavor to use
Search by name (reg expression) or by id
"""
# Get a list of flavors from config file
flavors = self.config.get('Deployment', 'flavors').split(",")
if flavor is not None:
# If we have a flavor_name to use, add it to our list
flavor_names.insert(0, flavor_name)
flavors = self.compute_client.list_flavors()
for flname in flavor_names:
sflname = flname.strip()
self.logger.debug("Try to find a flavor with name \"%s\"" % sflname)
fls = [f for f in flavors
if re.search(sflname, f['name']) is not None]
if fls:
self.logger.debug("Will use %s with id %s"
% (fls[0]['name'], fls[0]['id']))
return fls[0]['id']
flavors.insert(0, flavor)
list_flavors = self.compute_client.list_flavors()
for flv in flavors:
[flv_type, flv_value] = flv.strip().split(':')
if flv_type == "name":
# Filter flavors by name
self.logger.debug(
"Trying to find a flavor with name \"%s\"" % flv_value)
list_flvs = \
[f for f in list_flavors
if re.search(flv_value, f['name'], flags=re.I) is not None]
elif flv_type == "id":
# Filter flavors by id
self.logger.debug(
"Trying to find a flavor with id \"%s\"" % flv_value)
list_flvs = \
[f for f in list_flavors
if f['id'].lower() == flv_value.lower()]
else:
self.logger.error("Unrecognized flavor type %s" % flv_type)
# Check if we found one
if list_flvs:
self.logger.debug("Will use \"%s\" with id \"%s\""
% (list_flvs[0]['name'], list_flvs[0]['id']))
return list_flvs[0]['id']
self.logger.error("No matching flavor found.. aborting")
sys.exit(1)
def _find_image(self):
def _find_image(self, image=None):
"""Find a suitable image to use
It has to belong to one of the `DEFAULT_SYSTEM_IMAGES_UUID'
users and contain the word given by `image_name' option.
In case of search by name, the image has to belong to one
of the `DEFAULT_SYSTEM_IMAGES_UUID' users.
In case of search by id it only has to exist.
"""
image_name = self.config.get('Deployment', 'image_name').lower()
images = self.image_client.list_public(detail=True)['images']
# Select images by `system_uuid' user
images = [x for x in images
if x['user_id'] in DEFAULT_SYSTEM_IMAGES_UUID]
# Select images with `image_name' in their names
images = [x for x in images
if x['name'].lower().find(image_name) != -1]
# Let's select the first one
return images[0]
# Get a list of images from config file
images = self.config.get('Deployment', 'images').split(",")
if image is not None:
# If we have an image from command line, add it to our list
images.insert(0, image)
list_images = self.image_client.list_public(detail=True)['images']
for img in images:
[img_type, img_value] = img.strip().split(':')
if img_type == "name":
# Filter images by name
self.logger.debug(
"Trying to find an image with name \"%s\"" % img_value)
list_imgs = \
[i for i in list_images
if i['user_id'] in DEFAULT_SYSTEM_IMAGES_UUID and
re.search(img_value, i['name'], flags=re.I) is not None]
elif img_type == "id":
# Filter images by id
self.logger.debug(
"Trying to find an image with id \"%s\"" % img_value)
list_imgs = \
[i for i in list_images
if i['id'].lower() == img_value.lower()]
else:
self.logger.error("Unrecognized image type %s" % img_type)
sys.exit(1)
# Check if we found one
if list_imgs:
self.logger.debug("Will use \"%s\" with id \"%s\""
% (list_imgs[0]['name'], list_imgs[0]['id']))
return list_imgs[0]['id']
# We didn't found one
self.logger.error("No matching image found.. aborting")
sys.exit(1)
def _get_server_ip_and_port(self, server):
"""Compute server's IPv4 and ssh port number"""
......@@ -614,7 +658,7 @@ class SynnefoCI(object):
self.logger.info("Deploy Synnefo..")
if schema is None:
schema = self.config.get('Global', 'schema')
self.logger.debug("Will use %s schema" % schema)
self.logger.debug("Will use \"%s\" schema" % schema)
schema_dir = os.path.join(self.ci_dir, "schemas/%s" % schema)
if not (os.path.exists(schema_dir) and os.path.isdir(schema_dir)):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment