Beispiel #1
0
class SecurityGroupList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    #              SecurityGroup <= version 1.1
    VERSION = '1.0'

    fields = {
        'objects': fields.ListOfObjectsField('SecurityGroup'),
    }
    child_versions = {
        '1.0': '1.1',
        # NOTE(danms): SecurityGroup was at 1.1 before we added this
    }

    def __init__(self, *args, **kwargs):
        super(SecurityGroupList, self).__init__(*args, **kwargs)
        self.objects = []
        self.obj_reset_changes()

    @base.remotable_classmethod
    def get_all(cls, context):
        groups = db.security_group_get_all(context)
        return base.obj_make_list(context, cls(context), objects.SecurityGroup,
                                  groups)

    @base.remotable_classmethod
    def get_by_project(cls, context, project_id):
        groups = db.security_group_get_by_project(context, project_id)
        return base.obj_make_list(context, cls(context), objects.SecurityGroup,
                                  groups)

    @base.remotable_classmethod
    def get_by_instance(cls, context, instance):
        groups = db.security_group_get_by_instance(context, instance.uuid)
        return base.obj_make_list(context, cls(context), objects.SecurityGroup,
                                  groups)
Beispiel #2
0
class InstanceMappingList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    VERSION = '1.0'

    fields = {
        'objects': fields.ListOfObjectsField('InstanceMapping'),
    }
    child_versions = {
        '1.0': '1.0',
    }

    @staticmethod
    def _get_by_project_id_from_db(context, project_id):
        session = db_api.get_api_session()

        with session.begin():
            db_mappings = session.query(api_models.InstanceMapping).filter_by(
                project_id=project_id).all()

        return db_mappings

    @base.remotable_classmethod
    def get_by_project_id(cls, context, project_id):
        db_mappings = cls._get_by_project_id_from_db(context, project_id)

        return base.obj_make_list(context, cls(), objects.InstanceMapping,
                                  db_mappings)
Beispiel #3
0
class KeyPairList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    #              KeyPair <= version 1.1
    # Version 1.1: KeyPair <= version 1.2
    # Version 1.2: KeyPair <= version 1.3
    VERSION = '1.2'

    fields = {
        'objects': fields.ListOfObjectsField('KeyPair'),
    }
    child_versions = {
        '1.0': '1.1',
        # NOTE(danms): KeyPair was at 1.1 before we added this
        '1.1': '1.2',
        '1.2': '1.3',
    }

    @base.remotable_classmethod
    def get_by_user(cls, context, user_id):
        db_keypairs = db.key_pair_get_all_by_user(context, user_id)
        return base.obj_make_list(context, cls(context), objects.KeyPair,
                                  db_keypairs)

    @base.remotable_classmethod
    def get_count_by_user(cls, context, user_id):
        return db.key_pair_count_by_user(context, user_id)
Beispiel #4
0
class FlavorList(base.ObjectListBase, base.NovaObject):
    VERSION = '1.1'

    fields = {
        'objects': fields.ListOfObjectsField('Flavor'),
    }
    child_versions = {
        '1.0': '1.0',
        '1.1': '1.1',
    }

    @base.remotable_classmethod
    def get_all(cls,
                context,
                inactive=False,
                filters=None,
                sort_key='flavorid',
                sort_dir='asc',
                limit=None,
                marker=None):
        db_flavors = db.flavor_get_all(context,
                                       inactive=inactive,
                                       filters=filters,
                                       sort_key=sort_key,
                                       sort_dir=sort_dir,
                                       limit=limit,
                                       marker=marker)
        return base.obj_make_list(context,
                                  cls(context),
                                  objects.Flavor,
                                  db_flavors,
                                  expected_attrs=['extra_specs'])
Beispiel #5
0
class ServiceList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    #              Service <= version 1.2
    # Version 1.1  Service version 1.3
    # Version 1.2: Service version 1.4
    # Version 1.3: Service version 1.5
    # Version 1.4: Service version 1.6
    # Version 1.5: Service version 1.7
    # Version 1.6: Service version 1.8
    # Version 1.7: Service version 1.9
    # Version 1.8: Service version 1.10
    # Version 1.9: Added get_by_binary() and Service version 1.11
    # Version 1.10: Service version 1.12
    VERSION = '1.10'

    fields = {
        'objects': fields.ListOfObjectsField('Service'),
    }
    child_versions = {
        '1.0': '1.2',
        # NOTE(danms): Service was at 1.2 before we added this
        '1.1': '1.3',
        '1.2': '1.4',
        '1.3': '1.5',
        '1.4': '1.6',
        '1.5': '1.7',
        '1.6': '1.8',
        '1.7': '1.9',
        '1.8': '1.10',
        '1.9': '1.11',
        '1.10': '1.12',
    }

    @base.remotable_classmethod
    def get_by_topic(cls, context, topic):
        db_services = db.service_get_all_by_topic(context, topic)
        return base.obj_make_list(context, cls(context), objects.Service,
                                  db_services)

    @base.remotable_classmethod
    def get_by_binary(cls, context, binary):
        db_services = db.service_get_all_by_binary(context, binary)
        return base.obj_make_list(context, cls(context), objects.Service,
                                  db_services)

    @base.remotable_classmethod
    def get_by_host(cls, context, host):
        db_services = db.service_get_all_by_host(context, host)
        return base.obj_make_list(context, cls(context), objects.Service,
                                  db_services)

    @base.remotable_classmethod
    def get_all(cls, context, disabled=None, set_zones=False):
        db_services = db.service_get_all(context, disabled=disabled)
        if set_zones:
            db_services = availability_zones.set_availability_zones(
                context, db_services)
        return base.obj_make_list(context, cls(context), objects.Service,
                                  db_services)
Beispiel #6
0
class AgentList(base.ObjectListBase, base.NovaObject):
    VERSION = '1.0'

    fields = {
        'objects': fields.ListOfObjectsField('Agent'),
        }
    child_versions = {
        '1.0': '1.0',
        }

    @base.remotable_classmethod
    def get_all(cls, context, hypervisor=None):
        db_agents = db.agent_build_get_all(context, hypervisor=hypervisor)
        return base.obj_make_list(context, cls(), objects.Agent, db_agents)
