Пример #1
0
    def _inject_into_image(self, context, node, instance, network_info, injected_files=None, admin_password=None):
        """Inject last-mile configuration into instances image

        Much of this method is a hack around DHCP and cloud-init
        not working together with baremetal provisioning yet.
        """
        partition = None
        if not instance["kernel_id"]:
            partition = "1"

        ssh_key = None
        if "key_data" in instance and instance["key_data"]:
            ssh_key = str(instance["key_data"])

        if injected_files is None:
            injected_files = []
        else:
            injected_files = list(injected_files)

        net_config = build_network_config(network_info)

        if instance["hostname"]:
            injected_files.append(("/etc/hostname", instance["hostname"]))

        LOG.debug("Injecting files into image for instance %(name)s", {"name": instance["name"]})

        bm_utils.inject_into_image(
            image=get_image_file_path(instance),
            key=ssh_key,
            net=net_config,
            metadata=utils.instance_meta(instance),
            admin_password=admin_password,
            files=injected_files,
            partition=partition,
        )
Пример #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
Пример #3
0
def get_instance_path(instance, relative=False):
    """Determine the correct path for instance storage.

    This method determines the directory name for instance storage.

    :param instance: the instance we want a path for
    :param relative: if True, just the relative path is returned

    :returns: a path to store information about that instance
    """
    if relative:
        return instance.uuid
    #return os.path.join(CONF.instances_path, instance.uuid)
    if CONF.storage_scope.lower() == "global":
        interpath = "global"
    else:
        interpath = None
    if len(instance.metadata) > 0:
        ins_meta = utils.instance_meta(instance)
        for key, value in ins_meta.items():
            if key.lower() == 'storage_scope':
                if value.lower() == 'global':
                    interpath = "global"
                else:
                    interpath = None
                break
    if interpath is None:
        return os.path.join(CONF.instances_path, instance.uuid)
    else:
        return os.path.join(CONF.instances_path, interpath, instance.uuid)
Пример #4
0
 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)
Пример #5
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)
Пример #6
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
Пример #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
        # 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
Пример #8
0
    def spawn(self, context, instance, image_meta, injected_files,
              admin_password, network_info=None, block_device_info=None,
              flavor=None):
        image_name = self._get_image_name(context, instance, image_meta)
        args = {
            'hostname': instance['name'],
            'mem_limit': self._get_memory_limit_bytes(instance),
            'cpu_shares': self._get_cpu_shares(instance),
            'network_disabled': True,
        }

        try:
            image = self.docker.inspect_image(self._encode_utf8(image_name))
        except errors.APIError:
            image = None

        if not image:
            image = self._pull_missing_image(context, image_meta, instance)
        # Glance command-line overrides any set in the Docker image
        if (image_meta and
                image_meta.get('properties', {}).get('os_command_line')):
            args['command'] = image_meta['properties'].get('os_command_line')

        if 'metadata' in instance:
            args['environment'] = nova_utils.instance_meta(instance)

        container_id = self._create_container(instance, image_name, args)
        if not container_id:
            raise exception.InstanceDeployFailure(
                _('Cannot create container'),
                instance_id=instance['name'])

        self._start_container(container_id, instance, network_info)
Пример #9
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'])
Пример #10
0
def get_instance_path(instance, relative=False):
    """Determine the correct path for instance storage.

    This method determines the directory name for instance storage.

    :param instance: the instance we want a path for
    :param relative: if True, just the relative path is returned

    :returns: a path to store information about that instance
    """
    if relative:
        return instance.uuid
    #return os.path.join(CONF.instances_path, instance.uuid)
    if CONF.storage_scope.lower() == "global":
        interpath = "global"
    else:
        interpath = None
    if len(instance.metadata) > 0:
        ins_meta = utils.instance_meta(instance)
        for key,value in ins_meta.items():
            if key.lower() == 'storage_scope':
                if value.lower() == 'global':
                    interpath = "global"
                else:
                    interpath = None
                break
    if interpath is None:
        return os.path.join(CONF.instances_path, instance.uuid)
    else:
        return os.path.join(CONF.instances_path, interpath, instance.uuid)
Пример #11
0
 def _get_metadata(instance):
     # FIXME(danms): Transitional support for objects
     metadata = instance.get('metadata')
     if isinstance(instance, instance_obj.Instance):
         return metadata or {}
     else:
         return utils.instance_meta(instance)
    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)
