Example #1
0
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)
Example #2
0
 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
Example #3
0
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
Example #4
0
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
Example #5
0
 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)
Example #6
0
    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)
Example #7
0
 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
Example #8
0
    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
Example #9
0
    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)
Example #10
0
 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)
Example #11
0
    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)
Example #12
0
    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)
Example #13
0
    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
Example #14
0
 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)
Example #15
0
    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)
Example #16
0
 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)
Example #17
0
    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
Example #18
0
 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)
Example #19
0
    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)
Example #20
0
 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)
Example #21
0
    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)
Example #22
0
 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)
Example #23
0
 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)
Example #24
0
 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]
Example #25
0
 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)
Example #26
0
 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)
Example #27
0
    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)
Example #28
0
    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
Example #29
0
    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)
Example #30
0
    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
Example #31
0
 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]
Example #32
0
 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
Example #33
0
 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))
Example #34
0
 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
Example #35
0
 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))
Example #36
0
 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))
Example #37
0
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
Example #38
0
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
Example #39
0
 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))
Example #40
0
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 = {}
Example #41
0
    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
Example #42
0
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 = {}
Example #43
0
 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
Example #44
0
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
Example #45
0
    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)
Example #46
0
    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
Example #47
0
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)
Example #48
0
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
Example #49
0
 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)
Example #50
0
 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)
Example #51
0
 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
Example #52
0
 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
Example #53
0
    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)  
Example #54
0
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
Example #55
0
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)
Example #56
0
    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
Example #57
0
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
Example #58
0
File: api.py Project: no2a/trove
    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)