Beispiel #7
0
class InstanceActionEventList(base.ObjectListBase, base.NovaObject):
    fields = {
        'objects': fields.ListOfObjectsField('InstanceActionEvent'),
    }
    child_versions = {
        '1.0': '1.0',
        '1.1': '1.1',
    }

    @base.remotable_classmethod
    def get_by_action(cls, context, action_id):
        db_events = db.action_events_get(context, action_id)
        return base.obj_make_list(context, cls(context),
                                  objects.InstanceActionEvent, db_events)
Beispiel #8
0
class DNSDomainList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    VERSION = '1.0'
    fields = {
        'objects': fields.ListOfObjectsField('DNSDomain'),
    }
    child_versions = {
        '1.0': '1.0',
    }

    @base.remotable_classmethod
    def get_all(cls, context):
        db_domains = db.dnsdomain_get_all(context)
        return base.obj_make_list(context, cls(context), objects.DNSDomain,
                                  db_domains)
Beispiel #9
0
class AggregateList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    # Version 1.1: Added key argument to get_by_host()
    #              Aggregate <= version 1.1
    # Version 1.2: Added get_by_metadata_key
    VERSION = '1.2'

    fields = {
        'objects': fields.ListOfObjectsField('Aggregate'),
    }
    child_versions = {
        '1.0': '1.1',
        '1.1': '1.1',
        # NOTE(danms): Aggregate was at 1.1 before we added this
        '1.2': '1.1',
    }

    @classmethod
    def _filter_db_aggregates(cls, db_aggregates, hosts):
        if not isinstance(hosts, set):
            hosts = set(hosts)
        filtered_aggregates = []
        for db_aggregate in db_aggregates:
            for host in db_aggregate['hosts']:
                if host in hosts:
                    filtered_aggregates.append(db_aggregate)
                    break
        return filtered_aggregates

    @base.remotable_classmethod
    def get_all(cls, context):
        db_aggregates = db.aggregate_get_all(context)
        return base.obj_make_list(context, cls(context), objects.Aggregate,
                                  db_aggregates)

    @base.remotable_classmethod
    def get_by_host(cls, context, host, key=None):
        db_aggregates = db.aggregate_get_by_host(context, host, key=key)
        return base.obj_make_list(context, cls(context), objects.Aggregate,
                                  db_aggregates)

    @base.remotable_classmethod
    def get_by_metadata_key(cls, context, key, hosts=None):
        db_aggregates = db.aggregate_get_by_metadata_key(context, key=key)
        if hosts:
            db_aggregates = cls._filter_db_aggregates(db_aggregates, hosts)
        return base.obj_make_list(context, cls(context), objects.Aggregate,
                                  db_aggregates)
Beispiel #10
0
class InstanceActionList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    #              InstanceAction <= version 1.1
    VERSION = '1.0'
    fields = {
        'objects': fields.ListOfObjectsField('InstanceAction'),
    }
    child_versions = {
        '1.0': '1.1',
        # NOTE(danms): InstanceAction was at 1.1 before we added this
    }

    @base.remotable_classmethod
    def get_by_instance_uuid(cls, context, instance_uuid):
        db_actions = db.actions_get(context, instance_uuid)
        return base.obj_make_list(context, cls(), InstanceAction, db_actions)
Beispiel #11
0
class NUMATopology(base.NovaObject, base.NovaObjectDictCompat):
    # Version 1.0: Initial version
    # Version 1.1: Update NUMACell to 1.1
    # Version 1.2: Update NUMACell to 1.2
    VERSION = '1.2'

    fields = {
        'cells': fields.ListOfObjectsField('NUMACell'),
    }

    obj_relationships = {
        'cells': [('1.0', '1.0'), ('1.1', '1.1'), ('1.2', '1.2')]
    }

    @classmethod
    def obj_from_primitive(cls, primitive):
        if 'patron_object.name' in primitive:
            obj_topology = super(NUMATopology,
                                 cls).obj_from_primitive(primitive)
        else:
            # NOTE(sahid): This compatibility code needs to stay until we can
            # guarantee that there are no cases of the old format stored in
            # the database (or forever, if we can never guarantee that).
            obj_topology = NUMATopology._from_dict(primitive)
        return obj_topology

    def _to_json(self):
        return jsonutils.dumps(self.obj_to_primitive())

    @classmethod
    def obj_from_db_obj(cls, db_obj):
        return cls.obj_from_primitive(jsonutils.loads(db_obj))

    def __len__(self):
        """Defined so that boolean testing works the same as for lists."""
        return len(self.cells)

    def _to_dict(self):
        # TODO(sahid): needs to be removed.
        return {'cells': [cell._to_dict() for cell in self.cells]}

    @classmethod
    def _from_dict(cls, data_dict):
        return cls(cells=[
            NUMACell._from_dict(cell_dict)
            for cell_dict in data_dict.get('cells', [])
        ])
Beispiel #12
0
class NetworkRequestList(obj_base.ObjectListBase, obj_base.NovaObject):
    fields = {
        'objects': fields.ListOfObjectsField('NetworkRequest'),
    }

    child_versions = {
        '1.0': '1.0',
        '1.1': '1.1',
    }
    VERSION = '1.1'

    def as_tuples(self):
        return [x.to_tuple() for x in self.objects]

    @property
    def is_single_unspecified(self):
        return ((len(self.objects) == 1) and
                (self.objects[0].to_tuple() == NetworkRequest().to_tuple()))