Пример #13
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)
Пример #14
0
    def spawn(self, context, instance, image_meta, injected_files,
              admin_password, network_info=None, block_device_info=None,
              flavor=None):
        image_name = self._get_image_name(context, instance, image_meta)
        args = {
            'hostname': instance['name'],
            'mem_limit': self._get_memory_limit_bytes(instance),
            'cpu_shares': self._get_cpu_shares(instance),
            'network_disabled': True,
        }

        try:
            image = self.docker.inspect_image(self._encode_utf8(image_name))
        except errors.APIError:
            image = None

        if not image:
            image = self._pull_missing_image(context, image_meta, instance)
        # Glance command-line overrides any set in the Docker image
        if (image_meta and
                image_meta.get('properties', {}).get('os_command_line')):
            args['command'] = image_meta['properties'].get('os_command_line')

        if 'metadata' in instance:
            args['environment'] = nova_utils.instance_meta(instance)

        container_id = self._create_container(instance, image_name, args)
        if not container_id:
            raise exception.InstanceDeployFailure(
                _('Cannot create container'),
                instance_id=instance['name'])

        self._start_container(container_id, instance, network_info)
Пример #15
0
    def spawn(self, context, instance, image_meta, injected_files,
              admin_password, network_info=None, block_device_info=None):
        image_name = self._get_image_name(context, instance, image_meta)
        args = {
            'Hostname': instance['name'],
            'Image': image_name,
            'Memory': self._get_memory_limit_bytes(instance),
            'CpuShares': self._get_cpu_shares(instance),
            'NetworkDisabled': True,
        }

        image = self.docker.inspect_image(image_name)

        if not image:
            image = self._pull_missing_image(image_name, instance)

        if not (image and image['container_config']['Cmd']):
            args['Cmd'] = ['sh']
        # Glance command-line overrides any set in the Docker image
        if (image_meta and
                image_meta.get('properties', {}).get('os_command_line')):
            args['Cmd'] = image_meta['properties'].get('os_command_line')

        # fix from ED
        args['Env'] = [pair[0]+'='+pair[1] for pair in utils.instance_meta(instance).items()]

        container_id = self._create_container(instance, args)
        if not container_id:
            raise exception.InstanceDeployFailure(
                _('Cannot create container'),
                instance_id=instance['name'])

        self._start_container(instance, network_info)
Пример #16
0
 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)
Пример #17
0
    def spawn(self,
              context,
              instance,
              image_meta,
              injected_files,
              admin_password,
              network_info=None,
              block_device_info=None,
              flavor=None,
              image_name=None):
        if not image_name:
            image_name = self._get_image_name(context, instance, image_meta)
        ips = self._extract_ips_entries(network_info)

        ips_addr = '-'.join(ips[0].split('.'))
        LOG.info('ooooooooo:%s:%s', (ips, ips_addr))
        dns = self._extract_dns_entries(network_info)
        #'hostname': instance['name'],
        args = {
            'hostname':
            'docker%s' % ips_addr,
            'mem_limit':
            self._get_memory_limit_bytes(instance),
            'cpu_shares':
            self._get_cpu_shares(instance),
            'network_disabled':
            True,
            'dns':
            dns,
            'extra_hosts': ["docker%s:%s" % (ips_addr, ips[0])],
            'binds':
            ["/data/docker/%s:/data" % ips_addr,
             "/tmp/%s:/tmp" % ips_addr],
        }

        try:
            LOG.info('IIIIIIIIIIIIIIIIIIIIIIIIMAGE name %s' % image_name)
            image = self.docker.inspect_image(self._encode_utf8(image_name))
        except errors.APIError:
            image = None

        if not image:
            image = self._pull_missing_image1(context, image_meta, instance)
        # Glance command-line overrides any set in the Docker image
        if (image_meta is not None
                and image_meta.properties.get("os_command_line") is not None):
            args['command'] = image_meta.properties.get("os_command_line")

        if 'metadata' in instance:
            args['environment'] = nova_utils.instance_meta(instance)

        container_id = self._create_container(instance, image_name, args)
        ###container create finish###

        if not container_id:
            raise exception.InstanceDeployFailure(_('Cannot create container'),
                                                  instance_id=instance['name'])

        self._start_container(container_id, instance, network_info)
Пример #18
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'])
Пример #19
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)
        # 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)

        # FIXME(danms): Same for ec2_ids
        instance_values.pop('ec2_ids', None)

        # FIXME(danms): Same for keypairs
        instance_values.pop('keypairs', None)

        instances = []
        num_instances = len(instance_uuids)
        security_groups = (
            self.compute_api.security_group_api.populate_security_groups(
                security_groups))
        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)
            block_device_mapping = (
                self.compute_api._bdm_validate_set_size_and_instance(
                    ctxt, instance, instance_type, block_device_mapping))
            self.compute_api._create_block_device_mapping(block_device_mapping)

            instances.append(instance)
            self.msg_runner.instance_update_at_top(ctxt, instance)
        return instances
