def _test_init_instance_reverts_crashed_migrations(self, old_vm_state=None): power_on = True if (not old_vm_state or old_vm_state == vm_states.ACTIVE) else False sys_meta = {"old_vm_state": old_vm_state} instance = { "uuid": "foo", "vm_state": vm_states.ERROR, "task_state": task_states.RESIZE_MIGRATING, "power_state": power_state.SHUTDOWN, "system_metadata": sys_meta, } fixed = dict(instance, task_state=None) self.mox.StubOutWithMock(compute_utils, "get_nw_info_for_instance") self.mox.StubOutWithMock(utils, "instance_sys_meta") self.mox.StubOutWithMock(self.compute.driver, "plug_vifs") self.mox.StubOutWithMock(self.compute.driver, "finish_revert_migration") self.mox.StubOutWithMock(self.compute, "_get_instance_volume_block_device_info") self.mox.StubOutWithMock(self.compute.driver, "get_info") self.mox.StubOutWithMock(self.compute, "_instance_update") compute_utils.get_nw_info_for_instance(instance).AndReturn(network_model.NetworkInfo()) self.compute.driver.plug_vifs(instance, []) utils.instance_sys_meta(instance).AndReturn(sys_meta) self.compute._get_instance_volume_block_device_info(self.context, instance).AndReturn([]) self.compute.driver.finish_revert_migration(instance, [], [], power_on) self.compute._instance_update(self.context, instance["uuid"], task_state=None).AndReturn(fixed) self.compute.driver.get_info(fixed).AndReturn({"state": power_state.SHUTDOWN}) self.mox.ReplayAll() self.compute._init_instance(self.context, instance)
def _from_db_object(context, instance, db_inst, expected_attrs=None): """Method to help with migration to objects. Converts a database entity to a formal object. """ instance._context = context if expected_attrs is None: expected_attrs = [] # Most of the field names match right now, so be quick for field in instance.fields: if field in INSTANCE_OPTIONAL_ATTRS: continue elif field == 'deleted': instance.deleted = db_inst['deleted'] == db_inst['id'] elif field == 'cleaned': instance.cleaned = db_inst['cleaned'] == 1 else: instance[field] = db_inst[field] if 'metadata' in expected_attrs: instance['metadata'] = utils.instance_meta(db_inst) if 'system_metadata' in expected_attrs: instance['system_metadata'] = utils.instance_sys_meta(db_inst) if 'fault' in expected_attrs: instance['fault'] = ( objects.InstanceFault.get_latest_for_instance( context, instance.uuid)) if 'numa_topology' in expected_attrs: instance._load_numa_topology() if 'pci_requests' in expected_attrs: instance._load_pci_requests() if 'info_cache' in expected_attrs: if db_inst['info_cache'] is None: instance.info_cache = None elif not instance.obj_attr_is_set('info_cache'): # TODO(danms): If this ever happens on a backlevel instance # passed to us by a backlevel service, things will break instance.info_cache = objects.InstanceInfoCache(context) if instance.info_cache is not None: instance.info_cache._from_db_object(context, instance.info_cache, db_inst['info_cache']) # TODO(danms): If we are updating these on a backlevel instance, # we'll end up sending back new versions of these objects (see # above note for new info_caches if 'pci_devices' in expected_attrs: pci_devices = base.obj_make_list( context, objects.PciDeviceList(context), objects.PciDevice, db_inst['pci_devices']) instance['pci_devices'] = pci_devices if 'security_groups' in expected_attrs: sec_groups = base.obj_make_list( context, objects.SecurityGroupList(context), objects.SecurityGroup, db_inst['security_groups']) instance['security_groups'] = sec_groups instance.obj_reset_changes() return instance
def extract_password(instance): result = '' sys_meta = utils.instance_sys_meta(instance) for key in sorted(sys_meta.keys()): if key.startswith('password_'): result += sys_meta[key] return result or None
def get_image_metadata(context, image_api, image_id_or_uri, instance): image_system_meta = {} # In case of boot from volume, image_id_or_uri may be None or '' if image_id_or_uri is not None and image_id_or_uri != '': # If the base image is still available, get its metadata try: image = image_api.get(context, image_id_or_uri) except (exception.ImageNotAuthorized, exception.ImageNotFound, exception.Invalid) as e: LOG.warning(_LW("Can't access image %(image_id)s: %(error)s"), {"image_id": image_id_or_uri, "error": e}, instance=instance) else: flavor = instance.get_flavor() image_system_meta = utils.get_system_metadata_from_image(image, flavor) # Get the system metadata from the instance system_meta = utils.instance_sys_meta(instance) # Merge the metadata from the instance with the image's, if any system_meta.update(image_system_meta) # Convert the system metadata to image metadata return utils.get_image_from_system_metadata(system_meta)
def from_instance(cls, instance): sysmeta = utils.instance_sys_meta(instance) properties = {} for key in [p for p in sysmeta.keys() if p.startswith('image_')]: image_key = key.split('_', 1)[1] properties[image_key] = sysmeta[key] return cls.from_image_properties(properties)
def _create_instances_here(self, ctxt, instance_uuids, instance_properties, instance_type, image, security_groups, block_device_mapping): instance_values = copy.copy(instance_properties) # The parent may pass these metadata values as lists, and the # create call expects it to be a dict. instance_values['metadata'] = utils.instance_meta(instance_values) sys_metadata = utils.instance_sys_meta(instance_values) # Make sure the flavor info is set. It may not have been passed # down. sys_metadata = flavors.save_flavor_info(sys_metadata, instance_type) instance_values['system_metadata'] = sys_metadata instance_values.pop('name') if 'security_groups' in instance_values: instance_values = security_group.make_secgroup_list( instance_values['security_groups']) num_instances = len(instance_uuids) for i, instance_uuid in enumerate(instance_uuids): instance = instance_obj.Instance() instance.update(instance_values) instance.uuid = instance_uuid instance = self.compute_api.create_db_entry_for_new_instance( ctxt, instance_type, image, instance, security_groups, block_device_mapping, num_instances, i) self.msg_runner.instance_update_at_top(ctxt, instance)
def test_create_instances_here(self): # Just grab the first instance type inst_type = objects.Flavor.get_by_id(self.ctxt, 1) image = {'properties': {}} instance_uuids = self.instance_uuids instance_props = { 'id': 'removed', 'security_groups': 'removed', 'info_cache': 'removed', 'name': 'instance-00000001', 'hostname': 'meow', 'display_name': 'moo', 'image_ref': uuidsentinel.fake_image_ref, 'user_id': self.ctxt.user_id, # Test these as lists 'metadata': { 'moo': 'cow' }, 'system_metadata': { 'meow': 'cat' }, 'flavor': inst_type, 'project_id': self.ctxt.project_id } call_info = {'uuids': []} block_device_mapping = objects.BlockDeviceMappingList(objects=[ objects.BlockDeviceMapping( context=self.ctxt, **fake_block_device.FakeDbBlockDeviceDict( block_device.create_image_bdm(uuidsentinel.fake_image_ref), anon=True)) ]) def _fake_instance_update_at_top(self, _ctxt, instance): call_info['uuids'].append(instance['uuid']) self.stub_out( 'nova.cells.messaging.MessageRunner.' 'instance_update_at_top', _fake_instance_update_at_top) self.scheduler._create_instances_here(self.ctxt, instance_uuids, instance_props, inst_type, image, ['default'], block_device_mapping) self.assertEqual(instance_uuids, call_info['uuids']) for count, instance_uuid in enumerate(instance_uuids): bdms = db.block_device_mapping_get_all_by_instance( self.ctxt, instance_uuid) self.assertIsNotNone(bdms) instance = db.instance_get_by_uuid(self.ctxt, instance_uuid) meta = utils.instance_meta(instance) self.assertEqual('cow', meta['moo']) sys_meta = utils.instance_sys_meta(instance) self.assertEqual('cat', sys_meta['meow']) self.assertEqual('meow', instance['hostname']) self.assertEqual('moo-%d' % (count + 1), instance['display_name']) self.assertEqual(uuidsentinel.fake_image_ref, instance['image_ref'])
def _create_instances_here(self, ctxt, instance_uuids, instance_properties, instance_type, image, security_groups, block_device_mapping): instance_values = copy.copy(instance_properties) # The parent may pass these metadata values as lists, and the # create call expects it to be a dict. instance_values['metadata'] = utils.instance_meta(instance_values) sys_metadata = utils.instance_sys_meta(instance_values) # Make sure the flavor info is set. It may not have been passed # down. sys_metadata = flavors.save_flavor_info(sys_metadata, instance_type) instance_values['system_metadata'] = sys_metadata # Pop out things that will get set properly when re-creating the # instance record. instance_values.pop('id') instance_values.pop('name') instance_values.pop('info_cache') instance_values.pop('security_groups') num_instances = len(instance_uuids) for i, instance_uuid in enumerate(instance_uuids): instance = instance_obj.Instance() instance.update(instance_values) instance.uuid = instance_uuid instance = self.compute_api.create_db_entry_for_new_instance( ctxt, instance_type, image, instance, security_groups, block_device_mapping, num_instances, i) instance = obj_base.obj_to_primitive(instance) self.msg_runner.instance_update_at_top(ctxt, instance)
def get_image_metadata(context, image_api, image_id_or_uri, instance): image_system_meta = {} # In case of boot from volume, image_id_or_uri may be None or '' if image_id_or_uri is not None and image_id_or_uri != '': # If the base image is still available, get its metadata try: image = image_api.get(context, image_id_or_uri) except (exception.ImageNotAuthorized, exception.ImageNotFound, exception.Invalid) as e: LOG.warning(_LW("Can't access image %(image_id)s: %(error)s"), { "image_id": image_id_or_uri, "error": e }, instance=instance) else: flavor = instance.get_flavor() image_system_meta = utils.get_system_metadata_from_image( image, flavor) # Get the system metadata from the instance system_meta = utils.instance_sys_meta(instance) # Merge the metadata from the instance with the image's, if any system_meta.update(image_system_meta) # Convert the system metadata to image metadata return utils.get_image_from_system_metadata(system_meta)
def _get_memory_limit_bytes(self, instance): if isinstance(instance, objects.Instance): return instance.get_flavor().memory_mb * units.Mi else: system_meta = utils.instance_sys_meta(instance) return int(system_meta.get( 'instance_type_memory_mb', 0)) * units.Mi
def extract_flavor(instance, prefix=''): """Create a Flavor object from instance's system_metadata information. """ flavor = objects.Flavor() sys_meta = utils.instance_sys_meta(instance) if not sys_meta: return None for key in system_metadata_flavor_props.keys(): type_key = '%sinstance_type_%s' % (prefix, key) setattr(flavor, key, sys_meta[type_key]) # NOTE(danms): We do NOT save all of extra_specs, but only the # NUMA-related ones that we need to avoid an uglier alternative. This # should be replaced by a general split-out of flavor information from # system_metadata very soon. extra_specs = [(k, v) for k, v in sys_meta.items() if k.startswith('%sinstance_type_extra_' % prefix)] if extra_specs: flavor.extra_specs = {} for key, value in extra_specs: extra_key = key[len('%sinstance_type_extra_' % prefix):] flavor.extra_specs[extra_key] = value return flavor
def _create_instances_here(self, ctxt, instance_uuids, instance_properties, instance_type, image, security_groups, block_device_mapping): instance_values = copy.copy(instance_properties) # The parent may pass these metadata values as lists, and the # create call expects it to be a dict. instance_values['metadata'] = utils.instance_meta(instance_values) sys_metadata = utils.instance_sys_meta(instance_values) # Make sure the flavor info is set. It may not have been passed # down. sys_metadata = flavors.save_flavor_info(sys_metadata, instance_type) instance_values['system_metadata'] = sys_metadata # Pop out things that will get set properly when re-creating the # instance record. instance_values.pop('id') instance_values.pop('name') instance_values.pop('info_cache') instance_values.pop('security_groups') instances = [] num_instances = len(instance_uuids) for i, instance_uuid in enumerate(instance_uuids): instance = objects.Instance() instance.update(instance_values) instance.uuid = instance_uuid instance = self.compute_api.create_db_entry_for_new_instance( ctxt, instance_type, image, instance, security_groups, block_device_mapping, num_instances, i) instances.append(instance) instance_p = obj_base.obj_to_primitive(instance) self.msg_runner.instance_update_at_top(ctxt, instance_p) return instances
def _get_memory_limit_bytes(self, instance): if isinstance(instance, objects.Instance): return instance.get_flavor().memory_mb * units.Mi else: system_meta = utils.instance_sys_meta(instance) return int(system_meta.get('instance_type_memory_mb', 0)) * units.Mi
def _create_instances_here(self, ctxt, instance_uuids, instance_properties, instance_type, image, security_groups, block_device_mapping): instance_values = copy.copy(instance_properties) # The parent may pass these metadata values as lists, and the # create call expects it to be a dict. instance_values['metadata'] = utils.instance_meta(instance_values) sys_metadata = utils.instance_sys_meta(instance_values) # Make sure the flavor info is set. It may not have been passed # down. sys_metadata = flavors.save_flavor_info(sys_metadata, instance_type) instance_values['system_metadata'] = sys_metadata instance_values.pop('name') num_instances = len(instance_uuids) for i, instance_uuid in enumerate(instance_uuids): instance_values['uuid'] = instance_uuid instance = self.compute_api.create_db_entry_for_new_instance( ctxt, instance_type, image, instance_values, security_groups, block_device_mapping, num_instances, i) self.msg_runner.instance_update_at_top(ctxt, instance)
def _save_instance_password_if_sshkey_present(self, new_pass): sshkey = self.instance.get("key_data") if sshkey and sshkey.startswith("ssh-rsa"): ctxt = context.get_admin_context() enc = crypto.ssh_encrypt_text(sshkey, new_pass) sys_meta = utils.instance_sys_meta(self.instance) sys_meta.update(password.convert_password(ctxt, base64.b64encode(enc))) self.virtapi.instance_update(ctxt, self.instance["uuid"], {"system_metadata": sys_meta})
def _save_instance_password_if_sshkey_present(self, new_pass): sshkey = self.instance.get('key_data') if sshkey: ctxt = context.get_admin_context() enc = crypto.ssh_encrypt_text(sshkey, new_pass) sys_meta = utils.instance_sys_meta(self.instance) sys_meta.update(password.convert_password(ctxt, base64.b64encode(enc))) self.virtapi.instance_update(ctxt, self.instance['uuid'], {'system_metadata': sys_meta})
def extract_flavor(instance, prefix=''): """Create an InstanceType-like object from instance's system_metadata information.""" instance_type = {} sys_meta = utils.instance_sys_meta(instance) for key, type_fn in system_metadata_flavor_props.items(): type_key = '%sinstance_type_%s' % (prefix, key) instance_type[key] = type_fn(sys_meta[type_key]) return instance_type
def extract_instance_type(instance, prefix=''): """Create an InstanceType-like object from instance's system_metadata information.""" instance_type = {} sys_meta = utils.instance_sys_meta(instance) for key, type_fn in system_metadata_instance_type_props.items(): type_key = '%sinstance_type_%s' % (prefix, key) instance_type[key] = type_fn(sys_meta[type_key]) return instance_type
def _save_instance_password_if_sshkey_present(self, new_pass): sshkey = self.instance.get('key_data') if sshkey and sshkey.startswith("ssh-rsa"): ctxt = context.get_admin_context() enc = crypto.ssh_encrypt_text(sshkey, new_pass) sys_meta = utils.instance_sys_meta(self.instance) sys_meta.update( password.convert_password(ctxt, base64.b64encode(enc))) self.virtapi.instance_update(ctxt, self.instance['uuid'], {'system_metadata': sys_meta})
def test_create_instances_here(self): # Just grab the first instance type inst_type = objects.Flavor.get_by_id(self.ctxt, 1) image = {'properties': {}} instance_uuids = self.instance_uuids instance_props = {'id': 'removed', 'security_groups': 'removed', 'info_cache': 'removed', 'name': 'instance-00000001', 'hostname': 'meow', 'display_name': 'moo', 'image_ref': uuidsentinel.fake_image_ref, 'user_id': self.ctxt.user_id, # Test these as lists 'metadata': {'moo': 'cow'}, 'system_metadata': {'meow': 'cat'}, 'flavor': inst_type, 'project_id': self.ctxt.project_id} call_info = {'uuids': []} block_device_mapping = objects.BlockDeviceMappingList( objects=[ objects.BlockDeviceMapping(context=self.ctxt, **fake_block_device.FakeDbBlockDeviceDict( block_device.create_image_bdm( uuidsentinel.fake_image_ref), anon=True)) ]) def _fake_instance_update_at_top(self, _ctxt, instance): call_info['uuids'].append(instance['uuid']) self.stub_out('nova.cells.messaging.MessageRunner.' 'instance_update_at_top', _fake_instance_update_at_top) self.scheduler._create_instances_here(self.ctxt, instance_uuids, instance_props, inst_type, image, ['default'], block_device_mapping) self.assertEqual(instance_uuids, call_info['uuids']) for count, instance_uuid in enumerate(instance_uuids): bdms = db.block_device_mapping_get_all_by_instance(self.ctxt, instance_uuid) self.assertIsNotNone(bdms) instance = db.instance_get_by_uuid(self.ctxt, instance_uuid) meta = utils.instance_meta(instance) self.assertEqual('cow', meta['moo']) sys_meta = utils.instance_sys_meta(instance) self.assertEqual('cat', sys_meta['meow']) self.assertEqual('meow', instance['hostname']) self.assertEqual('moo-%d' % (count + 1), instance['display_name']) self.assertEqual(uuidsentinel.fake_image_ref, instance['image_ref'])
def test_create_instances_here(self): # Just grab the first instance type inst_type = flavors.get_flavor(1) image = {'properties': {}} instance_uuids = self.instance_uuids instance_props = { 'id': 'removed', 'security_groups': 'removed', 'info_cache': 'removed', 'name': 'instance-00000001', 'hostname': 'meow', 'display_name': 'moo', 'image_ref': 'fake_image_ref', 'user_id': self.ctxt.user_id, # Test these as lists 'metadata': { 'moo': 'cow' }, 'system_metadata': { 'meow': 'cat' }, 'flavor': inst_type, 'project_id': self.ctxt.project_id } call_info = {'uuids': []} block_device_mapping = [ objects.BlockDeviceMapping( context=self.ctxt, **fake_block_device.FakeDbBlockDeviceDict( block_device.create_image_bdm('fake_image_ref'), anon=True)) ] def _fake_instance_update_at_top(_ctxt, instance): call_info['uuids'].append(instance['uuid']) self.stubs.Set(self.msg_runner, 'instance_update_at_top', _fake_instance_update_at_top) self.scheduler._create_instances_here(self.ctxt, instance_uuids, instance_props, inst_type, image, ['default'], block_device_mapping) self.assertEqual(instance_uuids, call_info['uuids']) for count, instance_uuid in enumerate(instance_uuids): instance = db.instance_get_by_uuid(self.ctxt, instance_uuid) meta = utils.instance_meta(instance) self.assertEqual('cow', meta['moo']) sys_meta = utils.instance_sys_meta(instance) self.assertEqual('cat', sys_meta['meow']) self.assertEqual('meow', instance['hostname']) self.assertEqual('moo-%d' % (count + 1), instance['display_name']) self.assertEqual('fake_image_ref', instance['image_ref'])
def should_use_agent(instance): sys_meta = utils.instance_sys_meta(instance) if USE_AGENT_SM_KEY not in sys_meta: return CONF.xenserver.use_agent_default else: use_agent_raw = sys_meta[USE_AGENT_SM_KEY] try: return strutils.bool_from_string(use_agent_raw, strict=True) except ValueError: LOG.warn(_("Invalid 'agent_present' value. " "Falling back to the default."), instance=instance) return CONF.xenserver.use_agent_default
def test_create_instances_here(self): # Just grab the first instance type inst_type = objects.Flavor.get_by_id(self.ctxt, 1) image = {"properties": {}} instance_uuids = self.instance_uuids instance_props = { "id": "removed", "security_groups": "removed", "info_cache": "removed", "name": "instance-00000001", "hostname": "meow", "display_name": "moo", "image_ref": uuidsentinel.fake_image_ref, "user_id": self.ctxt.user_id, # Test these as lists "metadata": {"moo": "cow"}, "system_metadata": {"meow": "cat"}, "flavor": inst_type, "project_id": self.ctxt.project_id, } call_info = {"uuids": []} block_device_mapping = objects.BlockDeviceMappingList( objects=[ objects.BlockDeviceMapping( context=self.ctxt, **fake_block_device.FakeDbBlockDeviceDict( block_device.create_image_bdm(uuidsentinel.fake_image_ref), anon=True ) ) ] ) def _fake_instance_update_at_top(_ctxt, instance): call_info["uuids"].append(instance["uuid"]) self.stubs.Set(self.msg_runner, "instance_update_at_top", _fake_instance_update_at_top) self.scheduler._create_instances_here( self.ctxt, instance_uuids, instance_props, inst_type, image, ["default"], block_device_mapping ) self.assertEqual(instance_uuids, call_info["uuids"]) for count, instance_uuid in enumerate(instance_uuids): bdms = db.block_device_mapping_get_all_by_instance(self.ctxt, instance_uuid) self.assertIsNotNone(bdms) instance = db.instance_get_by_uuid(self.ctxt, instance_uuid) meta = utils.instance_meta(instance) self.assertEqual("cow", meta["moo"]) sys_meta = utils.instance_sys_meta(instance) self.assertEqual("cat", sys_meta["meow"]) self.assertEqual("meow", instance["hostname"]) self.assertEqual("moo-%d" % (count + 1), instance["display_name"]) self.assertEqual(uuidsentinel.fake_image_ref, instance["image_ref"])
def _from_db_object(context, instance, db_inst, expected_attrs=None): """Method to help with migration to objects. Converts a database entity to a formal object. """ if expected_attrs is None: expected_attrs = [] # Most of the field names match right now, so be quick for field in instance.fields: if field in INSTANCE_OPTIONAL_FIELDS + INSTANCE_IMPLIED_FIELDS: continue elif field == 'deleted': instance.deleted = db_inst['deleted'] == db_inst['id'] elif field == 'cleaned': instance.cleaned = db_inst['cleaned'] == 1 else: instance[field] = db_inst[field] if 'metadata' in expected_attrs: instance['metadata'] = utils.instance_meta(db_inst) if 'system_metadata' in expected_attrs: instance['system_metadata'] = utils.instance_sys_meta(db_inst) if 'fault' in expected_attrs: instance['fault'] = ( instance_fault.InstanceFault.get_latest_for_instance( context, instance.uuid)) if 'pci_devices' in expected_attrs: if db_inst['pci_devices'] is None: pci_devices = None else: pci_devices = pci_device._make_pci_list( context, pci_device.PciDeviceList(), db_inst['pci_devices']) instance['pci_devices'] = pci_devices # NOTE(danms): info_cache and security_groups are almost # always joined in the DB layer right now, so check to see if # they are asked for and are present in the resulting object if 'info_cache' in expected_attrs and db_inst.get('info_cache'): instance['info_cache'] = instance_info_cache.InstanceInfoCache() instance_info_cache.InstanceInfoCache._from_db_object( context, instance['info_cache'], db_inst['info_cache']) if ('security_groups' in expected_attrs and db_inst.get('security_groups') is not None): instance['security_groups'] = security_group.SecurityGroupList() security_group._make_secgroup_list(context, instance['security_groups'], db_inst['security_groups']) instance._context = context instance.obj_reset_changes() return instance
def test_delete_flavor(self): namespace = 'foo' prefix = '%s_' % namespace db_inst = db.instance_create(self.context, { 'user_id': self.context.user_id, 'project_id': self.context.project_id, 'system_metadata': flavors.save_flavor_info( {}, flavors.get_default_flavor(), prefix)}) inst = instance.Instance.get_by_uuid(self.context, db_inst['uuid']) inst.delete_flavor(namespace) db_inst = db.instance_get(self.context, db_inst['id']) self.assertEqual({}, utils.instance_sys_meta(db_inst))
def test_create_instances_here(self): # Just grab the first instance type inst_type = db.flavor_get(self.ctxt, 1) image = {'properties': {}} instance_uuids = self.instance_uuids instance_props = { 'id': 'removed', 'security_groups': 'removed', 'info_cache': 'removed', 'name': 'instance-00000001', 'hostname': 'meow', 'display_name': 'moo', 'image_ref': 'fake_image_ref', 'user_id': self.ctxt.user_id, # Test these as lists 'metadata': [{ 'key': 'moo', 'value': 'cow' }], 'system_metadata': [{ 'key': 'meow', 'value': 'cat' }], 'project_id': self.ctxt.project_id } call_info = {'uuids': []} block_device_mapping = [ block_device.create_image_bdm('fake_image_ref') ] def _fake_instance_update_at_top(_ctxt, instance): call_info['uuids'].append(instance['uuid']) self.stubs.Set(self.msg_runner, 'instance_update_at_top', _fake_instance_update_at_top) self.scheduler._create_instances_here(self.ctxt, instance_uuids, instance_props, inst_type, image, ['default'], block_device_mapping) self.assertEqual(instance_uuids, call_info['uuids']) for instance_uuid in instance_uuids: instance = db.instance_get_by_uuid(self.ctxt, instance_uuid) meta = utils.instance_meta(instance) self.assertEqual('cow', meta['moo']) sys_meta = utils.instance_sys_meta(instance) self.assertEqual('cat', sys_meta['meow']) self.assertEqual('meow', instance['hostname']) self.assertEqual('moo-%s' % instance['uuid'], instance['display_name']) self.assertEqual('fake_image_ref', instance['image_ref'])
def required_by(instance): image_prop = utils.instance_sys_meta(instance).get( utils.SM_IMAGE_PROP_PREFIX + 'img_config_drive', 'optional') if image_prop not in ['optional', 'mandatory']: LOG.warning(_LW('Image config drive option %(image_prop)s is invalid ' 'and will be ignored'), {'image_prop': image_prop}, instance=instance) return (instance.get('config_drive') or 'always' == CONF.force_config_drive or strutils.bool_from_string(CONF.force_config_drive) or image_prop == 'mandatory')
def _test_init_instance_reverts_crashed_migrations(self, old_vm_state=None): power_on = True if (not old_vm_state or old_vm_state == vm_states.ACTIVE) else False sys_meta = { 'old_vm_state': old_vm_state } instance = { 'uuid': 'foo', 'vm_state': vm_states.ERROR, 'task_state': task_states.RESIZE_MIGRATING, 'power_state': power_state.SHUTDOWN, 'system_metadata': sys_meta } fixed = dict(instance, task_state=None) self.mox.StubOutWithMock(compute_utils, 'get_nw_info_for_instance') self.mox.StubOutWithMock(utils, 'instance_sys_meta') self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs') self.mox.StubOutWithMock(self.compute.driver, 'finish_revert_migration') self.mox.StubOutWithMock(self.compute, '_get_instance_volume_block_device_info') self.mox.StubOutWithMock(self.compute.driver, 'get_info') self.mox.StubOutWithMock(self.compute, '_instance_update') compute_utils.get_nw_info_for_instance(instance).AndReturn( network_model.NetworkInfo()) self.compute.driver.plug_vifs(instance, []) utils.instance_sys_meta(instance).AndReturn(sys_meta) self.compute._get_instance_volume_block_device_info( self.context, instance).AndReturn([]) self.compute.driver.finish_revert_migration(instance, [], [], power_on) self.compute._instance_update(self.context, instance['uuid'], task_state=None).AndReturn(fixed) self.compute.driver.get_info(fixed).AndReturn( {'state': power_state.SHUTDOWN}) self.mox.ReplayAll() self.compute._init_instance(self.context, instance)
def _from_db_object(context, instance, db_inst, expected_attrs=None): """Method to help with migration to objects. Converts a database entity to a formal object. """ LOG.debug(instance) if expected_attrs is None: expected_attrs = [] # Most of the field names match right now, so be quick for field in instance.fields: if field in INSTANCE_OPTIONAL_ATTRS: continue elif field == 'deleted': instance.deleted = db_inst['deleted'] == db_inst['id'] elif field == 'cleaned': instance.cleaned = db_inst['cleaned'] == 1 else: instance[field] = db_inst[field] if 'metadata' in expected_attrs: instance['metadata'] = utils.instance_meta(db_inst) if 'system_metadata' in expected_attrs: instance['system_metadata'] = utils.instance_sys_meta(db_inst) if 'fault' in expected_attrs: instance['fault'] = ( instance_fault.InstanceFault.get_latest_for_instance( context, instance.uuid)) if 'pci_devices' in expected_attrs: pci_devices = pci_device._make_pci_list( context, pci_device.PciDeviceList(), db_inst['pci_devices']) instance['pci_devices'] = pci_devices if 'info_cache' in expected_attrs: if db_inst['info_cache'] is None: instance.info_cache = None elif not instance.obj_attr_is_set('info_cache'): # TODO(danms): If this ever happens on a backlevel instance # passed to us by a backlevel service, things will break instance.info_cache = instance_info_cache.InstanceInfoCache() if instance.info_cache is not None: instance_info_cache.InstanceInfoCache._from_db_object( context, instance.info_cache, db_inst['info_cache']) if 'security_groups' in expected_attrs: sec_groups = security_group._make_secgroup_list( context, security_group.SecurityGroupList(), db_inst['security_groups']) instance['security_groups'] = sec_groups instance._context = context instance.obj_reset_changes() return instance
def from_instance(cls, instance): """Create instance from instance system metadata :param instance: Instance object Creates a new object instance, initializing from the system metadata "image_*" properties associated with instance :returns: an ImageMeta instance """ sysmeta = utils.instance_sys_meta(instance) image_meta = utils.get_image_from_system_metadata(sysmeta) return cls.from_dict(image_meta)
def notify_usage_exists(notifier, context, instance_ref, current_period=False, ignore_missing_network_data=True, system_metadata=None, extra_usage_info=None): """Generates 'exists' notification for an instance for usage auditing purposes. :param notifier: a messaging.Notifier :param current_period: if True, this will generate a usage for the current usage period; if False, this will generate a usage for the previous audit period. :param ignore_missing_network_data: if True, log any exceptions generated while getting network info; if False, raise the exception. :param system_metadata: system_metadata DB entries for the instance, if not None. *NOTE*: Currently unused here in trunk, but needed for potential custom modifications. :param extra_usage_info: Dictionary containing extra values to add or override in the notification if not None. """ audit_start, audit_end = notifications.audit_period_bounds(current_period) bw = notifications.bandwidth_usage(instance_ref, audit_start, ignore_missing_network_data) if system_metadata is None: system_metadata = utils.instance_sys_meta(instance_ref) # add image metadata to the notification: image_meta = notifications.image_meta(system_metadata) extra_info = dict(audit_period_beginning=str(audit_start), audit_period_ending=str(audit_end), bandwidth=bw, image_meta=image_meta) if extra_usage_info: extra_info.update(extra_usage_info) notify_about_instance_usage(notifier, context, instance_ref, 'exists', system_metadata=system_metadata, extra_usage_info=extra_info)
def notify_usage_exists(notifier, context, instance_ref, current_period=False, ignore_missing_network_data=True, system_metadata=None, extra_usage_info=None): """Generates 'exists' unversioned legacy notification for an instance for usage auditing purposes. :param notifier: a messaging.Notifier :param context: request context for the current operation :param instance_ref: nova.objects.Instance object from which to report usage :param current_period: if True, this will generate a usage for the current usage period; if False, this will generate a usage for the previous audit period. :param ignore_missing_network_data: if True, log any exceptions generated while getting network info; if False, raise the exception. :param system_metadata: system_metadata override for the instance. If None, the instance_ref.system_metadata will be used. :param extra_usage_info: Dictionary containing extra values to add or override in the notification if not None. """ audit_start, audit_end = notifications.audit_period_bounds(current_period) bw = notifications.bandwidth_usage(context, instance_ref, audit_start, ignore_missing_network_data) if system_metadata is None: system_metadata = utils.instance_sys_meta(instance_ref) # add image metadata to the notification: image_meta = notifications.image_meta(system_metadata) extra_info = dict(audit_period_beginning=str(audit_start), audit_period_ending=str(audit_end), bandwidth=bw, image_meta=image_meta) if extra_usage_info: extra_info.update(extra_usage_info) notify_about_instance_usage(notifier, context, instance_ref, 'exists', extra_usage_info=extra_info)
def _from_db_object(context, instance, db_inst, expected_attrs=None): """Method to help with migration to objects. Converts a database entity to a formal object. """ if expected_attrs is None: expected_attrs = [] # Most of the field names match right now, so be quick for field in instance.fields: if field in INSTANCE_OPTIONAL_ATTRS: continue elif field == 'deleted': instance.deleted = db_inst['deleted'] == db_inst['id'] elif field == 'cleaned': instance.cleaned = db_inst['cleaned'] == 1 else: instance[field] = db_inst[field] if 'metadata' in expected_attrs: instance['metadata'] = utils.instance_meta(db_inst) if 'system_metadata' in expected_attrs: instance['system_metadata'] = utils.instance_sys_meta(db_inst) if 'fault' in expected_attrs: instance['fault'] = ( instance_fault.InstanceFault.get_latest_for_instance( context, instance.uuid)) if 'pci_devices' in expected_attrs: pci_devices = pci_device._make_pci_list(context, pci_device.PciDeviceList(), db_inst['pci_devices']) instance['pci_devices'] = pci_devices if 'info_cache' in expected_attrs: if db_inst['info_cache'] is None: info_cache = None else: info_cache = instance_info_cache.InstanceInfoCache() instance_info_cache.InstanceInfoCache._from_db_object( context, info_cache, db_inst['info_cache']) instance['info_cache'] = info_cache if 'security_groups' in expected_attrs: sec_groups = security_group._make_secgroup_list( context, security_group.SecurityGroupList(), db_inst['security_groups']) instance['security_groups'] = sec_groups instance._context = context instance.obj_reset_changes() return instance
def required_by(instance): image_prop = utils.instance_sys_meta(instance).get( utils.SM_IMAGE_PROP_PREFIX + 'img_config_drive', 'optional') if image_prop not in ['optional', 'mandatory']: LOG.warning(_LW('Image config drive option %(image_prop)s is invalid ' 'and will be ignored'), {'image_prop': image_prop}, instance=instance) return (instance.get('config_drive') or 'always' == CONF.force_config_drive or strutils.bool_from_string(CONF.force_config_drive) or image_prop == 'mandatory' )
def test_delete_flavor(self): namespace = "foo" prefix = "%s_" % namespace db_inst = db.instance_create( self.context, { "user_id": self.context.user_id, "project_id": self.context.project_id, "system_metadata": flavors.save_flavor_info({}, flavors.get_default_flavor(), prefix), }, ) inst = instance.Instance.get_by_uuid(self.context, db_inst["uuid"]) inst.delete_flavor(namespace) db_inst = db.instance_get(self.context, db_inst["id"]) self.assertEqual({}, utils.instance_sys_meta(db_inst))
def test_create_instances_here(self): # Just grab the first instance type inst_type = flavors.get_flavor(1) image = {'properties': {}} instance_uuids = self.instance_uuids instance_props = {'id': 'removed', 'security_groups': 'removed', 'info_cache': 'removed', 'name': 'instance-00000001', 'hostname': 'meow', 'display_name': 'moo', 'image_ref': 'fake_image_ref', 'user_id': self.ctxt.user_id, # Test these as lists 'metadata': {'moo': 'cow'}, 'system_metadata': {'meow': 'cat'}, 'flavor': inst_type, 'project_id': self.ctxt.project_id} call_info = {'uuids': []} block_device_mapping = [ objects.BlockDeviceMapping(context=self.ctxt, **fake_block_device.FakeDbBlockDeviceDict( block_device.create_image_bdm('fake_image_ref'), anon=True)) ] def _fake_instance_update_at_top(_ctxt, instance): call_info['uuids'].append(instance['uuid']) self.stubs.Set(self.msg_runner, 'instance_update_at_top', _fake_instance_update_at_top) self.scheduler._create_instances_here(self.ctxt, instance_uuids, instance_props, inst_type, image, ['default'], block_device_mapping) self.assertEqual(instance_uuids, call_info['uuids']) for count, instance_uuid in enumerate(instance_uuids): instance = db.instance_get_by_uuid(self.ctxt, instance_uuid) meta = utils.instance_meta(instance) self.assertEqual('cow', meta['moo']) sys_meta = utils.instance_sys_meta(instance) self.assertEqual('cat', sys_meta['meow']) self.assertEqual('meow', instance['hostname']) self.assertEqual('moo-%d' % (count + 1), instance['display_name']) self.assertEqual('fake_image_ref', instance['image_ref'])
def required_by(instance): image_prop = utils.instance_sys_meta(instance).get(utils.SM_IMAGE_PROP_PREFIX + "img_config_drive", "optional") if image_prop not in ["optional", "mandatory"]: LOG.warning( _LW("Image config drive option %(image_prop)s is invalid " "and will be ignored"), {"image_prop": image_prop}, instance=instance, ) return ( instance.get("config_drive") or "always" == CONF.force_config_drive or strutils.bool_from_string(CONF.force_config_drive) or image_prop == "mandatory" )
def notify_usage_exists( notifier, context, instance_ref, current_period=False, ignore_missing_network_data=True, system_metadata=None, extra_usage_info=None, ): """Generates 'exists' notification for an instance for usage auditing purposes. :param notifier: a messaging.Notifier :param current_period: if True, this will generate a usage for the current usage period; if False, this will generate a usage for the previous audit period. :param ignore_missing_network_data: if True, log any exceptions generated while getting network info; if False, raise the exception. :param system_metadata: system_metadata DB entries for the instance, if not None. *NOTE*: Currently unused here in trunk, but needed for potential custom modifications. :param extra_usage_info: Dictionary containing extra values to add or override in the notification if not None. """ audit_start, audit_end = notifications.audit_period_bounds(current_period) bw = notifications.bandwidth_usage(instance_ref, audit_start, ignore_missing_network_data) if system_metadata is None: system_metadata = utils.instance_sys_meta(instance_ref) # add image metadata to the notification: image_meta = notifications.image_meta(system_metadata) extra_info = dict( audit_period_beginning=str(audit_start), audit_period_ending=str(audit_end), bandwidth=bw, image_meta=image_meta ) if extra_usage_info: extra_info.update(extra_usage_info) notify_about_instance_usage( notifier, context, instance_ref, "exists", system_metadata=system_metadata, extra_usage_info=extra_info )
def _create_instances_here(self, ctxt, instance_uuids, instance_properties, instance_type, image, security_groups, block_device_mapping): instance_values = copy.copy(instance_properties) # The parent may pass these metadata values as lists, and the # create call expects it to be a dict. instance_values['metadata'] = utils.instance_meta(instance_values) sys_metadata = utils.instance_sys_meta(instance_values) # Make sure the flavor info is set. It may not have been passed # down. sys_metadata = flavors.save_flavor_info(sys_metadata, instance_type) instance_values['system_metadata'] = sys_metadata # Pop out things that will get set properly when re-creating the # instance record. instance_values.pop('id') instance_values.pop('name') instance_values.pop('info_cache') instance_values.pop('security_groups') # FIXME(danms): The instance was brutally serialized before being # sent over RPC to us. Thus, the pci_requests value wasn't really # sent in a useful form. Since it was getting ignored for cells # before it was part of the Instance, skip it now until cells RPC # is sending proper instance objects. instance_values.pop('pci_requests', None) instances = [] num_instances = len(instance_uuids) for i, instance_uuid in enumerate(instance_uuids): instance = objects.Instance(context=ctxt) instance.update(instance_values) instance.uuid = instance_uuid instance = self.compute_api.create_db_entry_for_new_instance( ctxt, instance_type, image, instance, security_groups, block_device_mapping, num_instances, i) instances.append(instance) instance_p = obj_base.obj_to_primitive(instance) self.msg_runner.instance_update_at_top(ctxt, instance_p) return instances
def _from_db_object(context, instance, db_inst, expected_attrs=None): """Method to help with migration to objects. Converts a database entity to a formal object. """ if expected_attrs is None: expected_attrs = [] # Most of the field names match right now, so be quick for field in instance.fields: if field in INSTANCE_OPTIONAL_ATTRS: continue elif field == "deleted": instance.deleted = db_inst["deleted"] == db_inst["id"] elif field == "cleaned": instance.cleaned = db_inst["cleaned"] == 1 else: instance[field] = db_inst[field] if "metadata" in expected_attrs: instance["metadata"] = utils.instance_meta(db_inst) if "system_metadata" in expected_attrs: instance["system_metadata"] = utils.instance_sys_meta(db_inst) if "fault" in expected_attrs: instance["fault"] = instance_fault.InstanceFault.get_latest_for_instance(context, instance.uuid) if "pci_devices" in expected_attrs: pci_devices = pci_device._make_pci_list(context, pci_device.PciDeviceList(), db_inst["pci_devices"]) instance["pci_devices"] = pci_devices if "info_cache" in expected_attrs: if db_inst["info_cache"] is None: info_cache = None else: info_cache = instance_info_cache.InstanceInfoCache() instance_info_cache.InstanceInfoCache._from_db_object(context, info_cache, db_inst["info_cache"]) instance["info_cache"] = info_cache if "security_groups" in expected_attrs: sec_groups = security_group._make_secgroup_list( context, security_group.SecurityGroupList(), db_inst["security_groups"] ) instance["security_groups"] = sec_groups instance._context = context instance.obj_reset_changes() return instance
def test_create_instances_here(self): # Just grab the first instance type inst_type = flavors.get_flavor(1) image = {"properties": {}} instance_uuids = self.instance_uuids instance_props = { "id": "removed", "security_groups": "removed", "info_cache": "removed", "name": "instance-00000001", "hostname": "meow", "display_name": "moo", "image_ref": "fake_image_ref", "user_id": self.ctxt.user_id, # Test these as lists "metadata": {"moo": "cow"}, "system_metadata": {"meow": "cat"}, "flavor": inst_type, "project_id": self.ctxt.project_id, } call_info = {"uuids": []} block_device_mapping = [block_device.create_image_bdm("fake_image_ref")] def _fake_instance_update_at_top(_ctxt, instance): call_info["uuids"].append(instance["uuid"]) self.stubs.Set(self.msg_runner, "instance_update_at_top", _fake_instance_update_at_top) self.scheduler._create_instances_here( self.ctxt, instance_uuids, instance_props, inst_type, image, ["default"], block_device_mapping ) self.assertEqual(instance_uuids, call_info["uuids"]) for count, instance_uuid in enumerate(instance_uuids): instance = db.instance_get_by_uuid(self.ctxt, instance_uuid) meta = utils.instance_meta(instance) self.assertEqual("cow", meta["moo"]) sys_meta = utils.instance_sys_meta(instance) self.assertEqual("cat", sys_meta["meow"]) self.assertEqual("meow", instance["hostname"]) self.assertEqual("moo-%d" % (count + 1), instance["display_name"]) self.assertEqual("fake_image_ref", instance["image_ref"])
def test_create_instances_here(self): # Just grab the first instance type inst_type = db.flavor_get(self.ctxt, 1) image = {'properties': {}} instance_uuids = self.instance_uuids instance_props = {'id': 'removed', 'security_groups': 'removed', 'info_cache': 'removed', 'name': 'instance-00000001', 'hostname': 'meow', 'display_name': 'moo', 'image_ref': 'fake_image_ref', 'user_id': self.ctxt.user_id, # Test these as lists 'metadata': [{'key': 'moo', 'value': 'cow'}], 'system_metadata': [{'key': 'meow', 'value': 'cat'}], 'project_id': self.ctxt.project_id} call_info = {'uuids': []} block_device_mapping = [block_device.create_image_bdm( 'fake_image_ref')] def _fake_instance_update_at_top(_ctxt, instance): call_info['uuids'].append(instance['uuid']) self.stubs.Set(self.msg_runner, 'instance_update_at_top', _fake_instance_update_at_top) self.scheduler._create_instances_here(self.ctxt, instance_uuids, instance_props, inst_type, image, ['default'], block_device_mapping) self.assertEqual(instance_uuids, call_info['uuids']) for instance_uuid in instance_uuids: instance = db.instance_get_by_uuid(self.ctxt, instance_uuid) meta = utils.instance_meta(instance) self.assertEqual('cow', meta['moo']) sys_meta = utils.instance_sys_meta(instance) self.assertEqual('cat', sys_meta['meow']) self.assertEqual('meow', instance['hostname']) self.assertEqual('moo-%s' % instance['uuid'], instance['display_name']) self.assertEqual('fake_image_ref', instance['image_ref'])
def get_image_metadata(context, image_service, image_id, instance): # If the base image is still available, get its metadata try: image = image_service.show(context, image_id) except Exception as e: LOG.warning(_("Can't access image %(image_id)s: %(error)s"), {"image_id": image_id, "error": e}, instance=instance) image_system_meta = {} else: flavor = flavors.extract_flavor(instance) image_system_meta = utils.get_system_metadata_from_image(image, flavor) # Get the system metadata from the instance system_meta = utils.instance_sys_meta(instance) # Merge the metadata from the instance with the image's, if any system_meta.update(image_system_meta) # Convert the system metadata to image metadata return utils.get_image_from_system_metadata(system_meta)
def get_instance_pci_requests(instance, prefix=""): """Get instance's pci allocation requirement. After a flavor's pci requirement is translated into pci requests, the requests are kept in instance's system metadata to avoid future flavor access and translation. This function get the pci requests from instance system metadata directly. As save_flavor_pci_info(), the prefix can be used to stash information about another flavor for later use, like in resize. """ if 'system_metadata' not in instance: return [] system_metadata = utils.instance_sys_meta(instance) pci_requests = system_metadata.get('%spci_requests' % prefix) if not pci_requests: return [] return jsonutils.loads(pci_requests)
def from_instance(cls, instance): """Create instance from instance system metadata :param instance: Instance object Creates a new object instance, initializing from the system metadata "image_*" properties associated with instance :returns: an ImageMeta instance """ sysmeta = utils.instance_sys_meta(instance) image_meta = utils.get_image_from_system_metadata(sysmeta) # NOTE(lyarwood): Provide the id of the image in image_meta if it # wasn't persisted in the system_metadata of the instance previously. # This is only provided to allow users of image_meta to avoid the need # to pass around references to instance.image_ref alongside image_meta. if image_meta.get('id') is None and instance.image_ref: image_meta['id'] = instance.image_ref return cls.from_dict(image_meta)
def handle_password(req, meta_data): ctxt = context.get_admin_context() if req.method == 'GET': return meta_data.password elif req.method == 'POST': # NOTE(vish): The conflict will only happen once the metadata cache # updates, but it isn't a huge issue if it can be set for # a short window. if meta_data.password: raise exc.HTTPConflict() if (req.content_length > MAX_SIZE or len(req.body) > MAX_SIZE): msg = _("Request is too large.") raise exc.HTTPBadRequest(explanation=msg) conductor_api = conductor.API() instance = conductor_api.instance_get_by_uuid(ctxt, meta_data.uuid) sys_meta = utils.instance_sys_meta(instance) sys_meta.update(convert_password(ctxt, req.body)) conductor_api.instance_update(ctxt, meta_data.uuid, system_metadata=sys_meta) else: raise exc.HTTPBadRequest()
def extract_flavor(instance, prefix=''): """Create an InstanceType-like object from instance's system_metadata information. """ instance_type = {} sys_meta = utils.instance_sys_meta(instance) for key, type_fn in system_metadata_flavor_props.items(): type_key = '%sinstance_type_%s' % (prefix, key) instance_type[key] = type_fn(sys_meta[type_key]) # NOTE(danms): We do NOT save all of extra_specs, but only the # NUMA-related ones that we need to avoid an uglier alternative. This # should be replaced by a general split-out of flavor information from # system_metadata very soon. extra_specs = [(k, v) for k, v in sys_meta.items() if k.startswith('%sinstance_type_extra_' % prefix)] if extra_specs: instance_type['extra_specs'] = {} for key, value in extra_specs: extra_key = key[len('%sinstance_type_extra_' % prefix):] instance_type['extra_specs'][extra_key] = value return instance_type
def get_image_metadata(context, image_api, image_id_or_uri, instance): # If the base image is still available, get its metadata try: image = image_api.get(context, image_id_or_uri) except (exception.ImageNotAuthorized, exception.ImageNotFound, exception.Invalid) as e: LOG.warning(_("Can't access image %(image_id)s: %(error)s"), { "image_id": image_id_or_uri, "error": e }, instance=instance) image_system_meta = {} else: flavor = flavors.extract_flavor(instance) image_system_meta = utils.get_system_metadata_from_image(image, flavor) # Get the system metadata from the instance system_meta = utils.instance_sys_meta(instance) # Merge the metadata from the instance with the image's, if any system_meta.update(image_system_meta) # Convert the system metadata to image metadata return utils.get_image_from_system_metadata(system_meta)
def notify_usage_exists(notifier, context, instance_ref, host, current_period=False, ignore_missing_network_data=True, system_metadata=None, extra_usage_info=None): """Generates 'exists' unversioned legacy and transformed notification for an instance for usage auditing purposes. :param notifier: a messaging.Notifier :param context: request context for the current operation :param instance_ref: nova.objects.Instance object from which to report usage :param host: the host emitting the notification :param current_period: if True, this will generate a usage for the current usage period; if False, this will generate a usage for the previous audit period. :param ignore_missing_network_data: if True, log any exceptions generated while getting network info; if False, raise the exception. :param system_metadata: system_metadata override for the instance. If None, the instance_ref.system_metadata will be used. :param extra_usage_info: Dictionary containing extra values to add or override in the notification if not None. """ audit_start, audit_end = notifications.audit_period_bounds(current_period) bw = notifications.bandwidth_usage(context, instance_ref, audit_start, ignore_missing_network_data) if system_metadata is None: system_metadata = utils.instance_sys_meta(instance_ref) # add image metadata to the notification: image_meta = notifications.image_meta(system_metadata) extra_info = dict(audit_period_beginning=str(audit_start), audit_period_ending=str(audit_end), bandwidth=bw, image_meta=image_meta) if extra_usage_info: extra_info.update(extra_usage_info) notify_about_instance_usage(notifier, context, instance_ref, 'exists', extra_usage_info=extra_info) audit_period = instance_notification.AuditPeriodPayload( audit_period_beginning=audit_start, audit_period_ending=audit_end) bandwidth = [instance_notification.BandwidthPayload( network_name=label, in_bytes=b['bw_in'], out_bytes=b['bw_out']) for label, b in bw.items()] payload = instance_notification.InstanceExistsPayload( context=context, instance=instance_ref, audit_period=audit_period, bandwidth=bandwidth) notification = instance_notification.InstanceExistsNotification( context=context, priority=fields.NotificationPriority.INFO, publisher=notification_base.NotificationPublisher( host=host, source=fields.NotificationSource.COMPUTE), event_type=notification_base.EventType( object='instance', action=fields.NotificationAction.EXISTS), payload=payload) notification.emit(context)
def _from_db_object(context, instance, db_inst, expected_attrs=None): """Method to help with migration to objects. Converts a database entity to a formal object. """ instance._context = context if expected_attrs is None: expected_attrs = [] # Most of the field names match right now, so be quick for field in instance.fields: if field in INSTANCE_OPTIONAL_ATTRS: continue elif field == 'deleted': instance.deleted = db_inst['deleted'] == db_inst['id'] elif field == 'cleaned': instance.cleaned = db_inst['cleaned'] == 1 else: instance[field] = db_inst[field] # NOTE(danms): We can be called with a dict instead of a # SQLAlchemy object, so we have to be careful here if hasattr(db_inst, '__dict__'): have_extra = 'extra' in db_inst.__dict__ and db_inst['extra'] else: have_extra = 'extra' in db_inst and db_inst['extra'] if 'metadata' in expected_attrs: instance['metadata'] = utils.instance_meta(db_inst) if 'system_metadata' in expected_attrs: instance['system_metadata'] = utils.instance_sys_meta(db_inst) if 'fault' in expected_attrs: instance['fault'] = (objects.InstanceFault.get_latest_for_instance( context, instance.uuid)) if 'numa_topology' in expected_attrs: if have_extra: instance._load_numa_topology( db_inst['extra'].get('numa_topology')) else: instance.numa_topology = None if 'pci_requests' in expected_attrs: if have_extra: instance._load_pci_requests( db_inst['extra'].get('pci_requests')) else: instance.pci_requests = None if 'vcpu_model' in expected_attrs: if have_extra: instance._load_vcpu_model(db_inst['extra'].get('vcpu_model')) else: instance.vcpu_model = None if 'ec2_ids' in expected_attrs: instance._load_ec2_ids() if 'migration_context' in expected_attrs: if have_extra: instance._load_migration_context( db_inst['extra'].get('migration_context')) else: instance.migration_context = None if 'info_cache' in expected_attrs: if db_inst.get('info_cache') is None: instance.info_cache = None elif not instance.obj_attr_is_set('info_cache'): # TODO(danms): If this ever happens on a backlevel instance # passed to us by a backlevel service, things will break instance.info_cache = objects.InstanceInfoCache(context) if instance.info_cache is not None: instance.info_cache._from_db_object(context, instance.info_cache, db_inst['info_cache']) if any([ x in expected_attrs for x in ('flavor', 'old_flavor', 'new_flavor') ]): if have_extra and db_inst['extra'].get('flavor'): instance._flavor_from_db(db_inst['extra']['flavor']) # TODO(danms): If we are updating these on a backlevel instance, # we'll end up sending back new versions of these objects (see # above note for new info_caches if 'pci_devices' in expected_attrs: pci_devices = base.obj_make_list(context, objects.PciDeviceList(context), objects.PciDevice, db_inst['pci_devices']) instance['pci_devices'] = pci_devices if 'security_groups' in expected_attrs: sec_groups = base.obj_make_list(context, objects.SecurityGroupList(context), objects.SecurityGroup, db_inst.get('security_groups', [])) instance['security_groups'] = sec_groups if 'tags' in expected_attrs: tags = base.obj_make_list(context, objects.TagList(context), objects.Tag, db_inst['tags']) instance['tags'] = tags instance.obj_reset_changes() return instance