Beispiel #13
0
class VirtCPUModel(base.NovaObject):
    # Version 1.0: Initial version
    VERSION = '1.0'

    fields = {
        'arch':
        fields.EnumField(nullable=True, valid_values=arch.ALL),
        'vendor':
        fields.StringField(nullable=True),
        'topology':
        fields.ObjectField('VirtCPUTopology', nullable=True),
        'features':
        fields.ListOfObjectsField("VirtCPUFeature", default=[]),
        'mode':
        fields.EnumField(nullable=True, valid_values=cpumodel.ALL_CPUMODES),
        'model':
        fields.StringField(nullable=True),
        'match':
        fields.EnumField(nullable=True, valid_values=cpumodel.ALL_MATCHES),
    }

    obj_relationships = {
        'topology': [('1.0', '1.0')],
        'features': [('1.0', '1.0')],
    }

    def obj_load_attr(self, attrname):
        setattr(self, attrname, None)

    def to_json(self):
        return jsonutils.dumps(self.obj_to_primitive())

    @classmethod
    def from_json(cls, jsonstr):
        return cls.obj_from_primitive(jsonutils.loads(jsonstr))

    @base.remotable_classmethod
    def get_by_instance_uuid(cls, context, instance_uuid):
        db_extra = db.instance_extra_get_by_instance_uuid(
            context, instance_uuid, columns=['vcpu_model'])
        if not db_extra or not db_extra['vcpu_model']:
            return None
        return cls.obj_from_primitive(jsonutils.loads(db_extra['vcpu_model']))
Beispiel #14
0
class NetworkList(obj_base.ObjectListBase, obj_base.NovaObject):
    # Version 1.0: Initial version
    # Version 1.1: Added get_by_project()
    # Version 1.2: Network <= version 1.2
    VERSION = '1.2'

    fields = {
        'objects': fields.ListOfObjectsField('Network'),
    }
    child_versions = {
        '1.0': '1.0',
        '1.1': '1.1',
        '1.2': '1.2',
    }

    @obj_base.remotable_classmethod
    def get_all(cls, context, project_only='allow_none'):
        db_networks = db.network_get_all(context, project_only)
        return obj_base.obj_make_list(context, cls(context), objects.Network,
                                      db_networks)

    @obj_base.remotable_classmethod
    def get_by_uuids(cls, context, network_uuids, project_only='allow_none'):
        db_networks = db.network_get_all_by_uuids(context, network_uuids,
                                                  project_only)
        return obj_base.obj_make_list(context, cls(context), objects.Network,
                                      db_networks)

    @obj_base.remotable_classmethod
    def get_by_host(cls, context, host):
        db_networks = db.network_get_all_by_host(context, host)
        return obj_base.obj_make_list(context, cls(context), objects.Network,
                                      db_networks)

    @obj_base.remotable_classmethod
    def get_by_project(cls, context, project_id, associate=True):
        db_networks = db.project_get_networks(context,
                                              project_id,
                                              associate=associate)
        return obj_base.obj_make_list(context, cls(context), objects.Network,
                                      db_networks)
Beispiel #15
0
class SecurityGroupRuleList(base.ObjectListBase, base.NovaObject):
    fields = {
        'objects': fields.ListOfObjectsField('SecurityGroupRule'),
        }
    VERSION = '1.1'
    child_versions = {
        '1.0': '1.0',
        '1.1': '1.1',
        }

    @base.remotable_classmethod
    def get_by_security_group_id(cls, context, secgroup_id):
        db_rules = db.security_group_rule_get_by_security_group(
            context, secgroup_id, columns_to_join=['grantee_group'])
        return base.obj_make_list(context, cls(context),
                                  objects.SecurityGroupRule, db_rules,
                                  expected_attrs=['grantee_group'])

    @classmethod
    def get_by_security_group(cls, context, security_group):
        return cls.get_by_security_group_id(context, security_group.id)
Beispiel #16
0
class BandwidthUsageList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    # Version 1.1: Add use_slave to get_by_uuids
    # Version 1.2: BandwidthUsage <= version 1.2
    VERSION = '1.2'
    fields = {
        'objects': fields.ListOfObjectsField('BandwidthUsage'),
    }
    child_versions = {
        '1.0': '1.0',
        '1.1': '1.1',
        '1.2': '1.2',
    }

    @base.serialize_args
    @base.remotable_classmethod
    def get_by_uuids(cls, context, uuids, start_period=None, use_slave=False):
        db_bw_usages = db.bw_usage_get_by_uuids(context, uuids=uuids,
                                                start_period=start_period,
                                                use_slave=use_slave)
        return base.obj_make_list(context, cls(), BandwidthUsage, db_bw_usages)
Beispiel #17
0
class InstanceFaultList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    #              InstanceFault <= version 1.1
    # Version 1.1: InstanceFault version 1.2
    VERSION = '1.1'

    fields = {
        'objects': fields.ListOfObjectsField('InstanceFault'),
    }
    child_versions = {
        '1.0': '1.1',
        # NOTE(danms): InstanceFault was at 1.1 before we added this
        '1.1': '1.2',
    }

    @base.remotable_classmethod
    def get_by_instance_uuids(cls, context, instance_uuids):
        db_faultdict = db.instance_fault_get_by_instance_uuids(
            context, instance_uuids)
        db_faultlist = itertools.chain(*db_faultdict.values())
        return base.obj_make_list(context, cls(context), objects.InstanceFault,
                                  db_faultlist)
Beispiel #18
0
class MigrationList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    #              Migration <= 1.1
    # Version 1.1: Added use_slave to get_unconfirmed_by_dest_compute
    VERSION = '1.1'

    fields = {
        'objects': fields.ListOfObjectsField('Migration'),
    }
    child_versions = {
        '1.0': '1.1',
        # NOTE(danms): Migration was at 1.1 before we added this
        '1.1': '1.1',
    }

    @base.remotable_classmethod
    def get_unconfirmed_by_dest_compute(cls,
                                        context,
                                        confirm_window,
                                        dest_compute,
                                        use_slave=False):
        db_migrations = db.migration_get_unconfirmed_by_dest_compute(
            context, confirm_window, dest_compute, use_slave=use_slave)
        return base.obj_make_list(context, cls(context), objects.Migration,
                                  db_migrations)

    @base.remotable_classmethod
    def get_in_progress_by_host_and_node(cls, context, host, node):
        db_migrations = db.migration_get_in_progress_by_host_and_node(
            context, host, node)
        return base.obj_make_list(context, cls(context), objects.Migration,
                                  db_migrations)

    @base.remotable_classmethod
    def get_by_filters(cls, context, filters):
        db_migrations = db.migration_get_all_by_filters(context, filters)
        return base.obj_make_list(context, cls(context), objects.Migration,
                                  db_migrations)