Пример #20
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'])
Пример #21
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"])
Пример #22
0
    def __init__(self,
                 path,
                 source_type,
                 driver_format,
                 instance,
                 is_block_dev=False):
        """Image initialization.

        :param path: libvirt's representation of the path of this disk.
        :param source_type: block or file
        :param driver_format: raw or qcow2
        :param is_block_dev:
        """
        if (CONF.ephemeral_storage_encryption.enabled
                and not self._supports_encryption()):
            msg = _('Incompatible settings: ephemeral storage encryption is '
                    'supported only for LVM images.')
            raise exception.InternalError(msg)

        self.path = path

        self.source_type = source_type
        self.driver_format = driver_format
        self.driver_io = None
        self.discard_mode = CONF.libvirt.hw_disk_discard
        self.is_block_dev = is_block_dev
        self.preallocate = False

        # NOTE(dripton): We store lines of json (path, disk_format) in this
        # file, for some image types, to prevent attacks based on changing the
        # disk_format.
        self.disk_info_path = None

        # NOTE(mikal): We need a lock directory which is shared along with
        # instance files, to cover the scenario where multiple compute nodes
        # are trying to create a base file at the same time
        if CONF.storage_scope.lower() == "global":
            interpath = "global"
        else:
            interpath = None
        if len(instance['metadata']) > 0:
            ins_meta = utils.instance_meta(instance)
            for key, value in ins_meta.items():
                if key.lower() == 'storage_scope':
                    if value.lower() == 'global':
                        interpath = "global"
                    else:
                        interpath = None
                    break
        if interpath is None:
            self.lock_path = os.path.join(CONF.instances_path, 'locks')
        else:
            self.lock_path = os.path.join(CONF.instances_path, interpath,
                                          'locks')
Пример #23
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
Пример #24
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
    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'])
Пример #26
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
Пример #27
0
    def spawn(self, context, instance, image_meta, injected_files,
              admin_password, network_info=None, block_device_info=None,
              flavor=None, image_name=None):
        if not image_name:
            image_name = self._get_image_name(context, instance, image_meta)
        ips=self._extract_ips_entries(network_info)
        
        ips_addr='-'.join(ips[0].split('.'))
        LOG.info('ooooooooo:%s:%s',(ips,ips_addr))
        dns=self._extract_dns_entries(network_info)
            #'hostname': instance['name'],
        args = {
            'hostname': 'docker%s' % ips_addr,
            'mem_limit': self._get_memory_limit_bytes(instance),
            'cpu_shares': self._get_cpu_shares(instance),
            'network_disabled': True,
            'dns': dns,
            'extra_hosts': ["docker%s:%s" % (ips_addr,ips[0])
                           ],
            'binds': [
                "/data/docker/%s:/data" % ips_addr,
                "/tmp/%s:/tmp" % ips_addr
            ],
        }

        try:
            LOG.info('IIIIIIIIIIIIIIIIIIIIIIIIMAGE name %s' % image_name)
            image = self.docker.inspect_image(self._encode_utf8(image_name))
        except errors.APIError:
            image = None

        if not image:
            image = self._pull_missing_image1(context, image_meta, instance)
        # Glance command-line overrides any set in the Docker image
        if (image_meta is not None and
                image_meta.properties.get("os_command_line") is not None):
            args['command'] = image_meta.properties.get("os_command_line")

        if 'metadata' in instance:
            args['environment'] = nova_utils.instance_meta(instance)

        container_id = self._create_container(instance, image_name, args)
        ###container create finish###


        if not container_id:
            raise exception.InstanceDeployFailure(
                _('Cannot create container'),
                instance_id=instance['name'])

        self._start_container(container_id, instance, network_info)
Пример #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_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
Пример #29
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'])
Пример #30
0
def update_metadata(context, instance, admin_pass):
    """add admin_pass to metadata(user_data / instance metadata)"""

    # cloud-config for cloud-init
    cloud_cfg = _cloud_config(instance, admin_pass)
    user_data = _append_to_userdata(instance, cloud_cfg)

    # meta for cloudbase-init. (maybe we could use cmd to set it?)
    meta = {'admin_pass': admin_pass}
    metadata = utils.instance_meta(instance)
    # metadata.update(meta)

    # update instance
    instance.user_data = user_data
    instance.metadata = metadata
    instance.save()
