Beispiel #1
0
    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)
Beispiel #2
0
    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
Beispiel #3
0
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
Beispiel #4
0
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)
Beispiel #5
0
 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)
Beispiel #6
0
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
Beispiel #7
0
    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)
Beispiel #8
0
    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'])
Beispiel #9
0
    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)
Beispiel #10
0
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)
Beispiel #11
0
    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
Beispiel #12
0
 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
Beispiel #14
0
    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
Beispiel #15
0
 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)
Beispiel #17
0
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
Beispiel #18
0
 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})
Beispiel #19
0
 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})
Beispiel #20
0
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
Beispiel #21
0
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
Beispiel #22
0
 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})
Beispiel #23
0
    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'])
Beispiel #24
0
    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'])
Beispiel #25
0
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
Beispiel #26
0
    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"])
Beispiel #27
0
    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
Beispiel #28
0
    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
Beispiel #29
0
 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))
Beispiel #30
0
 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'])
Beispiel #32
0
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')
Beispiel #33
0
    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 _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)
Beispiel #35
0
    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
Beispiel #36
0
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
Beispiel #37
0
    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)
Beispiel #38
0
    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)
Beispiel #39
0
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)
Beispiel #40
0
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)
Beispiel #41
0
    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
Beispiel #42
0
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'
            )
Beispiel #43
0
 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))
Beispiel #44
0
    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'])
Beispiel #45
0
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"
    )
Beispiel #46
0
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
    )
Beispiel #47
0
    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
Beispiel #48
0
    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"])
Beispiel #50
0
    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'])
Beispiel #51
0
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)
Beispiel #52
0
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)
Beispiel #53
0
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)
Beispiel #54
0
    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)
Beispiel #55
0
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()
Beispiel #56
0
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
Beispiel #57
0
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)
Beispiel #58
0
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)
Beispiel #59
0
    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