Beispiel #19
0
class VirtualInterfaceList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    VERSION = '1.0'
    fields = {
        'objects': fields.ListOfObjectsField('VirtualInterface'),
    }
    child_versions = {
        '1.0': '1.0',
    }

    @base.remotable_classmethod
    def get_all(cls, context):
        db_vifs = db.virtual_interface_get_all(context)
        return base.obj_make_list(context, cls(context),
                                  objects.VirtualInterface, db_vifs)

    @base.remotable_classmethod
    def get_by_instance_uuid(cls, context, instance_uuid, use_slave=False):
        db_vifs = db.virtual_interface_get_by_instance(context,
                                                       instance_uuid,
                                                       use_slave=use_slave)
        return base.obj_make_list(context, cls(context),
                                  objects.VirtualInterface, db_vifs)
Beispiel #20
0
class InstanceGroupList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    #              InstanceGroup <= version 1.3
    # Version 1.1: InstanceGroup <= version 1.4
    # Version 1.2: InstanceGroup <= version 1.5
    # Version 1.3: InstanceGroup <= version 1.6
    # Version 1.4: InstanceGroup <= version 1.7
    # Version 1.5: InstanceGroup <= version 1.8
    # Version 1.6: InstanceGroup <= version 1.9
    VERSION = '1.6'

    fields = {
        'objects': fields.ListOfObjectsField('InstanceGroup'),
    }
    child_versions = {
        '1.0': '1.3',
        # NOTE(danms): InstanceGroup was at 1.3 before we added this
        '1.1': '1.4',
        '1.2': '1.5',
        '1.3': '1.6',
        '1.4': '1.7',
        '1.5': '1.8',
        '1.6': '1.9',
    }

    @base.remotable_classmethod
    def get_by_project_id(cls, context, project_id):
        groups = db.instance_group_get_all_by_project_id(context, project_id)
        return base.obj_make_list(context, cls(context), objects.InstanceGroup,
                                  groups)

    @base.remotable_classmethod
    def get_all(cls, context):
        groups = db.instance_group_get_all(context)
        return base.obj_make_list(context, cls(context), objects.InstanceGroup,
                                  groups)
Beispiel #21
0
class TagList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    VERSION = '1.0'

    fields = {
        'objects': fields.ListOfObjectsField('Tag'),
    }
    child_versions = {
        '1.0': '1.0',
    }

    @base.remotable_classmethod
    def get_by_resource_id(cls, context, resource_id):
        db_tags = db.instance_tag_get_by_instance_uuid(context, resource_id)
        return base.obj_make_list(context, cls(), objects.Tag, db_tags)

    @base.remotable_classmethod
    def create(cls, context, resource_id, tags):
        db_tags = db.instance_tag_set(context, resource_id, tags)
        return base.obj_make_list(context, cls(), objects.Tag, db_tags)

    @base.remotable_classmethod
    def destroy(cls, context, resource_id):
        db.instance_tag_delete_all(context, resource_id)
class InstanceNUMATopology(base.NovaObject, base.NovaObjectDictCompat):
    # Version 1.0: Initial version
    # Version 1.1: Takes into account pagesize
    VERSION = '1.1'

    fields = {
        # NOTE(danms): The 'id' field is no longer used and should be
        # removed in the future when convenient
        'id': obj_fields.IntegerField(),
        'instance_uuid': obj_fields.UUIDField(),
        'cells': obj_fields.ListOfObjectsField('InstanceNUMACell'),
    }

    obj_relationships = {
        'cells': [('1.0', '1.0')],
    }

    @classmethod
    def obj_from_primitive(cls, primitive):
        if 'patron_object.name' in primitive:
            obj_topology = super(InstanceNUMATopology,
                                 cls).obj_from_primitive(primitive)
        else:
            # NOTE(sahid): This compatibility code needs to stay until we can
            # guarantee that there are no cases of the old format stored in
            # the database (or forever, if we can never guarantee that).
            obj_topology = InstanceNUMATopology._from_dict(primitive)
            obj_topology.id = 0
        return obj_topology

    @classmethod
    def obj_from_db_obj(cls, instance_uuid, db_obj):
        primitive = jsonutils.loads(db_obj)
        obj_topology = cls.obj_from_primitive(primitive)

        if 'patron_object.name' not in db_obj:
            obj_topology.instance_uuid = instance_uuid
            # No benefit to store a list of changed fields
            obj_topology.obj_reset_changes()

        return obj_topology

    # TODO(ndipanov) Remove this method on the major version bump to 2.0
    @base.remotable
    def create(self):
        self._save()

    # NOTE(ndipanov): We can't rename create and want to avoid version bump
    # as this needs to be backported to stable so this is not a @remotable
    # That's OK since we only call it from inside Instance.save() which is.
    def _save(self):
        values = {'numa_topology': self._to_json()}
        db.instance_extra_update_by_uuid(self._context, self.instance_uuid,
                                         values)
        self.obj_reset_changes()

    # NOTE(ndipanov): We want to avoid version bump
    # as this needs to be backported to stable so this is not a @remotable
    # That's OK since we only call it from inside Instance.save() which is.
    @classmethod
    def delete_by_instance_uuid(cls, context, instance_uuid):
        values = {'numa_topology': None}
        db.instance_extra_update_by_uuid(context, instance_uuid, values)

    @base.remotable_classmethod
    def get_by_instance_uuid(cls, context, instance_uuid):
        db_extra = db.instance_extra_get_by_instance_uuid(
            context, instance_uuid, columns=['numa_topology'])
        if not db_extra:
            raise exception.NumaTopologyNotFound(instance_uuid=instance_uuid)

        if db_extra['numa_topology'] is None:
            return None

        return cls.obj_from_db_obj(instance_uuid, db_extra['numa_topology'])

    def _to_json(self):
        return jsonutils.dumps(self.obj_to_primitive())

    def __len__(self):
        """Defined so that boolean testing works the same as for lists."""
        return len(self.cells)

    def _to_dict(self):
        # NOTE(sahid): Used as legacy, could be renamed in _legacy_to_dict_
        # in the future to avoid confusing.
        return {'cells': [cell._to_dict() for cell in self.cells]}

    @classmethod
    def _from_dict(cls, data_dict):
        # NOTE(sahid): Used as legacy, could be renamed in _legacy_from_dict_
        # in the future to avoid confusing.
        return cls(cells=[
            InstanceNUMACell._from_dict(cell_dict)
            for cell_dict in data_dict.get('cells', [])
        ])

    @property
    def cpu_pinning_requested(self):
        return all(cell.cpu_pinning_requested for cell in self.cells)
