def _get_metadata(instance): # FIXME(danms): Transitional support for objects metadata = instance.get('metadata') if isinstance(instance, obj_base.NovaObject): return metadata or {} else: return utils.instance_meta(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 = [ 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 _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) # 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') instance_values.pop('flavor') # 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.flavor = instance_type instance.old_flavor = None instance.new_flavor = None 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 __init__(self, instance, address=None, content=None, extra_md=None, conductor_api=None, network_info=None, vd_driver=None): """Creation of this object should basically cover all time consuming collection. Methods after that should not cause time delays due to network operations or lengthy cpu operations. The user should then get a single instance and make multiple method calls on it. """ if not content: content = [] ctxt = context.get_admin_context() # The default value of mimeType is set to MIME_TYPE_TEXT_PLAIN self.set_mimetype(MIME_TYPE_TEXT_PLAIN) self.instance = instance self.extra_md = extra_md if conductor_api: capi = conductor_api else: capi = conductor.API() self.availability_zone = az.get_instance_availability_zone(ctxt, instance) self.security_groups = objects.SecurityGroupList.get_by_instance( ctxt, instance) self.mappings = _format_instance_mapping(ctxt, instance) if instance.user_data is not None: self.userdata_raw = base64.b64decode(instance.user_data) else: self.userdata_raw = None self.ec2_ids = capi.get_ec2_ids(ctxt, obj_base.obj_to_primitive(instance)) self.address = address # expose instance metadata. self.launch_metadata = utils.instance_meta(instance) self.password = password.extract_password(instance) self.uuid = instance.uuid self.content = {} self.files = [] # get network info, and the rendered network template if network_info is None: network_info = instance.info_cache.network_info self.ip_info = \ ec2utils.get_ip_info_for_instance_from_nw_info(network_info) self.network_config = None cfg = netutils.get_injected_network_template(network_info) if cfg: key = "%04i" % len(self.content) self.content[key] = cfg self.network_config = {"name": "network_config", 'content_path': "/%s/%s" % (CONTENT_DIR, key)} # 'content' is passed in from the configdrive code in # patron/virt/libvirt/driver.py. That's how we get the injected files # (personalities) in. AFAIK they're not stored in the db at all, # so are not available later (web service metadata time). for (path, contents) in content: key = "%04i" % len(self.content) self.files.append({'path': path, 'content_path': "/%s/%s" % (CONTENT_DIR, key)}) self.content[key] = contents if vd_driver is None: vdclass = importutils.import_class(CONF.vendordata_driver) else: vdclass = vd_driver self.vddriver = vdclass(instance=instance, address=address, extra_md=extra_md, network_info=network_info) self.route_configuration = None