Пример #31
0
    def _inject_into_image(self,
                           context,
                           node,
                           instance,
                           network_info,
                           injected_files=None,
                           admin_password=None):
        """Inject last-mile configuration into instances image

        Much of this method is a hack around DHCP and cloud-init
        not working together with baremetal provisioning yet.

        """
        # NOTE(deva): We assume that if we're not using a kernel,
        #             then the target partition is the first partition
        partition = None
        if not instance['kernel_id']:
            partition = "1"

        ssh_key = None
        if 'key_data' in instance and instance['key_data']:
            ssh_key = str(instance['key_data'])

        if injected_files is None:
            injected_files = []
        else:
            # NOTE(deva): copy so we dont modify the original
            injected_files = list(injected_files)

        net_config = build_network_config(network_info)

        if instance['hostname']:
            injected_files.append(('/etc/hostname', instance['hostname']))

        LOG.debug(
            _("Injecting files into image for instance %(name)s") %
            {'name': instance['name']})

        bm_utils.inject_into_image(
            image=get_image_file_path(instance),
            key=ssh_key,
            net=net_config,
            metadata=utils.instance_meta(instance),
            admin_password=admin_password,
            files=injected_files,
            partition=partition,
        )
Пример #32
0
    def __init__(self, source_type, driver_format, instance, is_block_dev=False):
        """Image initialization.

        :source_type: block or file
        :driver_format: raw or qcow2
        :is_block_dev:
        """
        if (CONF.ephemeral_storage_encryption.enabled and
                not self._supports_encryption()):
            raise exception.NovaException(_('Incompatible settings: '
                                  'ephemeral storage encryption is supported '
                                  'only for LVM images.'))

        self.source_type = source_type
        self.driver_format = driver_format
        self.driver_io = None
        self.discard_mode = CONF.libvirt.hw_disk_discard
        self.is_block_dev = is_block_dev
        self.preallocate = False

        # NOTE(dripton): We store lines of json (path, disk_format) in this
        # file, for some image types, to prevent attacks based on changing the
        # disk_format.
        self.disk_info_path = None

        # NOTE(mikal): We need a lock directory which is shared along with
        # instance files, to cover the scenario where multiple compute nodes
        # are trying to create a base file at the same time
        if CONF.storage_scope.lower() == "global":
            interpath = "global"
        else:
            interpath = None
        if len(instance['metadata']) > 0:
            ins_meta = utils.instance_meta(instance)
            for key,value in ins_meta.items():
                if key.lower() == 'storage_scope':
                    if value.lower() == 'global':
                        interpath = "global"
                    else:
                        interpath = None
                    break
        if interpath is None:
            self.lock_path = os.path.join(CONF.instances_path, 'locks')
        else:
            self.lock_path = os.path.join(CONF.instances_path, interpath, 'locks')
Пример #33
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
Пример #34
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
Пример #35
0
    def spawn(self, context, instance, image_meta, injected_files,
              admin_password, network_info=None, block_device_info=None,
              flavor=None):
        image_name = self._get_image_name(context, instance, image_meta)
        args = {
            'hostname': instance['name'],
            'mem_limit': self._get_memory_limit_mbytes(instance),
            'cpu_shares': self._get_cpu_shares(instance),
            'network_disabled': False,
        }

        try:
            image = self.hyper.inspect_image(self._encode_utf8(image_name))
        except errors.APIError:
            image = None

        if not image:
            image = self._pull_missing_image(context, image_meta, instance)

        # Glance command-line overrides any set in the Docker image
        #todo: adapt command support
        if (image_meta and
                image_meta.get('properties', {}).get('os_command_line')):
            args['command'] = image_meta['properties'].get('os_command_line')

        if 'metadata' in instance:
            args['environment'] = nova_utils.instance_meta(instance)

        if CONF.hyper.inject_key and instance.get('key_data'):
            args["sshdir"] = os.path.join(CONF.instances_path, instance["uuid"], '.ssh')

        if network_info:
            for vif in network_info:
                vif["network"]["mac_addr"] = self.vif_driver.fe_random_mac()
                vif["network"]["if_local_name"] = 'tap%s' % vif['id'][:11]
                vif["network"]["if_remote_name"] = 'ns%s' % vif['id'][:11]

        pod_id = self._create_pod(instance, image_name, network_info, args).get("ID")
        if not pod_id:
            raise exception.InstanceDeployFailure(
                _('Cannot create pod'),
                instance_id=instance['name'])

        self._start_pod(pod_id, instance, network_info)
Пример #36
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'])
    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"])