Beispiel #23
0
class ComputeNodeList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    #              ComputeNode <= version 1.2
    # Version 1.1 ComputeNode version 1.3
    # Version 1.2 Add get_by_service()
    # Version 1.3 ComputeNode version 1.4
    # Version 1.4 ComputeNode version 1.5
    # Version 1.5 Add use_slave to get_by_service
    # Version 1.6 ComputeNode version 1.6
    # Version 1.7 ComputeNode version 1.7
    # Version 1.8 ComputeNode version 1.8 + add get_all_by_host()
    # Version 1.9 ComputeNode version 1.9
    # Version 1.10 ComputeNode version 1.10
    # Version 1.11 ComputeNode version 1.11
    VERSION = '1.11'
    fields = {
        'objects': fields.ListOfObjectsField('ComputeNode'),
    }
    child_versions = {
        '1.0': '1.2',
        # NOTE(danms): ComputeNode was at 1.2 before we added this
        '1.1': '1.3',
        '1.2': '1.3',
        '1.3': '1.4',
        '1.4': '1.5',
        '1.5': '1.5',
        '1.6': '1.6',
        '1.7': '1.7',
        '1.8': '1.8',
        '1.9': '1.9',
        '1.10': '1.10',
        '1.11': '1.11',
    }

    @base.remotable_classmethod
    def get_all(cls, context):
        db_computes = db.compute_node_get_all(context)
        return base.obj_make_list(context, cls(context), objects.ComputeNode,
                                  db_computes)

    @base.remotable_classmethod
    def get_by_hypervisor(cls, context, hypervisor_match):
        db_computes = db.compute_node_search_by_hypervisor(
            context, hypervisor_match)
        return base.obj_make_list(context, cls(context), objects.ComputeNode,
                                  db_computes)

    @base.remotable_classmethod
    def _get_by_service(cls, context, service_id, use_slave=False):
        try:
            db_computes = db.compute_nodes_get_by_service_id(
                context, service_id)
        except exception.ServiceNotFound:
            # NOTE(sbauza): Previous behaviour was returning an empty list
            # if the service was created with no computes, we need to keep it.
            db_computes = []
        return base.obj_make_list(context, cls(context), objects.ComputeNode,
                                  db_computes)

    @classmethod
    def get_by_service(cls, context, service, use_slave=False):
        return cls._get_by_service(context, service.id, use_slave=use_slave)

    @base.remotable_classmethod
    def get_all_by_host(cls, context, host, use_slave=False):
        try:
            db_computes = db.compute_node_get_all_by_host(
                context, host, use_slave)
        except exception.ComputeHostNotFound:
            # FIXME(sbauza): Some old computes can still have no host record
            # We need to provide compatibility by using the old service_id
            # record.
            # We assume the compatibility as an extra penalty of one more DB
            # call but that's necessary until all nodes are upgraded.
            try:
                service = objects.Service.get_by_compute_host(
                    context, host, use_slave)
                db_computes = db.compute_nodes_get_by_service_id(
                    context, service.id)
            except exception.ServiceNotFound:
                # We need to provide the same exception upstream
                raise exception.ComputeHostNotFound(host=host)
            # We can avoid an extra call to Service object in _from_db_object
            for db_compute in db_computes:
                db_compute['host'] = service.host
        return base.obj_make_list(context, cls(context), objects.ComputeNode,
                                  db_computes)
Beispiel #24
0
class FixedIPList(obj_base.ObjectListBase, obj_base.NovaObject):
    # Version 1.0: Initial version
    # Version 1.1: Added get_by_network()
    # Version 1.2: FixedIP <= version 1.2
    # Version 1.3: FixedIP <= version 1.3
    # Version 1.4: FixedIP <= version 1.4
    # Version 1.5: FixedIP <= version 1.5, added expected attrs to gets
    # Version 1.6: FixedIP <= version 1.6
    # Version 1.7: FixedIP <= version 1.7
    # Version 1.8: FixedIP <= version 1.8
    # Version 1.8: FixedIP <= version 1.9
    VERSION = '1.9'

    fields = {
        'objects': fields.ListOfObjectsField('FixedIP'),
        }
    child_versions = {
        '1.0': '1.0',
        '1.1': '1.1',
        '1.2': '1.2',
        '1.3': '1.3',
        '1.4': '1.4',
        '1.5': '1.5',
        '1.6': '1.6',
        '1.7': '1.7',
        '1.8': '1.8',
        '1.9': '1.9',
        }

    @obj_base.remotable_classmethod
    def get_all(cls, context):
        db_fixedips = db.fixed_ip_get_all(context)
        return obj_base.obj_make_list(context, cls(context),
                                      objects.FixedIP, db_fixedips)

    @obj_base.remotable_classmethod
    def get_by_instance_uuid(cls, context, instance_uuid):
        expected_attrs = ['network', 'virtual_interface', 'floating_ips']
        db_fixedips = db.fixed_ip_get_by_instance(context, instance_uuid)
        return obj_base.obj_make_list(context, cls(context),
                                      objects.FixedIP, db_fixedips,
                                      expected_attrs=expected_attrs)

    @obj_base.remotable_classmethod
    def get_by_host(cls, context, host):
        db_fixedips = db.fixed_ip_get_by_host(context, host)
        return obj_base.obj_make_list(context, cls(context),
                                      objects.FixedIP, db_fixedips)

    @obj_base.remotable_classmethod
    def get_by_virtual_interface_id(cls, context, vif_id):
        expected_attrs = ['network', 'floating_ips']
        db_fixedips = db.fixed_ips_by_virtual_interface(context, vif_id)
        return obj_base.obj_make_list(context, cls(context),
                                      objects.FixedIP, db_fixedips,
                                      expected_attrs=expected_attrs)

    @obj_base.remotable_classmethod
    def get_by_network(cls, context, network, host=None):
        ipinfo = db.network_get_associated_fixed_ips(context,
                                                     network['id'],
                                                     host=host)
        if not ipinfo:
            return []

        fips = cls(context=context, objects=[])

        for info in ipinfo:
            inst = objects.Instance(context=context,
                                    uuid=info['instance_uuid'],
                                    hostname=info['instance_hostname'],
                                    created_at=info['instance_created'],
                                    updated_at=info['instance_updated'])
            vif = objects.VirtualInterface(context=context,
                                           id=info['vif_id'],
                                           address=info['vif_address'])
            fip = objects.FixedIP(context=context,
                                  address=info['address'],
                                  instance_uuid=info['instance_uuid'],
                                  network_id=info['network_id'],
                                  virtual_interface_id=info['vif_id'],
                                  allocated=info['allocated'],
                                  leased=info['leased'],
                                  default_route=info['default_route'],
                                  instance=inst,
                                  virtual_interface=vif)
            fips.objects.append(fip)
        fips.obj_reset_changes()
        return fips

    @obj_base.remotable_classmethod
    def bulk_create(self, context, fixed_ips):
        ips = []
        for fixedip in fixed_ips:
            ip = obj_base.obj_to_primitive(fixedip)
            if 'id' in ip:
                raise exception.ObjectActionError(action='create',
                                                  reason='already created')
            ips.append(ip)
        db.fixed_ip_bulk_create(context, ips)
