From dddd0d0668d06b35c4a8f9bc2cb8babed21a5a1a Mon Sep 17 00:00:00 2001 From: Tony Mack Date: Tue, 14 Feb 2012 08:21:00 -0500 Subject: [PATCH] create slivers using EucaShell --- sfa/openstack/osaggregate.py | 143 ++++++++++++++++++++++++++--------- 1 file changed, 107 insertions(+), 36 deletions(-) diff --git a/sfa/openstack/osaggregate.py b/sfa/openstack/osaggregate.py index 12aca553..b0249a66 100644 --- a/sfa/openstack/osaggregate.py +++ b/sfa/openstack/osaggregate.py @@ -1,4 +1,5 @@ from nova.exception import ImageNotFound +from nova.api.ec2.cloud import CloudController from sfa.util.faults import SfaAPIError from sfa.rspecs.rspec import RSpec from sfa.rspecs.elements.hardware_type import HardwareType @@ -12,6 +13,15 @@ from sfa.util.osxrn import OSXrn from sfa.rspecs.version_manager import VersionManager +def disk_image_to_rspec_object(image): + img = DiskImage() + img['name'] = image['name'] + img['description'] = image['name'] + img['os'] = image['name'] + img['version'] = image['name'] + return img + + class OSAggregate: def __init__(self, driver): @@ -47,27 +57,42 @@ class OSAggregate: 'tags': []}) return sliver - def get_disk_images(self, image_id=None): + + def get_machine_image_details(self, image): + """ + Returns a dict that contains the ami, aki and ari details for the specified + ami image. + """ + disk_image = {} + if image['container_format'] == 'ami': + disk_image['ami'] = image + disk_image['aki'] = self.driver.shell.image_manager.show(image['kernel_id']) + disk_image['ari'] = self.driver.shell.image_manager.show(image['ramdisk_id']) + return disk_image + + def get_disk_image(self, id=None, name=None): + """ + Look up a image bundle using the specifeid id or name + """ + disk_image = None + try: + if id: + image = self.driver.shell.image_manager.show(image_id) + elif name: + image = self.driver.shell.image_manager.show_by_name(image_name) + if image['container_format'] == 'ami': + disk_image = self.get_machine_image_details(image) + except ImageNotFound: + pass + return disk_image + + def get_available_disk_images(self): # get image records - if image_id: - try: - images = [self.driver.shell.image_manager.show(image_id)] - except ImageNotFound: - images = [] - else: - images = self.driver.shell.image_manager.detail() - disk_images = [] - # create disk image objects - for image in images: + for image in self.driver.shell.image_manager.detail(): if image['container_format'] == 'ami': - img = DiskImage() - img['name'] = image['name'] - img['description'] = image['name'] - img['os'] = image['name'] - img['version'] = image['name'] - disk_images.append(img) - return disk_images + disk_images.append(self.get_machine_image_details(image)) + return disk_images def get_rspec(self, slice_xrn=None, version=None, options={}): version_manager = VersionManager() @@ -93,7 +118,8 @@ class OSAggregate: rspec_node['component_name'] = xrn.name rspec_node['component_manager_id'] = Xrn(self.driver.hrn, 'authority+cm').get_urn() sliver = self.instance_to_sliver(instance) - sliver['disk_images'] = self.get_disk_images(instance.image_ref) + disk_image = self.get_disk_image(instance.image_ref) + sliver['disk_images'] = [disk_image_to_rspec_object(disk_image)] rspec_node['slivers'] = [sliver] rspec_nodes.append(rspec_node) return rspec_nodes @@ -109,8 +135,9 @@ class OSAggregate: # available sliver/instance/vm types instances = self.driver.shell.db.instance_type_get_all().values() # available images - disk_images = self.get_disk_images() - + disk_images = self.get_available_disk_images() + disk_image_objects = [disk_image_to_rspec_object(image) \ + for image in disk_image] rspec_nodes = [] for zone in zones: rspec_node = Node() @@ -124,7 +151,7 @@ class OSAggregate: slivers = [] for instance in instances: sliver = self.instance_to_sliver(instance) - sliver['disk_images'] = disk_images + sliver['disk_images'] = disk_image_objects slivers.append(sliver) rspec_node['slivers'] = slivers @@ -133,7 +160,7 @@ class OSAggregate: return rspec_nodes - def verify_slice(self, slicename, users, options={}): + def create_project(self, slicename, users, options={}): """ Create the slice if it doesn't alredy exist """ @@ -147,7 +174,7 @@ class OSAggregate: proj_manager = usernames[0] self.driver.shell.auth_manager.create_project(slicename, proj_manager) - def verify_slice_users(self, slicename, users, options={}): + def create_project_users(self, slicename, users, options={}): """ Add requested users to the specified slice. """ @@ -163,6 +190,7 @@ class OSAggregate: except nova.exception.UserNotFound: self.driver.shell.auth_manager.create_user(username) self.verify_user_keys(username, user['keys'], options) + def verify_user_keys(self, username, keys, options={}): """ @@ -173,7 +201,7 @@ class OSAggregate: existing_pub_keys = [key.public_key for key in existing_keys] removed_pub_keys = set(existing_pub_keys).difference(keys) added_pub_keys = set(keys).difference(existing_pub_keys) - + pubkeys = [] # add new keys for public_key in added_pub_keys: key = {} @@ -187,14 +215,57 @@ class OSAggregate: for key in existing_keys: if key.public_key in removed_pub_keys: self.driver.shell.db.key_pair_destroy(username, key.name) - - def verify_instances(self, slicename, rspec): - rsepc = RSpec(rspec) - nodes = rspec.version.get_nodes_with_slivers() - old_instances = self.driver.shell.db.instance_get_all_by_project(name) - for node in nodes: - for slivers in node.get('slivers', []): - pass - # get instance type - # get image - # start instance + + def reserve_instance(self, image_id, kernel_id, ramdisk_id, \ + instance_type, key_name, user_data): + conn = self.driver.euca_shell + logger.info('Reserving an instance: image: %s, kernel: ' \ + '%s, ramdisk: %s, type: %s, key: %s' % \ + (image_id, kernel_id, ramdisk_id, + instance_type, key_name)) + try: + reservation = conn.run_instances(image_id=image_id, + kernel_id=kernel_id, + ramdisk_id=ramdisk_id, + instance_type=instance_type, + key_name=key_name, + user_data = user_data) + except EC2ResponseError, ec2RespError: + logger.log_exc(ec2RespError) + + def run_instances(self, slicename, rspec, keyname, pubkeys): + """ + Create the instances thats requested in the rspec + """ + # the default image to use for instnaces that dont + # explicitly request an image. + # Just choose the first available image for now. + available_images = self.get_available_disk_images() + default_image = self.get_disk_images()[0] + default_ami_id = CloudController.image_ec2_id(default_image['ami']['id']) + default_aki_id = CloudController.image_ec2_id(default_image['aki']['id']) + default_ari_id = CloudController.image_ec2_id(default_image['ari']['id']) + + # get requested slivers + rspec = RSpec(rspec) + requested_instances = defaultdict(list) + # iterate over clouds/zones/nodes + for node in rspec.version.get_nodes_with_slivers(): + instance_types = node.get('slivers', []) + if isinstance(instance_types, list): + # iterate over sliver/instance types + for instance_type in instance_types: + ami_id = default_ami_id + aki_id = default_aki_id + ari_id = default_ari_id + req_image = instance_type.get('disk_images') + if req_image and isinstance(req_image, list): + req_image_name = req_image[0]['name'] + disk_image = self.get_disk_image(name=req_image_name) + if disk_image: + ami_id = CloudController.image_ec2_id(disk_image['ami']['id']) + aki_id = CloudController.image_ec2_id(disk_image['aki']['id']) + ari_id = CloudController.image_ec2_id(disk_image['ari']['id']) + # start the instance + self.reserve_instance(ami_id, aki_id, ari_id, \ + instance_type['name'], keyname, pubkeys) -- 2.43.0