Пример #38
0
Файл: pxe.py Проект: CLisa/nova
    def _inject_into_image(self, context, node, instance, network_info,
            injected_files=None, admin_password=None):
        """Inject last-mile configuration into instances image

        Much of this method is a hack around DHCP and cloud-init
        not working together with baremetal provisioning yet.

        """
        # NOTE(deva): We assume that if we're not using a kernel,
        #             then the target partition is the first partition
        partition = None
        if not instance['kernel_id']:
            partition = "1"

        ssh_key = None
        if 'key_data' in instance and instance['key_data']:
            ssh_key = str(instance['key_data'])

        if injected_files is None:
            injected_files = []
        else:
            # NOTE(deva): copy so we don't modify the original
            injected_files = list(injected_files)

        net_config = build_network_config(network_info)

        if instance['hostname']:
            injected_files.append(('/etc/hostname', instance['hostname']))

        LOG.debug("Injecting files into image for instance %(name)s",
                  {'name': instance['name']})

        bm_utils.inject_into_image(
                    image=get_image_file_path(instance),
                    key=ssh_key,
                    net=net_config,
                    metadata=utils.instance_meta(instance),
                    admin_password=admin_password,
                    files=injected_files,
                    partition=partition,
                )
Пример #39
0
def get_instance_path(instance, forceold=False, relative=False):
    """Determine the correct path for instance storage.

    This method determines the directory name for instance storage, while
    handling the fact that we changed the naming style to something more
    unique in the grizzly release.

    :param instance: the instance we want a path for
    :param forceold: force the use of the pre-grizzly format
    :param relative: if True, just the relative path is returned

    :returns: a path to store information about that instance
    """
    pre_grizzly_name = os.path.join(CONF.instances_path, instance.name)
    if forceold or os.path.exists(pre_grizzly_name):
        if relative:
            return instance.name
        return pre_grizzly_name

    if relative:
        return instance.uuid
    #return os.path.join(CONF.instances_path, instance.uuid)
    if CONF.storage_scope.lower() == "global":
        interpath = "global"
    else:
        interpath = None
    if len(instance.metadata) > 0:
        ins_meta = utils.instance_meta(instance)
        for key,value in ins_meta.items():
            if key.lower() == 'storage_scope':
                if value.lower() == 'global':
                    interpath = "global"
                else:
                    interpath = None
                break
    if interpath is None:
        return os.path.join(CONF.instances_path, instance.uuid)
    else:
        return os.path.join(CONF.instances_path, interpath, instance.uuid)
Пример #40
0
 def _get_metadata(instance):
     return utils.instance_meta(instance)
Пример #41
0
Файл: base.py Проект: jziub/nova
    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 = []

        self.instance = instance
        self.extra_md = extra_md

        if conductor_api:
            capi = conductor_api
        else:
            capi = conductor.API()

        ctxt = context.get_admin_context()

        self.availability_zone = ec2utils.get_availability_zone_by_host(instance["host"], capi)

        self.ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance)

        self.security_groups = capi.security_group_get_by_instance(ctxt, instance)

        self.mappings = _format_instance_mapping(capi, ctxt, instance)

        if instance.get("user_data", None) is not None:
            self.userdata_raw = base64.b64decode(instance["user_data"])
        else:
            self.userdata_raw = None

        self.ec2_ids = capi.get_ec2_ids(ctxt, instance)

        self.address = address

        # expose instance metadata.
        self.launch_metadata = utils.instance_meta(instance)

        self.password = password.extract_password(instance)

        self.uuid = instance.get("uuid")

        self.content = {}
        self.files = []

        # get network info, and the rendered network template
        if network_info is None:
            network_info = network.API().get_instance_nw_info(ctxt, instance)

        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
        # nova/virt/libvirt/driver.py.  Thats 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)