Beispiel #25
0
class NUMACell(base.NovaObject, base.NovaObjectDictCompat):
    # Version 1.0: Initial version
    # Version 1.1: Added pinned_cpus and siblings fields
    # Version 1.2: Added mempages field
    VERSION = '1.2'

    fields = {
        'id': fields.IntegerField(read_only=True),
        'cpuset': fields.SetOfIntegersField(),
        'memory': fields.IntegerField(),
        'cpu_usage': fields.IntegerField(default=0),
        'memory_usage': fields.IntegerField(default=0),
        'pinned_cpus': fields.SetOfIntegersField(),
        'siblings': fields.ListOfSetsOfIntegersField(),
        'mempages': fields.ListOfObjectsField('NUMAPagesTopology'),
    }

    obj_relationships = {'mempages': [('1.2', '1.0')]}

    def __eq__(self, other):
        return all_things_equal(self, other)

    def __ne__(self, other):
        return not (self == other)

    @property
    def free_cpus(self):
        return self.cpuset - self.pinned_cpus or set()

    @property
    def free_siblings(self):
        return [sibling_set & self.free_cpus for sibling_set in self.siblings]

    @property
    def avail_cpus(self):
        return len(self.free_cpus)

    @property
    def avail_memory(self):
        return self.memory - self.memory_usage

    def pin_cpus(self, cpus):
        if self.pinned_cpus & cpus:
            raise exception.CPUPinningInvalid(requested=list(cpus),
                                              pinned=list(self.pinned_cpus))
        self.pinned_cpus |= cpus

    def unpin_cpus(self, cpus):
        if (self.pinned_cpus & cpus) != cpus:
            raise exception.CPUPinningInvalid(requested=list(cpus),
                                              pinned=list(self.pinned_cpus))
        self.pinned_cpus -= cpus

    def _to_dict(self):
        return {
            'id': self.id,
            'cpus': hardware.format_cpu_spec(self.cpuset, allow_ranges=False),
            'mem': {
                'total': self.memory,
                'used': self.memory_usage
            },
            'cpu_usage': self.cpu_usage
        }

    @classmethod
    def _from_dict(cls, data_dict):
        cpuset = hardware.parse_cpu_spec(data_dict.get('cpus', ''))
        cpu_usage = data_dict.get('cpu_usage', 0)
        memory = data_dict.get('mem', {}).get('total', 0)
        memory_usage = data_dict.get('mem', {}).get('used', 0)
        cell_id = data_dict.get('id')
        return cls(id=cell_id,
                   cpuset=cpuset,
                   memory=memory,
                   cpu_usage=cpu_usage,
                   memory_usage=memory_usage,
                   mempages=[],
                   pinned_cpus=set([]),
                   siblings=[])

    def can_fit_hugepages(self, pagesize, memory):
        """Returns whether memory can fit into hugepages size

        :param pagesize: a page size in KibB
        :param memory: a memory size asked to fit in KiB

        :returns: whether memory can fit in hugepages
        :raises: MemoryPageSizeNotSupported if page size not supported
        """
        for pages in self.mempages:
            if pages.size_kb == pagesize:
                return (memory <= pages.free_kb
                        and (memory % pages.size_kb) == 0)
        raise exception.MemoryPageSizeNotSupported(pagesize=pagesize)
