class Usage(base.NovaObject): # Version 1.0: Initial version # Version 1.1: Changed resource_class to allow custom strings VERSION = '1.1' fields = { 'resource_class': fields.ResourceClassField(read_only=True), 'usage': fields.NonNegativeIntegerField(), } def obj_make_compatible(self, primitive, target_version): super(Usage, self).obj_make_compatible(primitive, target_version) target_version = versionutils.convert_version_to_tuple(target_version) if target_version < (1, 1) and 'resource_class' in primitive: rc = primitive['resource_class'] rc_cache.raise_if_custom_resource_class_pre_v1_1(rc) @staticmethod def _from_db_object(context, target, source): for field in target.fields: if field not in ('resource_class'): setattr(target, field, source[field]) if 'resource_class' not in target: rc_str = _RC_CACHE.string_from_id(source['resource_class_id']) target.resource_class = rc_str target._context = context target.obj_reset_changes() return target
class Resource(base.NovaObject): # Version 1.0: Initial version VERSION = "1.0" fields = { # UUID of resource provider 'provider_uuid': fields.UUIDField(), # resource class of the Resource 'resource_class': fields.ResourceClassField(), # identifier is used to identify resource, it is up to virt drivers # for mdev, it will be a UUID, for vpmem, it's backend namespace name 'identifier': fields.StringField(), # metadata is used to contain virt driver specific resource info 'metadata': fields.ObjectField('ResourceMetadata', subclasses=True), } def __eq__(self, other): return base.all_things_equal(self, other) def __ne__(self, other): return not (self == other) def __hash__(self): metadata = self.metadata if 'metadata' in self else None return hash((self.provider_uuid, self.resource_class, self.identifier, metadata))
def setUp(self): super(TestResourceClass, self).setUp() self.field = fields.ResourceClassField() self.coerce_good_values = [ ('VCPU', 'VCPU'), ('MEMORY_MB', 'MEMORY_MB'), ('DISK_GB', 'DISK_GB'), ('PCI_DEVICE', 'PCI_DEVICE'), ('SRIOV_NET_VF', 'SRIOV_NET_VF'), ('NUMA_SOCKET', 'NUMA_SOCKET'), ('NUMA_CORE', 'NUMA_CORE'), ('NUMA_THREAD', 'NUMA_THREAD'), ('NUMA_MEMORY_MB', 'NUMA_MEMORY_MB'), ('IPV4_ADDRESS', 'IPV4_ADDRESS'), ] self.expected_indexes = [ ('VCPU', 0), ('MEMORY_MB', 1), ('DISK_GB', 2), ('PCI_DEVICE', 3), ('SRIOV_NET_VF', 4), ('NUMA_SOCKET', 5), ('NUMA_CORE', 6), ('NUMA_THREAD', 7), ('NUMA_MEMORY_MB', 8), ('IPV4_ADDRESS', 9), ] self.coerce_bad_values = ['acme'] self.to_primitive_values = self.coerce_good_values[0:1] self.from_primitive_values = self.coerce_good_values[0:1]
class Inventory(_HasAResourceProvider): # Version 1.0: Initial version # Version 1.1: Changed resource_class to allow custom strings VERSION = '1.1' fields = { 'id': fields.IntegerField(read_only=True), 'resource_provider': fields.ObjectField('ResourceProvider'), 'resource_class': fields.ResourceClassField(read_only=True), 'total': fields.NonNegativeIntegerField(), 'reserved': fields.NonNegativeIntegerField(default=0), 'min_unit': fields.NonNegativeIntegerField(default=1), 'max_unit': fields.NonNegativeIntegerField(default=1), 'step_size': fields.NonNegativeIntegerField(default=1), 'allocation_ratio': fields.NonNegativeFloatField(default=1.0), } def obj_make_compatible(self, primitive, target_version): super(Inventory, self).obj_make_compatible(primitive, target_version) target_version = versionutils.convert_version_to_tuple(target_version) if target_version < (1, 1) and 'resource_class' in primitive: rc = primitive['resource_class'] rc_cache.raise_if_custom_resource_class_pre_v1_1(rc) @property def capacity(self): """Inventory capacity, adjusted by allocation_ratio.""" return int((self.total - self.reserved) * self.allocation_ratio) @base.remotable def create(self): if 'id' in self: raise exception.ObjectActionError(action='create', reason='already created') _ensure_rc_cache(self._context) updates = self._make_db(self.obj_get_changes()) db_inventory = self._create_in_db(self._context, updates) self._from_db_object(self._context, self, db_inventory) @base.remotable def save(self): if 'id' not in self: raise exception.ObjectActionError(action='save', reason='not created') _ensure_rc_cache(self._context) updates = self.obj_get_changes() updates.pop('id', None) self._update_in_db(self._context, self.id, updates) @staticmethod def _create_in_db(context, updates): return _create_inventory_in_db(context, updates) @staticmethod def _update_in_db(context, id_, updates): return _update_inventory_in_db(context, id_, updates)
class Allocation(_HasAResourceProvider): # Version 1.0: Initial version # Version 1.1: Changed resource_class to allow custom strings VERSION = '1.1' fields = { 'id': fields.IntegerField(), 'resource_provider': fields.ObjectField('ResourceProvider'), 'consumer_id': fields.UUIDField(), 'resource_class': fields.ResourceClassField(), 'used': fields.IntegerField(), } def obj_make_compatible(self, primitive, target_version): super(Allocation, self).obj_make_compatible(primitive, target_version) target_version = versionutils.convert_version_to_tuple(target_version) if target_version < (1, 1) and 'resource_class' in primitive: rc = primitive['resource_class'] rc_cache.raise_if_custom_resource_class_pre_v1_1(rc) @staticmethod @db_api.api_context_manager.writer def _create_in_db(context, updates): db_allocation = models.Allocation() db_allocation.update(updates) context.session.add(db_allocation) # We may be in a nested context manager so must flush so the # caller receives an id. context.session.flush() return db_allocation @staticmethod @db_api.api_context_manager.writer def _destroy(context, id): result = context.session.query(models.Allocation).filter_by( id=id).delete() if not result: raise exception.NotFound() @base.remotable def create(self): if 'id' in self: raise exception.ObjectActionError(action='create', reason='already created') _ensure_rc_cache(self._context) updates = self._make_db(self.obj_get_changes()) db_allocation = self._create_in_db(self._context, updates) self._from_db_object(self._context, self, db_allocation) @base.remotable def destroy(self): self._destroy(self._context, self.id)
class Inventory(_HasAResourceProvider): # Version 1.0: Initial version VERSION = '1.0' fields = { 'id': fields.IntegerField(read_only=True), 'resource_provider': fields.ObjectField('ResourceProvider'), 'resource_class': fields.ResourceClassField(read_only=True), 'total': fields.IntegerField(), 'reserved': fields.IntegerField(), 'min_unit': fields.IntegerField(), 'max_unit': fields.IntegerField(), 'step_size': fields.IntegerField(), 'allocation_ratio': fields.FloatField(), } @base.remotable def create(self): if 'id' in self: raise exception.ObjectActionError(action='create', reason='already created') updates = self._make_db(self.obj_get_changes()) db_inventory = self._create_in_db(self._context, updates) self._from_db_object(self._context, self, db_inventory) @base.remotable def save(self): if 'id' not in self: raise exception.ObjectActionError(action='save', reason='not created') updates = self.obj_get_changes() updates.pop('id', None) self._update_in_db(self._context, self.id, updates) @staticmethod @db_api.main_context_manager.writer def _create_in_db(context, updates): db_inventory = models.Inventory() db_inventory.update(updates) context.session.add(db_inventory) return db_inventory @staticmethod @db_api.main_context_manager.writer def _update_in_db(context, id_, updates): result = context.session.query( models.Inventory).filter_by(id=id_).update(updates) if not result: raise exception.NotFound()
class Inventory(_HasAResourceProvider): # Version 1.0: Initial version VERSION = '1.0' fields = { 'id': fields.IntegerField(read_only=True), 'resource_provider': fields.ObjectField('ResourceProvider'), 'resource_class': fields.ResourceClassField(read_only=True), 'total': fields.NonNegativeIntegerField(), 'reserved': fields.NonNegativeIntegerField(default=0), 'min_unit': fields.NonNegativeIntegerField(default=1), 'max_unit': fields.NonNegativeIntegerField(default=1), 'step_size': fields.NonNegativeIntegerField(default=1), 'allocation_ratio': fields.NonNegativeFloatField(default=1.0), } @property def capacity(self): """Inventory capacity, adjusted by allocation_ratio.""" return int((self.total - self.reserved) * self.allocation_ratio) @base.remotable def create(self): if 'id' in self: raise exception.ObjectActionError(action='create', reason='already created') updates = self._make_db(self.obj_get_changes()) db_inventory = self._create_in_db(self._context, updates) self._from_db_object(self._context, self, db_inventory) @base.remotable def save(self): if 'id' not in self: raise exception.ObjectActionError(action='save', reason='not created') updates = self.obj_get_changes() updates.pop('id', None) self._update_in_db(self._context, self.id, updates) @staticmethod def _create_in_db(context, updates): return _create_inventory_in_db(context, updates) @staticmethod def _update_in_db(context, id_, updates): return _update_inventory_in_db(context, id_, updates)
class ResourceClass(base.NovaObject): # Version 1.0: Initial version VERSION = '1.0' fields = { 'id': fields.IntegerField(read_only=True), 'name': fields.ResourceClassField(read_only=True), } @staticmethod def _from_db_object(context, target, source): for field in target.fields: setattr(target, field, source[field]) target._context = context target.obj_reset_changes() return target
def setUp(self): super(TestResourceClass, self).setUp() self.field = fields.ResourceClassField() self.coerce_good_values = [ ('VCPU', 'VCPU'), ('MEMORY_MB', 'MEMORY_MB'), ('DISK_GB', 'DISK_GB'), ('PCI_DEVICE', 'PCI_DEVICE'), ('SRIOV_NET_VF', 'SRIOV_NET_VF'), ('NUMA_SOCKET', 'NUMA_SOCKET'), ('NUMA_CORE', 'NUMA_CORE'), ('NUMA_THREAD', 'NUMA_THREAD'), ('NUMA_MEMORY_MB', 'NUMA_MEMORY_MB'), ('IPV4_ADDRESS', 'IPV4_ADDRESS'), ] self.coerce_bad_values = [object(), dict()] self.to_primitive_values = self.coerce_good_values[0:1] self.from_primitive_values = self.coerce_good_values[0:1]
class Allocation(_HasAResourceProvider): # Version 1.0: Initial version VERSION = '1.0' fields = { 'id': fields.IntegerField(), 'resource_provider': fields.ObjectField('ResourceProvider'), 'consumer_id': fields.UUIDField(), 'resource_class': fields.ResourceClassField(), 'used': fields.IntegerField(), } @staticmethod @db_api.api_context_manager.writer def _create_in_db(context, updates): db_allocation = models.Allocation() db_allocation.update(updates) context.session.add(db_allocation) # We may be in a nested context manager so must flush so the # caller receives an id. context.session.flush() return db_allocation @staticmethod @db_api.api_context_manager.writer def _destroy(context, id): result = context.session.query( models.Allocation).filter_by(id=id).delete() if not result: raise exception.NotFound() @base.remotable def create(self): if 'id' in self: raise exception.ObjectActionError(action='create', reason='already created') updates = self._make_db(self.obj_get_changes()) db_allocation = self._create_in_db(self._context, updates) self._from_db_object(self._context, self, db_allocation) @base.remotable def destroy(self): self._destroy(self._context, self.id)
class Usage(base.NovaObject): # Version 1.0: Initial version VERSION = '1.0' fields = { 'resource_class': fields.ResourceClassField(read_only=True), 'usage': fields.NonNegativeIntegerField(), } @staticmethod def _from_db_object(context, target, source): for field in target.fields: if field not in ('resource_class'): setattr(target, field, source[field]) if 'resource_class' not in target: target.resource_class = ( target.fields['resource_class'].from_index( source['resource_class_id'])) target._context = context target.obj_reset_changes() return target