def validate_instance_flavors(context, instances, volume_enabled, ephemeral_enabled): """Validate flavors for given instance definitions.""" nova_cli_cache = dict() for instance in instances: region_name = instance.get('region_name') flavor_id = instance['flavor_id'] try: if region_name is None: nova_client = remote.create_nova_client(context, region_name) else: if region_name not in nova_cli_cache: nova_client = remote.create_nova_client( context, region_name) nova_cli_cache[region_name] = nova_client else: nova_client = nova_cli_cache[region_name] flavor = nova_client.flavors.get(flavor_id) if (not volume_enabled and (ephemeral_enabled and flavor.ephemeral == 0)): raise exception.LocalStorageNotSpecified( flavor=flavor_id) except nova_exceptions.NotFound: raise exception.FlavorNotFound(uuid=flavor_id)
def _get_cluster_network_interfaces(self): nova_client = remote.create_nova_client(self.context) nova_instance_id = self.db_instances[0].compute_instance_id interfaces = nova_client.virtual_interfaces.list(nova_instance_id) ret = [{"net-id": getattr(interface, 'net_id')} for interface in interfaces] return ret
def load_mgmt_instance(cls, context, id, include_deleted): try: instance = load_instance(cls, context, id, needs_server=True, include_deleted=include_deleted) client = remote.create_nova_client(context, CONF.os_region_name) try: server = client.rdservers.get(instance.server_id) except AttributeError: server = client.servers.get(instance.server_id) if hasattr(server, 'host'): instance.server.host = server.host elif hasattr(server, 'hostId'): instance.server.host = server.hostId if hasattr(server, 'deleted'): instance.server.deleted = server.deleted if hasattr(server, 'deleted_at'): instance.server.deleted_at = server.deleted_at if hasattr(server, 'local_id'): instance.server.local_id = server.local_id assert instance.server is not None except Exception as e: LOG.error(e) instance = load_instance(cls, context, id, needs_server=False, include_deleted=include_deleted) return instance
def load_mgmt_instance(cls, context, id, include_deleted): try: instance = instance_models.load_instance( cls, context, id, needs_server=True, include_deleted=include_deleted) client = remote.create_nova_client(context, CONF.os_region_name) try: server = client.rdservers.get(instance.server_id) except AttributeError: server = client.servers.get(instance.server_id) if hasattr(server, 'host'): instance.server.host = server.host elif hasattr(server, 'hostId'): instance.server.host = server.hostId if hasattr(server, 'deleted'): instance.server.deleted = server.deleted if hasattr(server, 'deleted_at'): instance.server.deleted_at = server.deleted_at if hasattr(server, 'local_id'): instance.server.local_id = server.local_id assert instance.server is not None except Exception as e: LOG.error(e) instance = instance_models.load_instance( cls, context, id, needs_server=False, include_deleted=include_deleted) return instance
def _check_instances(context, instances, datastore_version, allowed_instance_count=None): instance_count = len(instances) if allowed_instance_count: if instance_count not in allowed_instance_count: raise exception.ClusterNumInstancesNotSupported( num_instances=allowed_instance_count ) flavor_ids = [instance['flavor_id'] for instance in instances] if len(set(flavor_ids)) != 1: raise exception.ClusterFlavorsNotEqual() flavor_id = flavor_ids[0] nova_client = remote.create_nova_client(context) try: flavor = nova_client.flavors.get(flavor_id) except nova_exceptions.NotFound: raise exception.FlavorNotFound(uuid=flavor_id) mongo_conf = CONF.get(datastore_version.manager) volume_sizes = [instance['volume_size'] for instance in instances if instance.get('volume_size', None)] if mongo_conf.volume_support: if len(volume_sizes) != instance_count: raise exception.ClusterVolumeSizeRequired() if len(set(volume_sizes)) != 1: raise exception.ClusterVolumeSizesNotEqual() volume_size = volume_sizes[0] models.validate_volume_size(volume_size) else: # TODO(amcreynolds): is ephemeral possible for mongodb clusters? if len(volume_sizes) > 0: raise exception.VolumeNotSupported() ephemeral_support = mongo_conf.device_path if ephemeral_support and flavor.ephemeral == 0: raise exception.LocalStorageNotSpecified(flavor=flavor_id)
def resize_flavor(self, new_flavor_id): self.validate_can_perform_action() LOG.debug("resizing instance %s flavor to %s" % (self.id, new_flavor_id)) # Validate that the flavor can be found and that it isn't the same size # as the current one. client = create_nova_client(self.context) try: new_flavor = client.flavors.get(new_flavor_id) except nova_exceptions.NotFound: raise exception.FlavorNotFound(uuid=new_flavor_id) old_flavor = client.flavors.get(self.flavor_id) new_flavor_size = new_flavor.ram old_flavor_size = old_flavor.ram if CONF.trove_volume_support: if new_flavor.ephemeral != 0: raise exception.LocalStorageNotSupported() if new_flavor_size == old_flavor_size: raise exception.CannotResizeToSameSize() elif CONF.device_path is not None: # ephemeral support enabled if new_flavor.ephemeral == 0: raise exception.LocalStorageNotSpecified(flavor=new_flavor_id) if (new_flavor_size == old_flavor_size and new_flavor.ephemeral == new_flavor.ephemeral): raise exception.CannotResizeToSameSize() # Set the task to RESIZING and begin the async call before returning. self.update_db(task_status=InstanceTasks.RESIZING) LOG.debug("Instance %s set to RESIZING." % self.id) task_api.API(self.context).resize_flavor(self.id, old_flavor, new_flavor)
def load(context, include_clustered): def load_simple_instance(context, db, status, **kwargs): return SimpleInstance(context, db, status) if context is None: raise TypeError("Argument context not defined.") client = create_nova_client(context) servers = client.servers.list() if include_clustered: db_infos = DBInstance.find_all(tenant_id=context.tenant, deleted=False) else: db_infos = DBInstance.find_all(tenant_id=context.tenant, cluster_id=None, deleted=False) limit = int(context.limit or Instances.DEFAULT_LIMIT) if limit > Instances.DEFAULT_LIMIT: limit = Instances.DEFAULT_LIMIT data_view = DBInstance.find_by_pagination('instances', db_infos, "foo", limit=limit, marker=context.marker) next_marker = data_view.next_page_marker find_server = create_server_list_matcher(servers) for db in db_infos: LOG.debug("Checking for db [id=%(db_id)s, " "compute_instance_id=%(instance_id)s].", {'db_id': db.id, 'instance_id': db.compute_instance_id}) ret = Instances._load_servers_status(load_simple_instance, context, data_view.collection, find_server) return ret, next_marker
def _create_instances(context, db_info, datastore, datastore_version, instances): Redis_conf = CONF.get(datastore_version.manager) num_instances = len(instances) total_volume_allocation = 0 # Validate and Cache flavors nova_client = remote.create_nova_client(context) unique_flavors = set(map(lambda i: i['flavor_id'], instances)) flavor_cache = {} for fid in unique_flavors: try: flavor_cache.update({fid: nova_client.flavors.get(fid)}) except nova_exceptions.NotFound: raise exception.FlavorNotFound(uuid=fid) # Checking volumes name_index = 1 for instance in instances: if not instance.get('name'): instance['name'] = "%s-member-%s" % (db_info.name, name_index) name_index += 1 volume_size = instance.get('volume_size') if Redis_conf.volume_support: models.validate_volume_size(volume_size) total_volume_allocation += volume_size else: if volume_size: raise exception.VolumeNotSupported() ephemeral_support = Redis_conf.device_path flavor_id = instance['flavor_id'] flavor = flavor_cache[flavor_id] if ephemeral_support and flavor.ephemeral == 0: raise exception.LocalStorageNotSpecified(flavor=flavor_id) # Check quotas quota_request = { 'instances': num_instances, 'volumes': total_volume_allocation } check_quotas(context.tenant, quota_request) # Creating member instances return map( lambda instance: inst_models.Instance.create( context, instance['name'], instance['flavor_id'], datastore_version.image_id, [], [], datastore, datastore_version, instance.get('volume_size'), None, instance.get('availability_zone', None), instance.get('nics', None), configuration_id=None, cluster_config={ "id": db_info.id, "instance_type": "member" }), instances)
def list_datastore_version_flavor_associations(cls, context, datastore_type, datastore_version_id): if datastore_type and datastore_version_id: """ All nova flavors are permitted for a datastore_version unless one or more entries are found in datastore_version_metadata, in which case only those are permitted. """ (datastore, datastore_version) = get_datastore_version( type=datastore_type, version=datastore_version_id) # If datastore_version_id and flavor key exists in the # metadata table return all the associated flavors for # that datastore version. nova_flavors = create_nova_client(context).flavors.list() bound_flavors = DBDatastoreVersionMetadata.find_all( datastore_version_id=datastore_version.id, key='flavor', deleted=False) if (bound_flavors.count() != 0): bound_flavors = tuple(f.value for f in bound_flavors) # Generate a filtered list of nova flavors ds_nova_flavors = (f for f in nova_flavors if f.id in bound_flavors) associated_flavors = tuple( flavor_model(flavor=item) for item in ds_nova_flavors) else: # Return all nova flavors if no flavor metadata found # for datastore_version. associated_flavors = tuple( flavor_model(flavor=item) for item in nova_flavors) return associated_flavors else: msg = _("Specify both the datastore and datastore_version_id.") raise exception.BadRequest(msg)
def resize_flavor(self, new_flavor_id): self.validate_can_perform_action() LOG.info(_LI("Resizing instance %(instance_id)s flavor to " "%(flavor_id)s."), {'instance_id': self.id, 'flavor_id': new_flavor_id}) if self.db_info.cluster_id is not None: raise exception.ClusterInstanceOperationNotSupported() # Validate that the old and new flavor IDs are not the same, new flavor # can be found and has ephemeral/volume support if required by the # current flavor. if self.flavor_id == new_flavor_id: raise exception.BadRequest(_("The new flavor id must be different " "than the current flavor id of '%s'.") % self.flavor_id) client = create_nova_client(self.context) try: new_flavor = client.flavors.get(new_flavor_id) except nova_exceptions.NotFound: raise exception.FlavorNotFound(uuid=new_flavor_id) old_flavor = client.flavors.get(self.flavor_id) if self.volume_support: if new_flavor.ephemeral != 0: raise exception.LocalStorageNotSupported() elif self.device_path is not None: # ephemeral support enabled if new_flavor.ephemeral == 0: raise exception.LocalStorageNotSpecified(flavor=new_flavor_id) # Set the task to RESIZING and begin the async call before returning. self.update_db(task_status=InstanceTasks.RESIZING) LOG.debug("Instance %s set to RESIZING.", self.id) task_api.API(self.context).resize_flavor(self.id, old_flavor, new_flavor)
def _validate_cluster_instances(context, instances, datastore, datastore_version): """Validate the flavor and volume""" ds_conf = CONF.get(datastore_version.manager) num_instances = len(instances) # Check number of instances is at least min_cluster_member_count if num_instances < ds_conf.min_cluster_member_count: raise exception.ClusterNumInstancesNotLargeEnough( num_instances=ds_conf.min_cluster_member_count) # Checking flavors and get delta for quota check flavor_ids = [instance['flavor_id'] for instance in instances] if len(set(flavor_ids)) != 1: raise exception.ClusterFlavorsNotEqual() flavor_id = flavor_ids[0] nova_client = remote.create_nova_client(context) try: flavor = nova_client.flavors.get(flavor_id) except nova_exceptions.NotFound: raise exception.FlavorNotFound(uuid=flavor_id) deltas = {'instances': num_instances} # Checking volumes and get delta for quota check volume_sizes = [instance['volume_size'] for instance in instances if instance.get('volume_size', None)] volume_size = None if ds_conf.volume_support: if len(volume_sizes) != num_instances: raise exception.ClusterVolumeSizeRequired() if len(set(volume_sizes)) != 1: raise exception.ClusterVolumeSizesNotEqual() volume_size = volume_sizes[0] cluster_models.validate_volume_size(volume_size) deltas['volumes'] = volume_size * num_instances else: if len(volume_sizes) > 0: raise exception.VolumeNotSupported() ephemeral_support = ds_conf.device_path if ephemeral_support and flavor.ephemeral == 0: raise exception.LocalStorageNotSpecified(flavor=flavor_id) # quota check check_quotas(context.tenant, deltas) # Checking networks are same for the cluster instance_nics = [] for instance in instances: nics = instance.get('nics') if nics: instance_nics.append(nics[0].get('net-id')) if len(set(instance_nics)) > 1: raise exception.ClusterNetworksNotEqual() if not instance_nics: return instance_nic = instance_nics[0] try: nova_client.networks.get(instance_nic) except nova_exceptions.NotFound: raise exception.NetworkNotFound(uuid=instance_nic)
def _create_server_volume_heat(self, flavor, image_id, security_groups, service_type, volume_size): client = create_heat_client(self.context) novaclient = create_nova_client(self.context) cinderclient = create_cinder_client(self.context) heat_template = template.HeatTemplate().template() parameters = { "KeyName": "heatkey", "Flavor": flavor["name"], "VolumeSize": volume_size, "ServiceType": "mysql", "InstanceId": self.id, } stack_name = "trove-%s" % self.id stack = client.stacks.create(stack_name=stack_name, template=heat_template, parameters=parameters) stack = client.stacks.get(stack_name) utils.poll_until( lambda: client.stacks.get(stack_name), lambda stack: stack.stack_status in ["CREATE_COMPLETE", "CREATE_FAILED"], sleep_time=2, time_out=HEAT_TIME_OUT, ) resource = client.resources.get(stack.id, "BaseInstance") server = novaclient.servers.get(resource.physical_resource_id) resource = client.resources.get(stack.id, "DataVolume") volume = cinderclient.volumes.get(resource.physical_resource_id) volume_info = self._build_volume(volume) self.update_db(compute_instance_id=server.id, volume_id=volume.id) return server, volume_info
def _create_instances(context, db_info, datastore, datastore_version, instances, extended_properties, locality): Redis_conf = CONF.get(datastore_version.manager) num_instances = len(instances) total_volume_allocation = 0 # Validate and Cache flavors nova_client = remote.create_nova_client(context) unique_flavors = set(map(lambda i: i['flavor_id'], instances)) flavor_cache = {} for fid in unique_flavors: try: flavor_cache.update({fid: nova_client.flavors.get(fid)}) except nova_exceptions.NotFound: raise exception.FlavorNotFound(uuid=fid) # Checking volumes name_index = 1 for instance in instances: if not instance.get('name'): instance['name'] = "%s-member-%s" % (db_info.name, name_index) name_index += 1 volume_size = instance.get('volume_size') if Redis_conf.volume_support: models.validate_volume_size(volume_size) total_volume_allocation += volume_size else: if volume_size: raise exception.VolumeNotSupported() ephemeral_support = Redis_conf.device_path flavor_id = instance['flavor_id'] flavor = flavor_cache[flavor_id] if ephemeral_support and flavor.ephemeral == 0: raise exception.LocalStorageNotSpecified(flavor=flavor_id) # Check quotas quota_request = {'instances': num_instances, 'volumes': total_volume_allocation} check_quotas(context.tenant, quota_request) # Creating member instances return map(lambda instance: inst_models.Instance.create(context, instance['name'], instance['flavor_id'], datastore_version.image_id, [], [], datastore, datastore_version, instance.get('volume_size'), None, instance.get( 'availability_zone', None), instance.get('nics', None), configuration_id=None, cluster_config={ "id": db_info.id, "instance_type": "member"}, locality=locality ), instances)
def test_create_with_catalog_all_opts(self): cfg.CONF.set_override('nova_compute_service_type', 'computev3') cfg.CONF.set_override('os_region_name', 'RegionTwo') client = remote.create_nova_client( TroveContext(service_catalog=self.service_catalog)) self.assertEqual(self.computev3_public_url_region_two, client.client.management_url)
def load(context, include_clustered): def load_simple_instance(context, db, status, **kwargs): return SimpleInstance(context, db, status) if context is None: raise TypeError("Argument context not defined.") client = create_nova_client(context) servers = client.servers.list() if include_clustered: db_infos = DBInstance.find_all(tenant_id=context.tenant, deleted=False) else: db_infos = DBInstance.find_all(tenant_id=context.tenant, cluster_id=None, deleted=False) limit = int(context.limit or Instances.DEFAULT_LIMIT) if limit > Instances.DEFAULT_LIMIT: limit = Instances.DEFAULT_LIMIT data_view = DBInstance.find_by_pagination('instances', db_infos, "foo", limit=limit, marker=context.marker) next_marker = data_view.next_page_marker find_server = create_server_list_matcher(servers) for db in db_infos: LOG.debug("Checking for db [id=%(db_id)s, " "compute_instance_id=%(instance_id)s]." % {'db_id': db.id, 'instance_id': db.compute_instance_id}) ret = Instances._load_servers_status(load_simple_instance, context, data_view.collection, find_server) return ret, next_marker
def list_datastore_version_flavor_associations(cls, context, datastore_type, datastore_version_id): if datastore_type and datastore_version_id: """ All nova flavors are permitted for a datastore_version unless one or more entries are found in datastore_version_metadata, in which case only those are permitted. """ (datastore, datastore_version) = get_datastore_version( type=datastore_type, version=datastore_version_id) # If datastore_version_id and flavor key exists in the # metadata table return all the associated flavors for # that datastore version. nova_flavors = create_nova_client(context).flavors.list() bound_flavors = DBDatastoreVersionMetadata.find_all( datastore_version_id=datastore_version.id, key='flavor', deleted=False ) if (bound_flavors.count() != 0): bound_flavors = tuple(f.value for f in bound_flavors) # Generate a filtered list of nova flavors ds_nova_flavors = (f for f in nova_flavors if f.id in bound_flavors) associated_flavors = tuple(flavor_model(flavor=item) for item in ds_nova_flavors) else: # Return all nova flavors if no flavor metadata found # for datastore_version. associated_flavors = tuple(flavor_model(flavor=item) for item in nova_flavors) return associated_flavors else: msg = _("Specify both the datastore and datastore_version_id.") raise exception.BadRequest(msg)
def test_create_with_catalog_all_opts(self): cfg.CONF.set_override('nova_compute_service_type', 'computev3') cfg.CONF.set_override('os_region_name', 'RegionTwo') client = remote.create_nova_client( TroveContext(service_catalog=self.service_catalog)) self.assertEqual(self.computev3_public_url_region_two, client.client.endpoint_override)
def test_create_with_conf_override_trailing_slash(self): nova_url_from_conf = 'http://example.com/' tenant_from_ctx = uuid.uuid4().hex cfg.CONF.set_override('nova_compute_url', nova_url_from_conf) client = remote.create_nova_client( TroveContext(tenant=tenant_from_ctx)) self.assertEqual('%s%s' % (nova_url_from_conf, tenant_from_ctx), client.client.endpoint_override)
def load(context, id): client = create_nova_client(context) account = client.accounts.get_instances(id) db_infos = DBInstance.find_all(tenant_id=id, deleted=False) servers = [Server(server) for server in account.servers] instances = MgmtInstances.load_status_from_existing( context, db_infos, servers) return Account(id, instances)
def load_all(context): client = create_nova_client(context) LOG.debug("Client.rdhosts=" + str(client.rdhosts)) rdhosts = client.rdhosts.list() LOG.debug("RDHOSTS=" + str(rdhosts)) for rdhost in rdhosts: LOG.debug("rdhost=" + str(rdhost)) return [SimpleHost(rdhost.name, rdhost.instanceCount) for rdhost in rdhosts]
def load(context, id): client = create_nova_client(context) account = client.accounts.get_instances(id) db_infos = DBInstance.find_all(tenant_id=id, deleted=False) servers = [Server(server) for server in account.servers] instances = MgmtInstances.load_status_from_existing(context, db_infos, servers) return Account(id, instances)
def test_create_with_conf_override_trailing_slash(self): nova_url_from_conf = 'http://example.com/' tenant_from_ctx = 'abc' cfg.CONF.set_override('nova_compute_url', nova_url_from_conf) client = remote.create_nova_client( TroveContext(tenant=tenant_from_ctx)) self.assertEqual('%s%s' % (nova_url_from_conf, tenant_from_ctx), client.client.management_url)
def test_create_with_conf_override(self): nova_url_from_conf = 'http://example.com' tenant_from_ctx = uuid.uuid4().hex cfg.CONF.set_override('nova_compute_url', nova_url_from_conf) client = remote.create_nova_client( TroveContext(tenant=tenant_from_ctx)) self.assertEqual('%s/%s' % (nova_url_from_conf, tenant_from_ctx), client.client.management_url)
def create(cls, context, locality, name_suffix): client = create_nova_client(context) server_group_name = "%s_%s" % ('locality', name_suffix) server_group = client.server_groups.create( name=server_group_name, policies=[locality]) LOG.debug("Created '%s' server group called %s (id: %s)." % (locality, server_group_name, server_group.id)) return server_group
def test_create_with_conf_override(self): nova_url_from_conf = 'http://example.com' tenant_from_ctx = 'abc' cfg.CONF.set_override('nova_compute_url', nova_url_from_conf) client = remote.create_nova_client( TroveContext(tenant=tenant_from_ctx)) self.assertEqual('%s/%s' % (nova_url_from_conf, tenant_from_ctx), client.client.management_url)
def create(cls, context, name_suffix, locality): client = create_nova_client(context) server_group_name = "%s_%s" % ('locality', name_suffix) server_group = client.server_groups.create(name=server_group_name, policies=[locality]) LOG.debug("Created '%s' server group called %s (id: %s)." % (locality, server_group_name, server_group.id)) return server_group
def load(cls, context, compute_id): client = create_nova_client(context) server_group = None try: for sg in client.server_groups.list(): if compute_id in sg.members: server_group = sg except Exception: LOG.exception(_("Could not load server group for compute %s") % compute_id) return server_group
def delete(cls, context, server_group, force=False): # Only delete the server group if we're the last member in it, or if # it has no members if server_group: if force or len(server_group.members) <= 1: client = create_nova_client(context) client.server_groups.delete(server_group.id) LOG.debug("Deleted server group %s." % server_group.id) else: LOG.debug("Skipping delete of server group %s (members: %s)." % (server_group.id, server_group.members))
def load(cls, context, compute_id): client = create_nova_client(context) server_group = None try: for sg in client.server_groups.list(): if compute_id in sg.members: server_group = sg except Exception: LOG.exception( _("Could not load server group for compute %s") % compute_id) return server_group
def delete(cls, context, server_group, inst_id): # Only delete the server group if we're the last member in it if server_group: if len(server_group.members) == 1: client = create_nova_client(context) client.server_groups.delete(server_group.id) LOG.debug("Deleted server group for instance %s (id: %s)." % (inst_id, server_group.id)) else: LOG.debug("Skipping delete of server group %s (members: %s)." % (server_group.id, server_group.members))
def load_server(context, instance_id, server_id): """Loads a server or raises an exception.""" client = create_nova_client(context) try: server = client.servers.get(server_id) except nova_exceptions.NotFound: LOG.debug("Could not find nova server_id(%s)" % server_id) raise exception.ComputeInstanceNotFound(instance_id=instance_id, server_id=server_id) except nova_exceptions.ClientException as e: raise exception.TroveError(str(e)) return server
def __init__(self, flavor=None, context=None, flavor_id=None): if flavor: self.flavor = flavor return if flavor_id and context: try: client = create_nova_client(context) self.flavor = client.flavors.get(flavor_id) except nova_exceptions.NotFound, e: raise exception.NotFound(uuid=flavor_id) except nova_exceptions.ClientException, e: raise exception.TroveError(str(e))
def load_simple_instance_server_status(context, db_info): """Loads a server or raises an exception.""" if 'BUILDING' == db_info.task_status.action: db_info.server_status = "BUILD" db_info.addresses = {} else: client = create_nova_client(context) try: server = client.servers.get(db_info.compute_instance_id) db_info.server_status = server.status db_info.addresses = server.addresses except nova_exceptions.NotFound: db_info.server_status = "SHUTDOWN" db_info.addresses = {}
def create(cls, context, locality, name_suffix): client = create_nova_client(context) server_group_name = "%s_%s" % ('locality', name_suffix) server_group = client.server_groups.create(name=server_group_name, policies=[locality]) LOG.debug( "Created '%(locality)s' server group called %(group_name)s " "(id: %(group_id)s).", { 'locality': locality, 'group_name': server_group_name, 'group_id': server_group.id }) return server_group
def _create_server(self, flavor_id, image_id, security_groups, service_type, block_device_mapping): nova_client = create_nova_client(self.context) files = {"/etc/guest_info": ("[DEFAULT]\nguest_id=%s\n" "service_type=%s\n" % (self.id, service_type))} name = self.hostname or self.name bdmap = block_device_mapping server = nova_client.servers.create(name, image_id, flavor_id, files=files, security_groups=security_groups, block_device_mapping=bdmap) LOG.debug(_("Created new compute instance %s.") % server.id) return server
def load_mgmt_instance(cls, context, id): try: instance = load_instance(cls, context, id, needs_server=True) client = remote.create_nova_client(context) server = client.rdservers.get(instance.server_id) instance.server.host = server.host instance.server.deleted = server.deleted instance.server.deleted_at = server.deleted_at instance.server.local_id = server.local_id assert instance.server is not None except Exception as e: LOG.error(e) instance = load_instance(cls, context, id, needs_server=False) return instance
def create(self, req, body, tenant_id): """Adds a new datastore version.""" context = req.environ[wsgi.CONTEXT_KEY] datastore_name = body['version']['datastore_name'] version_name = body['version']['name'] manager = body['version']['datastore_manager'] image_id = body['version']['image'] packages = body['version']['packages'] if type(packages) is list: packages = ','.join(packages) active = body['version']['active'] default = body['version']['default'] LOG.info( _("Tenant: '%(tenant)s' is adding the datastore " "version: '%(version)s' to datastore: '%(datastore)s'") % { 'tenant': tenant_id, 'version': version_name, 'datastore': datastore_name }) client = remote.create_nova_client(context) try: client.images.get(image_id) except nova_exceptions.NotFound: raise exception.ImageNotFound(uuid=image_id) try: datastore = models.Datastore.load(datastore_name) except exception.DatastoreNotFound: # Create the datastore if datastore_name does not exists. LOG.info(_("Creating datastore %s") % datastore_name) datastore = models.DBDatastore() datastore.id = utils.generate_uuid() datastore.name = datastore_name datastore.save() try: models.DatastoreVersion.load(datastore, version_name) raise exception.DatastoreVersionAlreadyExists(name=version_name) except exception.DatastoreVersionNotFound: models.update_datastore_version(datastore.name, version_name, manager, image_id, packages, active) if default: models.update_datastore(datastore.name, version_name) return wsgi.Result(None, 202)
def _create_server_volume_heat(self, flavor, image_id, datastore_manager, volume_size, availability_zone): LOG.debug(_("begin _create_server_volume_heat for id: %s") % self.id) client = create_heat_client(self.context) novaclient = create_nova_client(self.context) template_obj = template.load_heat_template(datastore_manager) heat_template_unicode = template_obj.render() try: heat_template = heat_template_unicode.encode('ascii') except UnicodeEncodeError: LOG.error(_("heat template ascii encode issue")) raise TroveError("heat template ascii encode issue") parameters = {"Flavor": flavor["name"], "VolumeSize": volume_size, "InstanceId": self.id, "ImageId": image_id, "DatastoreManager": datastore_manager, "AvailabilityZone": availability_zone} stack_name = 'trove-%s' % self.id client.stacks.create(stack_name=stack_name, template=heat_template, parameters=parameters) stack = client.stacks.get(stack_name) utils.poll_until( lambda: client.stacks.get(stack_name), lambda stack: stack.stack_status in ['CREATE_COMPLETE', 'CREATE_FAILED'], sleep_time=2, time_out=HEAT_TIME_OUT) resource = client.resources.get(stack.id, 'BaseInstance') server = novaclient.servers.get(resource.physical_resource_id) if CONF.trove_volume_support: cinderclient = create_cinder_client(self.context) resource = client.resources.get(stack.id, 'DataVolume') volume = cinderclient.volumes.get(resource.physical_resource_id) volume_info = self._build_volume(volume) self.update_db(compute_instance_id=server.id, volume_id=volume.id) else: volume_info = self._build_volume_info(volume_size) self.update_db(compute_instance_id=server.id) LOG.debug(_("end _create_server_volume_heat for id: %s") % self.id) return server, volume_info
def validate_instance_flavors(context, instances, volume_enabled, ephemeral_enabled): """Validate flavors for given instance definitions.""" nova_cli_cache = dict() for instance in instances: region_name = instance.get('region_name') flavor_id = instance['flavor_id'] try: if region_name is None: nova_client = remote.create_nova_client(context, region_name) else: if region_name not in nova_cli_cache: nova_client = remote.create_nova_client( context, region_name) nova_cli_cache[region_name] = nova_client else: nova_client = nova_cli_cache[region_name] flavor = nova_client.flavors.get(flavor_id) if (not volume_enabled and (ephemeral_enabled and flavor.ephemeral == 0)): raise exception.LocalStorageNotSpecified(flavor=flavor_id) except nova_exceptions.NotFound: raise exception.FlavorNotFound(uuid=flavor_id)
def load_mgmt_instances(context, deleted=None, client=None): if not client: client = remote.create_nova_client(context) try: mgmt_servers = client.rdservers.list() except AttributeError: mgmt_servers = client.servers.list(search_opts={'all_tenants': 1}) LOG.info("Found %d servers in Nova" % len(mgmt_servers if mgmt_servers else [])) if deleted is not None: db_infos = instance_models.DBInstance.find_all(deleted=deleted) else: db_infos = instance_models.DBInstance.find_all() instances = MgmtInstances.load_status_from_existing(context, db_infos, mgmt_servers) return instances
def __init__(self, flavor=None, context=None, flavor_id=None): if flavor: self.flavor = flavor return if flavor_id and context: try: client = create_nova_client(context) self.flavor = client.flavors.get(flavor_id) except nova_exceptions.NotFound as e: raise exception.NotFound(uuid=flavor_id) except nova_exceptions.ClientException as e: raise exception.TroveError(str(e)) return msg = ("Flavor is not defined, and" " context and flavor_id were not specified.") raise exception.InvalidModelError(errors=msg)
def _render_cluster_config(self, context, instance, cluster_ips, cluster_name, replication_user): client = create_nova_client(context) flavor = client.flavors.get(instance.flavor_id) instance_ip = self.get_ip(instance) config = ClusterConfigTemplate(self.datastore_version, flavor, instance.id) replication_user_pass = "******" % replication_user config_rendered = config.render( replication_user_pass=replication_user_pass, cluster_ips=cluster_ips, cluster_name=cluster_name, instance_ip=instance_ip, instance_name=instance.name, ) return config_rendered
def _render_cluster_config(self, context, instance, cluster_ips, cluster_name, replication_user): client = create_nova_client(context) flavor = client.flavors.get(instance.flavor_id) instance_ip = self.get_ip(instance) config = ClusterConfigTemplate( self.datastore_version, flavor, instance.id) replication_user_pass = "******" % replication_user config_rendered = config.render( replication_user_pass=replication_user_pass, cluster_ips=cluster_ips, cluster_name=cluster_name, instance_ip=instance_ip, instance_name=instance.name, ) return config_rendered
def create(self, req, body, tenant_id): context = req.environ[wsgi.CONTEXT_KEY] name = body['flavor']['name'] vcpus = body['flavor']['vcpus'] disk = body['flavor']['disk'] ram = body['flavor']['ram'] client = create_nova_client(context) try: flavor = client.flavors.create(name, ram, vcpus, disk, rxtx_factor=0) except Exception as ex: msg = (_("Failed create flavor for tenant_id %s, %s"%(tenant_id, ex))) LOG.error(msg) raise exception.BadRequest(msg) return wsgi.Result(views.FlavorView(flavor, req).data(), 200)
def get_flavors_from_instance_defs(context, instances, volume_enabled, ephemeral_enabled): """Load and validate flavors for given instance definitions.""" flavors = dict() nova_client = remote.create_nova_client(context) for instance in instances: flavor_id = instance["flavor_id"] if flavor_id not in flavors: try: flavor = nova_client.flavors.get(flavor_id) if not volume_enabled and (ephemeral_enabled and flavor.ephemeral == 0): raise exception.LocalStorageNotSpecified(flavor=flavor_id) flavors[flavor_id] = flavor except nova_exceptions.NotFound: raise exception.FlavorNotFound(uuid=flavor_id) return flavors
def validate_instance_nics(context, instances): """Checking networks are same for the cluster.""" instance_nics = [] for instance in instances: nics = instance.get('nics') if nics: instance_nics.append(nics[0].get('net-id')) if len(set(instance_nics)) > 1: raise exception.ClusterNetworksNotEqual() if not instance_nics: return instance_nic = instance_nics[0] try: nova_client = remote.create_nova_client(context) nova_client.networks.get(instance_nic) except nova_exceptions.NotFound: raise exception.NetworkNotFound(uuid=instance_nic)
def _create_server_volume_heat(self, flavor, image_id, datastore_manager, volume_size, availability_zone): LOG.debug(_("begin _create_server_volume_heat for id: %s") % self.id) client = create_heat_client(self.context) novaclient = create_nova_client(self.context) cinderclient = create_cinder_client(self.context) template_obj = template.load_heat_template(datastore_manager) heat_template_unicode = template_obj.render() try: heat_template = heat_template_unicode.encode('ascii') except UnicodeEncodeError: LOG.error(_("heat template ascii encode issue")) raise TroveError("heat template ascii encode issue") parameters = { "Flavor": flavor["name"], "VolumeSize": volume_size, "InstanceId": self.id, "ImageId": image_id, "DatastoreManager": datastore_manager, "AvailabilityZone": availability_zone } stack_name = 'trove-%s' % self.id client.stacks.create(stack_name=stack_name, template=heat_template, parameters=parameters) stack = client.stacks.get(stack_name) utils.poll_until(lambda: client.stacks.get(stack_name), lambda stack: stack.stack_status in ['CREATE_COMPLETE', 'CREATE_FAILED'], sleep_time=2, time_out=HEAT_TIME_OUT) resource = client.resources.get(stack.id, 'BaseInstance') server = novaclient.servers.get(resource.physical_resource_id) resource = client.resources.get(stack.id, 'DataVolume') volume = cinderclient.volumes.get(resource.physical_resource_id) volume_info = self._build_volume(volume) self.update_db(compute_instance_id=server.id, volume_id=volume.id) LOG.debug(_("end _create_server_volume_heat for id: %s") % self.id) return server, volume_info
def get_flavors_from_instance_defs(context, instances, volume_enabled, ephemeral_enabled): """Load and validate flavors for given instance definitions.""" flavors = dict() nova_client = remote.create_nova_client(context) for instance in instances: flavor_id = instance['flavor_id'] if flavor_id not in flavors: try: flavor = nova_client.flavors.get(flavor_id) if (not volume_enabled and (ephemeral_enabled and flavor.ephemeral == 0)): raise exception.LocalStorageNotSpecified(flavor=flavor_id) flavors[flavor_id] = flavor except nova_exceptions.NotFound: raise exception.FlavorNotFound(uuid=flavor_id) return flavors
def _validate_cluster_instances(context, instances, datastore, datastore_version): """Validate the flavor and volume""" ds_conf = CONF.get(datastore_version.manager) num_instances = len(instances) # Check number of instances is at least min_cluster_member_count if num_instances < ds_conf.min_cluster_member_count: raise exception.ClusterNumInstancesNotLargeEnough( num_instances=ds_conf.min_cluster_member_count) # Checking volumes and get delta for quota check cluster_models.validate_instance_flavors(context, instances, ds_conf.volume_support, ds_conf.device_path) req_volume_size = cluster_models.get_required_volume_size( instances, ds_conf.volume_support) cluster_models.assert_homogeneous_cluster(instances) deltas = {'instances': num_instances, 'volumes': req_volume_size} # quota check check_quotas(context.tenant, deltas) # Checking networks are same for the cluster instance_nics = [] for instance in instances: nics = instance.get('nics') if nics: instance_nics.append(nics[0].get('net-id')) if len(set(instance_nics)) > 1: raise exception.ClusterNetworksNotEqual() if not instance_nics: return instance_nic = instance_nics[0] try: nova_client = remote.create_nova_client(context) nova_client.networks.get(instance_nic) except nova_exceptions.NotFound: raise exception.NetworkNotFound(uuid=instance_nic)