Beispiel #26
0
class ComputeNode(base.NovaPersistentObject, base.NovaObject,
                  base.NovaObjectDictCompat):
    # Version 1.0: Initial version
    # Version 1.1: Added get_by_service_id()
    # Version 1.2: String attributes updated to support unicode
    # Version 1.3: Added stats field
    # Version 1.4: Added host ip field
    # Version 1.5: Added numa_topology field
    # Version 1.6: Added supported_hv_specs
    # Version 1.7: Added host field
    # Version 1.8: Added get_by_host_and_nodename()
    # Version 1.9: Added pci_device_pools
    # Version 1.10: Added get_first_node_by_host_for_old_compat()
    # Version 1.11: PciDevicePoolList version 1.1
    VERSION = '1.11'

    fields = {
        'id': fields.IntegerField(read_only=True),
        'service_id': fields.IntegerField(),
        'host': fields.StringField(nullable=True),
        'vcpus': fields.IntegerField(),
        'memory_mb': fields.IntegerField(),
        'local_gb': fields.IntegerField(),
        'vcpus_used': fields.IntegerField(),
        'memory_mb_used': fields.IntegerField(),
        'local_gb_used': fields.IntegerField(),
        'hypervisor_type': fields.StringField(),
        'hypervisor_version': fields.IntegerField(),
        'hypervisor_hostname': fields.StringField(nullable=True),
        'free_ram_mb': fields.IntegerField(nullable=True),
        'free_disk_gb': fields.IntegerField(nullable=True),
        'current_workload': fields.IntegerField(nullable=True),
        'running_vms': fields.IntegerField(nullable=True),
        'cpu_info': fields.StringField(nullable=True),
        'disk_available_least': fields.IntegerField(nullable=True),
        'metrics': fields.StringField(nullable=True),
        'stats': fields.DictOfNullableStringsField(nullable=True),
        'host_ip': fields.IPAddressField(nullable=True),
        'numa_topology': fields.StringField(nullable=True),
        # NOTE(pmurray): the supported_hv_specs field maps to the
        # supported_instances field in the database
        'supported_hv_specs': fields.ListOfObjectsField('HVSpec'),
        # NOTE(pmurray): the pci_device_pools field maps to the
        # pci_stats field in the database
        'pci_device_pools': fields.ObjectField('PciDevicePoolList',
                                               nullable=True),
    }

    obj_relationships = {
        'pci_device_pools': [('1.9', '1.0'), ('1.11', '1.1')],
        'supported_hv_specs': [('1.6', '1.0')],
    }

    def obj_make_compatible(self, primitive, target_version):
        super(ComputeNode, self).obj_make_compatible(primitive, target_version)
        target_version = utils.convert_version_to_tuple(target_version)
        if target_version < (1, 7) and 'host' in primitive:
            del primitive['host']
        if target_version < (1, 5) and 'numa_topology' in primitive:
            del primitive['numa_topology']
        if target_version < (1, 4) and 'host_ip' in primitive:
            del primitive['host_ip']
        if target_version < (1, 3) and 'stats' in primitive:
            # pre 1.3 version does not have a stats field
            del primitive['stats']

    @staticmethod
    def _host_from_db_object(compute, db_compute):
        if (('host' not in db_compute or db_compute['host'] is None)
                and 'service_id' in db_compute
                and db_compute['service_id'] is not None):
            # FIXME(sbauza) : Unconverted compute record, provide compatibility
            # This has to stay until we can be sure that any/all compute nodes
            # in the database have been converted to use the host field

            # Service field of ComputeNode could be deprecated in a next patch,
            # so let's use directly the Service object
            try:
                service = objects.Service.get_by_id(compute._context,
                                                    db_compute['service_id'])
            except exception.ServiceNotFound:
                compute['host'] = None
                return
            try:
                compute['host'] = service.host
            except (AttributeError, exception.OrphanedObjectError):
                # Host can be nullable in Service
                compute['host'] = None
        elif 'host' in db_compute and db_compute['host'] is not None:
            # New-style DB having host as a field
            compute['host'] = db_compute['host']
        else:
            # We assume it should not happen but in case, let's set it to None
            compute['host'] = None

    @staticmethod
    def _from_db_object(context, compute, db_compute):
        special_cases = set([
            'stats',
            'supported_hv_specs',
            'host',
            'pci_device_pools',
        ])
        fields = set(compute.fields) - special_cases
        for key in fields:
            compute[key] = db_compute[key]

        stats = db_compute['stats']
        if stats:
            compute['stats'] = jsonutils.loads(stats)

        sup_insts = db_compute.get('supported_instances')
        if sup_insts:
            hv_specs = jsonutils.loads(sup_insts)
            hv_specs = [
                objects.HVSpec.from_list(hv_spec) for hv_spec in hv_specs
            ]
            compute['supported_hv_specs'] = hv_specs

        pci_stats = db_compute.get('pci_stats')
        compute.pci_device_pools = pci_device_pool.from_pci_stats(pci_stats)
        compute._context = context

        # Make sure that we correctly set the host field depending on either
        # host column is present in the table or not
        compute._host_from_db_object(compute, db_compute)

        compute.obj_reset_changes()
        return compute

    @base.remotable_classmethod
    def get_by_id(cls, context, compute_id):
        db_compute = db.compute_node_get(context, compute_id)
        return cls._from_db_object(context, cls(), db_compute)

    @base.remotable_classmethod
    def get_by_service_id(cls, context, service_id):
        db_computes = db.compute_nodes_get_by_service_id(context, service_id)
        # NOTE(sbauza): Old version was returning an item, we need to keep this
        # behaviour for backwards compatibility
        db_compute = db_computes[0]
        return cls._from_db_object(context, cls(), db_compute)

    @base.remotable_classmethod
    def get_by_host_and_nodename(cls, context, host, nodename):
        try:
            db_compute = db.compute_node_get_by_host_and_nodename(
                context, host, nodename)
        except exception.ComputeHostNotFound:
            # FIXME(sbauza): Some old computes can still have no host record
            # We need to provide compatibility by using the old service_id
            # record.
            # We assume the compatibility as an extra penalty of one more DB
            # call but that's necessary until all nodes are upgraded.
            try:
                service = objects.Service.get_by_compute_host(context, host)
                db_computes = db.compute_nodes_get_by_service_id(
                    context, service.id)
            except exception.ServiceNotFound:
                # We need to provide the same exception upstream
                raise exception.ComputeHostNotFound(host=host)
            db_compute = None
            for compute in db_computes:
                if compute['hypervisor_hostname'] == nodename:
                    db_compute = compute
                    # We can avoid an extra call to Service object in
                    # _from_db_object
                    db_compute['host'] = service.host
                    break
            if not db_compute:
                raise exception.ComputeHostNotFound(host=host)
        return cls._from_db_object(context, cls(), db_compute)

    @base.remotable_classmethod
    def get_first_node_by_host_for_old_compat(cls,
                                              context,
                                              host,
                                              use_slave=False):
        computes = ComputeNodeList.get_all_by_host(context, host, use_slave)
        # FIXME(sbauza): Some hypervisors (VMware, Ironic) can return multiple
        # nodes per host, we should return all the nodes and modify the callers
        # instead.
        # Arbitrarily returning the first node.
        return computes[0]

    @staticmethod
    def _convert_stats_to_db_format(updates):
        stats = updates.pop('stats', None)
        if stats is not None:
            updates['stats'] = jsonutils.dumps(stats)

    @staticmethod
    def _convert_host_ip_to_db_format(updates):
        host_ip = updates.pop('host_ip', None)
        if host_ip:
            updates['host_ip'] = str(host_ip)

    @staticmethod
    def _convert_supported_instances_to_db_format(updates):
        hv_specs = updates.pop('supported_hv_specs', None)
        if hv_specs is not None:
            hv_specs = [hv_spec.to_list() for hv_spec in hv_specs]
            updates['supported_instances'] = jsonutils.dumps(hv_specs)

    @staticmethod
    def _convert_pci_stats_to_db_format(updates):
        pools = updates.pop('pci_device_pools', None)
        if pools:
            updates['pci_stats'] = jsonutils.dumps(pools.obj_to_primitive())

    @base.remotable
    def create(self):
        if self.obj_attr_is_set('id'):
            raise exception.ObjectActionError(action='create',
                                              reason='already created')
        updates = self.obj_get_changes()
        self._convert_stats_to_db_format(updates)
        self._convert_host_ip_to_db_format(updates)
        self._convert_supported_instances_to_db_format(updates)
        self._convert_pci_stats_to_db_format(updates)

        db_compute = db.compute_node_create(self._context, updates)
        self._from_db_object(self._context, self, db_compute)

    @base.remotable
    def save(self, prune_stats=False):
        # NOTE(belliott) ignore prune_stats param, no longer relevant

        updates = self.obj_get_changes()
        updates.pop('id', None)
        self._convert_stats_to_db_format(updates)
        self._convert_host_ip_to_db_format(updates)
        self._convert_supported_instances_to_db_format(updates)
        self._convert_pci_stats_to_db_format(updates)

        db_compute = db.compute_node_update(self._context, self.id, updates)
        self._from_db_object(self._context, self, db_compute)

    @base.remotable
    def destroy(self):
        db.compute_node_delete(self._context, self.id)

    @property
    def service(self):
        if not hasattr(self, '_cached_service'):
            self._cached_service = objects.Service.get_by_id(
                self._context, self.service_id)
        return self._cached_service