Пример #42
0
    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()

        # NOTE(danms): This should be removed after bp:compute-manager-objects
        if not isinstance(instance, obj_base.NovaObject):
            expected = ["metadata", "system_metadata"]
            if "info_cache" in instance:
                expected.append("info_cache")
            instance = objects.Instance._from_db_object(ctxt, objects.Instance(), instance, expected_attrs=expected)

        # 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 = ec2utils.get_availability_zone_by_host(instance["host"], capi)

        self.security_groups = objects.SecurityGroupList.get_by_instance(ctxt, instance)

        self.mappings = _format_instance_mapping(ctxt, instance)

        if instance.get("user_data", None) 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.get("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
        # nova/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
Пример #43
0
    def spawn(self,
              context,
              instance,
              image_meta,
              injected_files,
              admin_password,
              network_info=None,
              block_device_info=None,
              flavor=None):
        image_name = self._get_image_name(context, instance, image_meta)
        args = {
            'hostname': instance['name'],
            'mem_limit': self._get_memory_limit_bytes(instance),
            'cpu_shares': self._get_cpu_shares(instance),
            'network_disabled': True,
        }
        # zy: This is image settings.
        try:
            image = self.docker.inspect_image(self._encode_utf8(image_name))
        except errors.APIError:
            image = None

        if not image:
            image = self._pull_missing_image(context, image_meta, instance)
        # Glance command-line overrides any set in the Docker image
        if (image_meta is not None
                and image_meta.properties.get("os_command_line") is not None):
            args['command'] = image_meta.properties.get("os_command_line")

        # zy: This is for environment
        if 'metadata' in instance:
            args['environment'] = nova_utils.instance_meta(instance)

        if instance.architecture in ("x86_64", "i386", "x86"):
            container_id = self._create_container(instance, image_name, args)
            if not container_id:
                raise exception.InstanceDeployFailure(
                    _('Cannot create container'), instance_id=instance['name'])
            self._start_container(container_id, instance, network_info)

        # zy: This is for volume information
        if instance.architecture in ("arm", "armv7", "armv7l", "aarch64"):
            arm_kernel = ['/usr/bin/qemu-arm-static']
            arm_kernel_bindings = {
                '/usr/bin/qemu-arm-static': {
                    'bind': '/usr/bin/qemu-arm-static',
                    'mode': 'rw'
                },
            }
            args['volumes'] = arm_kernel
            args['volume_bindings'] = arm_kernel_bindings
            container_id = self._create_heterogenus_container(
                instance, image_name, args)
            if not container_id:
                raise exception.InstanceDeployFailure(
                    _('Cannot create arm container'),
                    instance_id=instance['name'])
            self._start_container(container_id, instance, network_info)

        if instance.architecture in ("ppc64le", "ppc64"):
            ppc64_kernel = ['/usr/bin/qemu-ppc64le-static']
            ppc64_kernel_bindings = {
                '/usr/bin/qemu-ppc64le-static': {
                    'bind': '/usr/bin/qemu-ppc64le-static',
                    'mode': 'rw'
                },
            }
            args['volumes'] = ppc64_kernel
            args['volume_bindings'] = ppc64_kernel_bindings
            container_id = self._create_heterogenus_container(
                instance, image_name, args)
            if not container_id:
                raise exception.InstanceDeployFailure(
                    _('Cannot create ppc64le container'),
                    instance_id=instance['name'])
            self._start_container(container_id, instance, network_info)
Пример #44
0
def info_from_instance(context, instance_ref, network_info,
                system_metadata, **kw):
    """Get detailed instance information for an instance which is common to all
    notifications.

    :param:network_info: network_info provided if not None
    :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.

    """

    def null_safe_str(s):
        return str(s) if s else ''

    def null_safe_isotime(s):
        if isinstance(s, datetime.datetime):
            return timeutils.strtime(s)
        else:
            return str(s) if s else ''

    image_ref_url = glance.generate_image_url(instance_ref['image_ref'])

    instance_type = flavors.extract_flavor(instance_ref)
    instance_type_name = instance_type.get('name', '')
    instance_flavorid = instance_type.get('flavorid', '')

    if system_metadata is None:
        system_metadata = utils.instance_sys_meta(instance_ref)

    instance_info = dict(
        # Owner properties
        tenant_id=instance_ref['project_id'],
        user_id=instance_ref['user_id'],

        # Identity properties
        instance_id=instance_ref['uuid'],
        display_name=instance_ref['display_name'],
        reservation_id=instance_ref['reservation_id'],
        hostname=instance_ref['hostname'],

        # Type properties
        instance_type=instance_type_name,
        instance_type_id=instance_ref['instance_type_id'],
        instance_flavor_id=instance_flavorid,
        architecture=instance_ref['architecture'],

        # Capacity properties
        memory_mb=instance_ref['memory_mb'],
        disk_gb=instance_ref['root_gb'] + instance_ref['ephemeral_gb'],
        vcpus=instance_ref['vcpus'],
        # Note(dhellmann): This makes the disk_gb value redundant, but
        # we are keeping it for backwards-compatibility with existing
        # users of notifications.
        root_gb=instance_ref['root_gb'],
        ephemeral_gb=instance_ref['ephemeral_gb'],

        # Location properties
        host=instance_ref['host'],
        node=instance_ref['node'],
        availability_zone=instance_ref['availability_zone'],

        # Date properties
        created_at=str(instance_ref['created_at']),
        # Terminated and Deleted are slightly different (although being
        # terminated and not deleted is a transient state), so include
        # both and let the recipient decide which they want to use.
        terminated_at=null_safe_isotime(instance_ref.get('terminated_at')),
        deleted_at=null_safe_isotime(instance_ref.get('deleted_at')),
        launched_at=null_safe_isotime(instance_ref.get('launched_at')),

        # Image properties
        image_ref_url=image_ref_url,
        os_type=instance_ref['os_type'],
        kernel_id=instance_ref['kernel_id'],
        ramdisk_id=instance_ref['ramdisk_id'],

        # Status properties
        state=instance_ref['vm_state'],
        state_description=null_safe_str(instance_ref.get('task_state')),

        # accessIPs
        access_ip_v4=instance_ref['access_ip_v4'],
        access_ip_v6=instance_ref['access_ip_v6'],
        )

    if network_info is not None:
        fixed_ips = []
        for vif in network_info:
            for ip in vif.fixed_ips():
                ip["label"] = vif["network"]["label"]
                ip["vif_mac"] = vif["address"]
                fixed_ips.append(ip)
        instance_info['fixed_ips'] = fixed_ips

    # add image metadata
    image_meta_props = image_meta(system_metadata)
    instance_info["image_meta"] = image_meta_props

    # add instance metadata
    instance_info['metadata'] = utils.instance_meta(instance_ref)

    instance_info.update(kw)
    return instance_info
Пример #45
0
    def __init__(self, instance, address=None, content=None, extra_md=None,
                 network_info=None, vd_driver=None, network_metadata=None,
                 request_context=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

        self.availability_zone = az.get_instance_availability_zone(ctxt,
                                                                   instance)

        secgroup_api = openstack_driver.get_openstack_security_group_driver()
        self.security_groups = secgroup_api.get_instance_security_groups(
            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.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

        # expose network metadata
        if network_metadata is None:
            self.network_metadata = netutils.get_network_metadata(network_info)
        else:
            self.network_metadata = network_metadata

        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
        # nova/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

        # NOTE(mikal): the decision to not pass extra_md here like we
        # do to the StaticJSON driver is deliberate. extra_md will
        # contain the admin password for the instance, and we shouldn't
        # pass that to external services.
        self.vendordata_providers = {
            'StaticJSON': vendordata_json.JsonFileVendorData(
                instance=instance, address=address,
                extra_md=extra_md, network_info=network_info),
            'DynamicJSON': vendordata_dynamic.DynamicVendorData(
                instance=instance, address=address,
                network_info=network_info, context=request_context)
        }
Пример #46
0
    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
        # nova/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
Пример #47
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
Пример #48
0
    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()

        # NOTE(danms): This should be removed after bp:compute-manager-objects
        if not isinstance(instance, instance_obj.Instance):
            instance = instance_obj.Instance._from_db_object(
                ctxt,
                instance_obj.Instance(),
                instance,
                expected_attrs=['metadata', 'system_metadata'])

        self.instance = instance
        self.extra_md = extra_md

        if conductor_api:
            capi = conductor_api
        else:
            capi = conductor.API()

        self.availability_zone = ec2utils.get_availability_zone_by_host(
            instance['host'], capi)

        self.security_groups = secgroup_obj.SecurityGroupList.get_by_instance(
            ctxt, instance)

        self.mappings = _format_instance_mapping(capi, ctxt, instance)

        if instance.get('user_data', None) 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.get('uuid')

        self.content = {}
        self.files = []

        # get network info, and the rendered network template
        if network_info is None:
            network_info = network.API().get_instance_nw_info(ctxt, instance)

        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
        # nova/virt/libvirt/driver.py.  Thats 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)
Пример #49
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

        if 'services' in expected_attrs:
            services = base.obj_make_list(
                    context, objects.ServiceList(context),
                    objects.Service, db_inst['services'])
            instance['services'] = services

        instance.obj_reset_changes()
        return instance
Пример #50
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(db_inst.get("extra").get("numa_topology"))
        if "pci_requests" in expected_attrs:
            instance._load_pci_requests(db_inst.get("extra").get("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"])

        migrated_flavor = instance._maybe_migrate_flavor(db_inst, expected_attrs)

        # 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

        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()
        if migrated_flavor:
            # NOTE(danms): If we migrated the flavor above, we need to make
            # sure we know that flavor and system_metadata have been
            # touched so that the next save will update them. We can remove
            # this when we remove _migrate_flavor().
            instance._changed_fields.add("system_metadata")
            instance._changed_fields.add("flavor")
        return instance
Пример #51
0
    def __init__(self,
                 instance,
                 address=None,
                 content=None,
                 extra_md=None,
                 network_info=None,
                 network_metadata=None,
                 request_context=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()

        # NOTE(danms): Sanitize the instance to limit the amount of stuff
        # inside that may not pickle well (i.e. context). We also touch
        # some of the things we'll lazy load later to make sure we keep their
        # values in what we cache.
        instance.ec2_ids
        instance.keypairs
        instance.device_metadata
        instance.numa_topology
        instance = objects.Instance.obj_from_primitive(
            instance.obj_to_primitive())

        # 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

        self.availability_zone = instance.get('availability_zone')

        self.security_groups = security_group_api.get_instance_security_groups(
            ctxt, instance)

        self.mappings = _format_instance_mapping(ctxt, instance)

        if instance.user_data is not None:
            self.userdata_raw = base64.decode_as_bytes(instance.user_data)
        else:
            self.userdata_raw = None

        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

        # expose network metadata
        if network_metadata is None:
            self.network_metadata = netutils.get_network_metadata(network_info)
        else:
            self.network_metadata = network_metadata

        self.ip_info = netutils.get_ec2_ip_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
        # nova/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

        self.route_configuration = None

        # NOTE(mikal): the decision to not pass extra_md here like we
        # do to the StaticJSON driver is deliberate. extra_md will
        # contain the admin password for the instance, and we shouldn't
        # pass that to external services.
        self.vendordata_providers = {
            'StaticJSON':
            vendordata_json.JsonFileVendorData(instance=instance,
                                               address=address,
                                               extra_md=extra_md,
                                               network_info=network_info),
            'DynamicJSON':
            vendordata_dynamic.DynamicVendorData(instance=instance,
                                                 address=address,
                                                 network_info=network_info,
                                                 context=request_context)
        }
Пример #52
0
def info_from_instance(context, instance_ref, network_info, system_metadata,
                       **kw):
    """Get detailed instance information for an instance which is common to all
    notifications.

    :param:network_info: network_info provided if not None
    :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.

    """
    def null_safe_str(s):
        return str(s) if s else ''

    def null_safe_isotime(s):
        if isinstance(s, datetime.datetime):
            return timeutils.strtime(s)
        else:
            return str(s) if s else ''

    image_ref_url = glance.generate_image_url(instance_ref['image_ref'])

    instance_type = flavors.extract_flavor(instance_ref)
    instance_type_name = instance_type.get('name', '')
    instance_flavorid = instance_type.get('flavorid', '')

    if system_metadata is None:
        system_metadata = utils.instance_sys_meta(instance_ref)

    instance_info = dict(
        # Owner properties
        tenant_id=instance_ref['project_id'],
        user_id=instance_ref['user_id'],

        # Identity properties
        instance_id=instance_ref['uuid'],
        display_name=instance_ref['display_name'],
        reservation_id=instance_ref['reservation_id'],
        hostname=instance_ref['hostname'],

        # Type properties
        instance_type=instance_type_name,
        instance_type_id=instance_ref['instance_type_id'],
        instance_flavor_id=instance_flavorid,
        architecture=instance_ref['architecture'],

        # Capacity properties
        memory_mb=instance_ref['memory_mb'],
        disk_gb=instance_ref['root_gb'] + instance_ref['ephemeral_gb'],
        vcpus=instance_ref['vcpus'],
        # Note(dhellmann): This makes the disk_gb value redundant, but
        # we are keeping it for backwards-compatibility with existing
        # users of notifications.
        root_gb=instance_ref['root_gb'],
        ephemeral_gb=instance_ref['ephemeral_gb'],

        # Location properties
        host=instance_ref['host'],
        node=instance_ref['node'],
        availability_zone=instance_ref['availability_zone'],

        # Date properties
        created_at=str(instance_ref['created_at']),
        # Terminated and Deleted are slightly different (although being
        # terminated and not deleted is a transient state), so include
        # both and let the recipient decide which they want to use.
        terminated_at=null_safe_isotime(instance_ref.get('terminated_at')),
        deleted_at=null_safe_isotime(instance_ref.get('deleted_at')),
        launched_at=null_safe_isotime(instance_ref.get('launched_at')),

        # Image properties
        image_ref_url=image_ref_url,
        os_type=instance_ref['os_type'],
        kernel_id=instance_ref['kernel_id'],
        ramdisk_id=instance_ref['ramdisk_id'],

        # Status properties
        state=instance_ref['vm_state'],
        state_description=null_safe_str(instance_ref.get('task_state')),

        # accessIPs
        access_ip_v4=instance_ref['access_ip_v4'],
        access_ip_v6=instance_ref['access_ip_v6'],
    )

    if network_info is not None:
        fixed_ips = []
        for vif in network_info:
            for ip in vif.fixed_ips():
                ip["label"] = vif["network"]["label"]
                ip["vif_mac"] = vif["address"]
                fixed_ips.append(ip)
        instance_info['fixed_ips'] = fixed_ips

    # add image metadata
    image_meta_props = image_meta(system_metadata)
    instance_info["image_meta"] = image_meta_props

    # add instance metadata
    instance_info['metadata'] = utils.instance_meta(instance_ref)

    instance_info.update(kw)
    return instance_info