Beispiel #27
0
class ObjectListBase(object):
    """Mixin class for lists of objects.

    This mixin class can be added as a base class for an object that
    is implementing a list of objects. It adds a single field of 'objects',
    which is the list store, and behaves like a list itself. It supports
    serialization of the list of objects automatically.
    """
    fields = {
        'objects': obj_fields.ListOfObjectsField('NovaObject'),
    }

    # This is a dictionary of my_version:child_version mappings so that
    # we can support backleveling our contents based on the version
    # requested of the list object.
    child_versions = {}

    def __init__(self, *args, **kwargs):
        super(ObjectListBase, self).__init__(*args, **kwargs)
        if 'objects' not in kwargs:
            self.objects = []
            self._changed_fields.discard('objects')

    def __iter__(self):
        """List iterator interface."""
        return iter(self.objects)

    def __len__(self):
        """List length."""
        return len(self.objects)

    def __getitem__(self, index):
        """List index access."""
        if isinstance(index, slice):
            new_obj = self.__class__()
            new_obj.objects = self.objects[index]
            # NOTE(danms): We must be mixed in with a NovaObject!
            new_obj.obj_reset_changes()
            new_obj._context = self._context
            return new_obj
        return self.objects[index]

    def __contains__(self, value):
        """List membership test."""
        return value in self.objects

    def count(self, value):
        """List count of value occurrences."""
        return self.objects.count(value)

    def index(self, value):
        """List index of value."""
        return self.objects.index(value)

    def sort(self, cmp=None, key=None, reverse=False):
        self.objects.sort(cmp=cmp, key=key, reverse=reverse)

    def obj_make_compatible(self, primitive, target_version):
        primitives = primitive['objects']
        child_target_version = self.child_versions.get(target_version, '1.0')
        for index, item in enumerate(self.objects):
            self.objects[index].obj_make_compatible(
                primitives[index]['patron_object.data'], child_target_version)
            primitives[index]['patron_object.version'] = child_target_version

    def obj_what_changed(self):
        changes = set(self._changed_fields)
        for child in self.objects:
            if child.obj_what_changed():
                changes.add('objects')
        return changes
Beispiel #28
0
class BlockDeviceMappingList(base.ObjectListBase, base.NovaObject):
    # Version 1.0: Initial version
    # Version 1.1: BlockDeviceMapping <= version 1.1
    # Version 1.2: Added use_slave to get_by_instance_uuid
    # Version 1.3: BlockDeviceMapping <= version 1.2
    # Version 1.4: BlockDeviceMapping <= version 1.3
    # Version 1.5: BlockDeviceMapping <= version 1.4
    # Version 1.6: BlockDeviceMapping <= version 1.5
    # Version 1.7: BlockDeviceMapping <= version 1.6
    # Version 1.8: BlockDeviceMapping <= version 1.7
    # Version 1.9: BlockDeviceMapping <= version 1.8
    VERSION = '1.9'

    fields = {
        'objects': fields.ListOfObjectsField('BlockDeviceMapping'),
    }
    child_versions = {
        '1.0': '1.0',
        '1.1': '1.1',
        '1.2': '1.1',
        '1.3': '1.2',
        '1.4': '1.3',
        '1.5': '1.4',
        '1.6': '1.5',
        '1.7': '1.6',
        '1.8': '1.7',
        '1.9': '1.8',
    }

    @base.remotable_classmethod
    def get_by_instance_uuid(cls, context, instance_uuid, use_slave=False):
        db_bdms = db.block_device_mapping_get_all_by_instance(
            context, instance_uuid, use_slave=use_slave)
        return base.obj_make_list(context, cls(), objects.BlockDeviceMapping,
                                  db_bdms or [])

    def root_bdm(self):
        try:
            return (bdm_obj for bdm_obj in self if bdm_obj.is_root).next()
        except StopIteration:
            return

    def root_metadata(self, context, image_api, volume_api):
        root_bdm = self.root_bdm()
        if not root_bdm:
            return {}

        if root_bdm.is_volume:
            try:
                volume = volume_api.get(context, root_bdm.volume_id)
                return volume.get('volume_image_metadata', {})
            except Exception:
                raise exception.InvalidBDMVolume(id=root_bdm.id)
        elif root_bdm.is_image:
            try:
                image_meta = image_api.show(context, root_bdm.image_id)
                return image_meta.get('properties', {})
            except Exception:
                raise exception.InvalidBDMImage(id=root_bdm.id)
        else:
            return {}