コード例 #1
0
ファイル: resource_tracker.py プロジェクト: bopopescu/jacket
    def _get_usage_dict(self, object_or_dict, **updates):
        """Make a usage dict _update methods expect.

        Accepts a dict or an Instance or Flavor object, and a set of updates.
        Converts the object to a dict and applies the updates.

        :param object_or_dict: instance or flavor as an object or just a dict
        :param updates: key-value pairs to update the passed object.
                        Currently only considers 'numa_topology', all other
                        keys are ignored.

        :returns: a dict with all the information from object_or_dict updated
                  with updates
        """
        usage = {}
        if isinstance(object_or_dict, objects.Instance):
            usage = obj_base.obj_to_primitive(object_or_dict)
        elif isinstance(object_or_dict, objects.Flavor):
            usage = obj_base.obj_to_primitive(object_or_dict)
        else:
            usage.update(object_or_dict)

        for key in ('numa_topology', ):
            if key in updates:
                usage[key] = updates[key]
        return usage
コード例 #2
0
ファイル: resource_tracker.py プロジェクト: HybridF5/jacket
    def _get_usage_dict(self, object_or_dict, **updates):
        """Make a usage dict _update methods expect.

        Accepts a dict or an Instance or Flavor object, and a set of updates.
        Converts the object to a dict and applies the updates.

        :param object_or_dict: instance or flavor as an object or just a dict
        :param updates: key-value pairs to update the passed object.
                        Currently only considers 'numa_topology', all other
                        keys are ignored.

        :returns: a dict with all the information from object_or_dict updated
                  with updates
        """
        usage = {}
        if isinstance(object_or_dict, objects.Instance):
            usage = obj_base.obj_to_primitive(object_or_dict)
        elif isinstance(object_or_dict, objects.Flavor):
            usage = obj_base.obj_to_primitive(object_or_dict)
        else:
            usage.update(object_or_dict)

        for key in ('numa_topology',):
            if key in updates:
                usage[key] = updates[key]
        return usage
コード例 #3
0
    def build_instances(self, ctxt, **kwargs):
        """Build instances."""
        build_inst_kwargs = kwargs
        instances = build_inst_kwargs['instances']
        build_inst_kwargs['image'] = jsonutils.to_primitive(
            build_inst_kwargs['image'])

        version = '1.34'
        if self.client.can_send_version('1.34'):
            build_inst_kwargs.pop('legacy_bdm', None)
        else:
            bdm_p = objects_base.obj_to_primitive(
                build_inst_kwargs['block_device_mapping'])
            build_inst_kwargs['block_device_mapping'] = bdm_p
            version = '1.32'
        if not self.client.can_send_version('1.32'):
            instances_p = [jsonutils.to_primitive(inst) for inst in instances]
            build_inst_kwargs['instances'] = instances_p
            version = '1.30'
        if not self.client.can_send_version('1.30'):
            if 'filter_properties' in build_inst_kwargs:
                filter_properties = build_inst_kwargs['filter_properties']
                flavor = filter_properties['instance_type']
                flavor_p = objects_base.obj_to_primitive(flavor)
                filter_properties['instance_type'] = flavor_p
            version = '1.8'
        cctxt = self.client.prepare(version=version)
        cctxt.cast(ctxt,
                   'build_instances',
                   build_inst_kwargs=build_inst_kwargs)
コード例 #4
0
 def migrate_server(self, context, instance, scheduler_hint, live, rebuild,
               flavor, block_migration, disk_over_commit,
               reservations=None, clean_shutdown=True, request_spec=None):
     kw = {'instance': instance, 'scheduler_hint': scheduler_hint,
           'live': live, 'rebuild': rebuild, 'flavor': flavor,
           'block_migration': block_migration,
           'disk_over_commit': disk_over_commit,
           'reservations': reservations,
           'clean_shutdown': clean_shutdown,
           'request_spec': request_spec,
           }
     version = '1.13'
     if not self.client.can_send_version(version):
         del kw['request_spec']
         version = '1.11'
     if not self.client.can_send_version(version):
         del kw['clean_shutdown']
         version = '1.10'
     if not self.client.can_send_version(version):
         kw['flavor'] = objects_base.obj_to_primitive(flavor)
         version = '1.6'
     if not self.client.can_send_version(version):
         kw['instance'] = jsonutils.to_primitive(
                 objects_base.obj_to_primitive(instance))
         version = '1.4'
     cctxt = self.client.prepare(version=version)
     return cctxt.call(context, 'migrate_server', **kw)
コード例 #5
0
    def build_instances(self, context, instances, image, filter_properties,
            admin_password, injected_files, requested_networks,
            security_groups, block_device_mapping, legacy_bdm=True):
        image_p = jsonutils.to_primitive(image)
        version = '1.10'
        if not self.client.can_send_version(version):
            version = '1.9'
            if 'instance_type' in filter_properties:
                flavor = filter_properties['instance_type']
                flavor_p = objects_base.obj_to_primitive(flavor)
                filter_properties = dict(filter_properties,
                                         instance_type=flavor_p)
        kw = {'instances': instances, 'image': image_p,
               'filter_properties': filter_properties,
               'admin_password': admin_password,
               'injected_files': injected_files,
               'requested_networks': requested_networks,
               'security_groups': security_groups}
        if not self.client.can_send_version(version):
            version = '1.8'
            kw['requested_networks'] = kw['requested_networks'].as_tuples()
        if not self.client.can_send_version('1.7'):
            version = '1.5'
            bdm_p = objects_base.obj_to_primitive(block_device_mapping)
            kw.update({'block_device_mapping': bdm_p,
                       'legacy_bdm': legacy_bdm})

        cctxt = self.client.prepare(version=version)
        cctxt.cast(context, 'build_instances', **kw)
コード例 #6
0
ファイル: test_flavors.py プロジェクト: HybridF5/jacket
    def _test_extract_flavor(self, prefix):
        instance_type = flavors.get_default_flavor()
        instance_type_p = obj_base.obj_to_primitive(instance_type)

        metadata = {}
        flavors.save_flavor_info(metadata, instance_type, prefix)
        instance = {'system_metadata': self._dict_to_metadata(metadata)}
        _instance_type = flavors.extract_flavor(instance, prefix)
        _instance_type_p = obj_base.obj_to_primitive(_instance_type)

        props = flavors.system_metadata_flavor_props.keys()
        for key in list(instance_type_p.keys()):
            if key not in props:
                del instance_type_p[key]

        self.assertEqual(instance_type_p, _instance_type_p)
コード例 #7
0
ファイル: rpcapi.py プロジェクト: bopopescu/jacket
 def set_network_host(self, ctxt, network_ref):
     version = '1.15'
     if not self.client.can_send_version(version):
         version = '1.0'
         network_ref = objects_base.obj_to_primitive(network_ref)
     cctxt = self.client.prepare(version=version)
     return cctxt.call(ctxt, 'set_network_host', network_ref=network_ref)
コード例 #8
0
ファイル: resource_tracker.py プロジェクト: bopopescu/jacket
    def _update_usage_from_instance(self, context, instance, is_removed=False):
        """Update usage for a single instance."""

        uuid = instance['uuid']
        is_new_instance = uuid not in self.tracked_instances
        is_removed_instance = (is_removed or instance['vm_state']
                               in vm_states.ALLOW_RESOURCE_REMOVAL)

        if is_new_instance:
            self.tracked_instances[uuid] = obj_base.obj_to_primitive(instance)
            sign = 1

        if is_removed_instance:
            self.tracked_instances.pop(uuid)
            sign = -1

        self.stats.update_stats_for_instance(instance, is_removed_instance)

        # if it's a new or deleted instance:
        if is_new_instance or is_removed_instance:
            if self.pci_tracker:
                self.pci_tracker.update_pci_for_instance(context,
                                                         instance,
                                                         sign=sign)
            # new instance, update compute node resource usage:
            self._update_usage(instance, sign=sign)

        self.compute_node.current_workload = self.stats.calculate_workload()
        if self.pci_tracker:
            obj = self.pci_tracker.stats.to_device_pools_obj()
            self.compute_node.pci_device_pools = obj
        else:
            self.compute_node.pci_device_pools = objects.PciDevicePoolList()
コード例 #9
0
ファイル: resource_tracker.py プロジェクト: HybridF5/jacket
    def _update_usage_from_instance(self, context, instance, is_removed=False):
        """Update usage for a single instance."""

        uuid = instance['uuid']
        is_new_instance = uuid not in self.tracked_instances
        is_removed_instance = (
                is_removed or
                instance['vm_state'] in vm_states.ALLOW_RESOURCE_REMOVAL)

        if is_new_instance:
            self.tracked_instances[uuid] = obj_base.obj_to_primitive(instance)
            sign = 1

        if is_removed_instance:
            self.tracked_instances.pop(uuid)
            sign = -1

        self.stats.update_stats_for_instance(instance, is_removed_instance)

        # if it's a new or deleted instance:
        if is_new_instance or is_removed_instance:
            if self.pci_tracker:
                self.pci_tracker.update_pci_for_instance(context,
                                                         instance,
                                                         sign=sign)
            # new instance, update compute node resource usage:
            self._update_usage(instance, sign=sign)

        self.compute_node.current_workload = self.stats.calculate_workload()
        if self.pci_tracker:
            obj = self.pci_tracker.stats.to_device_pools_obj()
            self.compute_node.pci_device_pools = obj
        else:
            self.compute_node.pci_device_pools = objects.PciDevicePoolList()
コード例 #10
0
 def instance_destroy_at_top(self, ctxt, instance):
     """Destroy instance at API level."""
     version = '1.35'
     if not self.client.can_send_version('1.35'):
         instance = objects_base.obj_to_primitive(instance)
         version = '1.34'
     cctxt = self.client.prepare(version=version)
     cctxt.cast(ctxt, 'instance_destroy_at_top', instance=instance)
コード例 #11
0
ファイル: test_notifications.py プロジェクト: HybridF5/jacket
    def test_send_on_task_change(self):

        old = obj_base.obj_to_primitive(self.instance)
        old['task_state'] = None
        # pretend we just transitioned to task SPAWNING:
        self.instance.task_state = task_states.SPAWNING
        notifications.send_update(self.context, old, self.instance)

        self.assertEqual(1, len(fake_notifier.NOTIFICATIONS))
コード例 #12
0
ファイル: rpcapi.py プロジェクト: bopopescu/jacket
 def refresh_instance_security_rules(self, ctxt, host, instance):
     version = '4.4'
     if not self.client.can_send_version(version):
         version = '4.0'
         instance = objects_base.obj_to_primitive(instance)
     cctxt = self.client.prepare(server=_compute_host(None, instance),
             version=version)
     cctxt.cast(ctxt, 'refresh_instance_security_rules',
                instance=instance)
コード例 #13
0
 def bulk_create(self, context, fixed_ips):
     ips = []
     for fixedip in fixed_ips:
         ip = obj_base.obj_to_primitive(fixedip)
         if 'id' in ip:
             raise exception.ObjectActionError(action='create',
                                               reason='already created')
         ips.append(ip)
     db.fixed_ip_bulk_create(context, ips)
コード例 #14
0
ファイル: fixed_ip.py プロジェクト: HybridF5/jacket
 def bulk_create(self, context, fixed_ips):
     ips = []
     for fixedip in fixed_ips:
         ip = obj_base.obj_to_primitive(fixedip)
         if 'id' in ip:
             raise exception.ObjectActionError(action='create',
                                               reason='already created')
         ips.append(ip)
     db.fixed_ip_bulk_create(context, ips)
コード例 #15
0
 def instance_info_cache_update_at_top(self, ctxt, instance_info_cache):
     """Broadcast up that an instance's info_cache has changed."""
     version = '1.35'
     instance = objects.Instance(uuid=instance_info_cache.instance_uuid,
                                 info_cache=instance_info_cache)
     if not self.client.can_send_version('1.35'):
         instance = objects_base.obj_to_primitive(instance)
         version = '1.34'
     cctxt = self.client.prepare(version=version)
     cctxt.cast(ctxt, 'instance_update_at_top', instance=instance)
コード例 #16
0
ファイル: test_notifications.py プロジェクト: HybridF5/jacket
    def test_send_on_vm_change(self):
        old = obj_base.obj_to_primitive(self.instance)
        old['vm_state'] = None
        # pretend we just transitioned to ACTIVE:
        self.instance.vm_state = vm_states.ACTIVE
        notifications.send_update(self.context, old, self.instance)

        self.assertEqual(1, len(fake_notifier.NOTIFICATIONS))
        # service name should default to 'compute'
        notif = fake_notifier.NOTIFICATIONS[0]
        self.assertEqual('compute.testhost', notif.publisher_id)
コード例 #17
0
ファイル: utils.py プロジェクト: bopopescu/jacket
def build_request_spec(ctxt, image, instances, instance_type=None):
    """Build a request_spec for the scheduler.

    The request_spec assumes that all instances to be scheduled are the same
    type.
    """
    instance = instances[0]
    if instance_type is None:
        if isinstance(instance, obj_instance.Instance):
            instance_type = instance.get_flavor()
        else:
            instance_type = flavors.extract_flavor(instance)

    if isinstance(instance, obj_instance.Instance):
        instance = obj_base.obj_to_primitive(instance)
        # obj_to_primitive doesn't copy this enough, so be sure
        # to detach our metadata blob because we modify it below.
        instance['system_metadata'] = dict(instance.get('system_metadata', {}))

    if isinstance(instance_type, objects.Flavor):
        instance_type = obj_base.obj_to_primitive(instance_type)
        # NOTE(danms): Replicate this old behavior because the
        # scheduler RPC interface technically expects it to be
        # there. Remove this when we bump the scheduler RPC API to
        # v5.0
        try:
            flavors.save_flavor_info(instance.get('system_metadata', {}),
                                     instance_type)
        except KeyError:
            # If the flavor isn't complete (which is legit with a
            # flavor object, just don't put it in the request spec
            pass

    request_spec = {
            'image': image or {},
            'instance_properties': instance,
            'instance_type': instance_type,
            'num_instances': len(instances)}
    return jsonutils.to_primitive(request_spec)
コード例 #18
0
ファイル: rpcapi.py プロジェクト: bopopescu/jacket
 def resize_instance(self, ctxt, instance, migration, image, instance_type,
                     reservations=None, clean_shutdown=True):
     msg_args = {'instance': instance, 'migration': migration,
                 'image': image, 'reservations': reservations,
                 'instance_type': instance_type,
                 'clean_shutdown': clean_shutdown,
     }
     version = '4.1'
     if not self.client.can_send_version(version):
         msg_args['instance_type'] = objects_base.obj_to_primitive(
                                         instance_type)
         version = '4.0'
     cctxt = self.client.prepare(server=_compute_host(None, instance),
             version=version)
     cctxt.cast(ctxt, 'resize_instance', **msg_args)
コード例 #19
0
    def bdm_update_or_create_at_top(self, ctxt, bdm, create=None):
        """Create or update a block device mapping in API cells.  If
        create is True, only try to create.  If create is None, try to
        update but fall back to create.  If create is False, only attempt
        to update.  This maps to compute-conductor's behavior.
        """
        if self.client.can_send_version('1.28'):
            version = '1.28'
        else:
            version = '1.10'
            bdm = objects_base.obj_to_primitive(bdm)
        cctxt = self.client.prepare(version=version)

        try:
            cctxt.cast(ctxt,
                       'bdm_update_or_create_at_top',
                       bdm=bdm,
                       create=create)
        except Exception:
            LOG.exception(_LE("Failed to notify cells of BDM update/create."))
コード例 #20
0
ファイル: test_migrate.py プロジェクト: HybridF5/jacket
 def setUp(self):
     super(MigrationTaskTestCase, self).setUp()
     self.user_id = 'fake'
     self.project_id = 'fake'
     self.context = FakeContext(self.user_id, self.project_id)
     inst = fake_instance.fake_db_instance(image_ref='image_ref')
     self.instance = compute.Instance._from_db_object(
         self.context, compute.Instance(), inst, [])
     self.instance.system_metadata = {'image_hw_disk_bus': 'scsi'}
     self.flavor = fake_flavor.fake_flavor_obj(self.context)
     self.flavor.extra_specs = {'extra_specs': 'fake'}
     self.request_spec = {'instance_type':
                              obj_base.obj_to_primitive(self.flavor),
                          'instance_properties': {},
                          'image': 'image'}
     self.hosts = [dict(host='host1', nodename=None, limits={})]
     self.filter_properties = {'limits': {}, 'retry': {'num_attempts': 1,
                               'hosts': [['host1', None]]}}
     self.reservations = []
     self.clean_shutdown = True
コード例 #21
0
ファイル: rpcapi.py プロジェクト: bopopescu/jacket
 def prep_resize(self, ctxt, image, instance, instance_type, host,
                 reservations=None, request_spec=None,
                 filter_properties=None, node=None,
                 clean_shutdown=True):
     image_p = jsonutils.to_primitive(image)
     msg_args = {'instance': instance,
                 'instance_type': instance_type,
                 'image': image_p,
                 'reservations': reservations,
                 'request_spec': request_spec,
                 'filter_properties': filter_properties,
                 'node': node,
                 'clean_shutdown': clean_shutdown}
     version = '4.1'
     if not self.client.can_send_version(version):
         version = '4.0'
         msg_args['instance_type'] = objects_base.obj_to_primitive(
                                         instance_type)
     cctxt = self.client.prepare(server=host, version=version)
     cctxt.cast(ctxt, 'prep_resize', **msg_args)
コード例 #22
0
ファイル: scheduler.py プロジェクト: bopopescu/jacket
    def _build_instances(self, message, target_cells, instance_uuids,
                         build_inst_kwargs):
        """Attempt to build instance(s) or send msg to child cell."""
        ctxt = message.ctxt
        instance_properties = obj_base.obj_to_primitive(
            build_inst_kwargs['instances'][0])
        filter_properties = build_inst_kwargs['filter_properties']
        instance_type = filter_properties['instance_type']
        image = build_inst_kwargs['image']
        security_groups = build_inst_kwargs['security_groups']
        block_device_mapping = build_inst_kwargs['block_device_mapping']

        LOG.debug("Building instances with routing_path=%(routing_path)s",
                  {'routing_path': message.routing_path})

        for target_cell in target_cells:
            try:
                if target_cell.is_me:
                    # Need to create instance DB entries as the conductor
                    # expects that the instance(s) already exists.
                    instances = self._create_instances_here(
                        ctxt, instance_uuids, instance_properties,
                        instance_type, image, security_groups,
                        block_device_mapping)
                    build_inst_kwargs['instances'] = instances
                    # Need to record the create action in the db as the
                    # conductor expects it to already exist.
                    self._create_action_here(ctxt, instance_uuids)
                    self.compute_task_api.build_instances(
                        ctxt, **build_inst_kwargs)
                    return
                self.msg_runner.build_instances(ctxt, target_cell,
                                                build_inst_kwargs)
                return
            except Exception:
                LOG.exception(_LE("Couldn't communicate with cell '%s'"),
                              target_cell.name)
        # FIXME(comstud): Would be nice to kick this back up so that
        # the parent cell could retry, if we had a parent.
        LOG.error(_LE("Couldn't communicate with any cells"))
        raise exception.NoCellsAvailable()
コード例 #23
0
    def _output(self, req, migrations_obj, add_link=False):
        """Returns the desired output of the API from an object.

        From a MigrationsList's object this method returns a list of
        primitive objects with the only necessary fields.
        """
        detail_keys = [
            'memory_total', 'memory_processed', 'memory_remaining',
            'disk_total', 'disk_processed', 'disk_remaining'
        ]

        # TODO(Shaohe Feng) we should share the in-progress list.
        live_migration_in_progress = [
            'queued', 'preparing', 'running', 'post-migrating'
        ]

        # Note(Shaohe Feng): We need to leverage the oslo.versionedobjects.
        # Then we can pass the target version to it's obj_to_primitive.
        objects = obj_base.obj_to_primitive(migrations_obj)
        objects = [x for x in objects if not x['hidden']]
        for obj in objects:
            del obj['deleted']
            del obj['deleted_at']
            del obj['hidden']
            if 'memory_total' in obj:
                for key in detail_keys:
                    del obj[key]
            # NOTE(Shaohe Feng) above version 2.23, add migration_type for all
            # kinds of migration, but we only add links just for in-progress
            # live-migration.
            if add_link and obj['migration_type'] == "live-migration" and (
                    obj["status"] in live_migration_in_progress):
                obj["links"] = self._view_builder._get_links(
                    req, obj["id"],
                    self._collection_name % obj['instance_uuid'])
            elif add_link is False:
                del obj['migration_type']

        return objects
コード例 #24
0
ファイル: migrations.py プロジェクト: bopopescu/jacket
def output(migrations_obj):
    """Returns the desired output of the API from an object.

    From a MigrationsList's object this method returns a list of
    primitive objects with the only necessary fields.
    """
    detail_keys = ['memory_total', 'memory_processed', 'memory_remaining',
                   'disk_total', 'disk_processed', 'disk_remaining']
    # Note(Shaohe Feng): We need to leverage the oslo.versionedobjects.
    # Then we can pass the target version to it's obj_to_primitive.
    objects = obj_base.obj_to_primitive(migrations_obj)
    objects = [x for x in objects if not x['hidden']]
    for obj in objects:
        del obj['deleted']
        del obj['deleted_at']
        del obj['migration_type']
        del obj['hidden']
        if 'memory_total' in obj:
            for key in detail_keys:
                del obj[key]

    return objects
コード例 #25
0
ファイル: test_rpcapi.py プロジェクト: HybridF5/jacket
 def test_set_network_host_network_object_to_primitive(self):
     # Tests that the network object is converted to a primitive if it
     # can't send version 1.15.
     ctxt = context.RequestContext('fake_user', 'fake_project')
     network = fake_network.fake_network_obj(ctxt)
     network_dict = objects_base.obj_to_primitive(network)
     rpcapi = network_rpcapi.NetworkAPI()
     call_mock = mock.Mock()
     cctxt_mock = mock.Mock(call=call_mock)
     with test.nested(
         mock.patch.object(rpcapi.client, 'can_send_version',
                           return_value=False),
         mock.patch.object(rpcapi.client, 'prepare',
                           return_value=cctxt_mock)
     ) as (
         can_send_mock, prepare_mock
     ):
         rpcapi.set_network_host(ctxt, network)
     # assert our mocks were called as expected
     can_send_mock.assert_called_once_with('1.15')
     prepare_mock.assert_called_once_with(version='1.0')
     call_mock.assert_called_once_with(ctxt, 'set_network_host',
                                       network_ref=network_dict)
コード例 #26
0
ファイル: migrations.py プロジェクト: HybridF5/jacket
    def _output(self, req, migrations_obj, add_link=False):
        """Returns the desired output of the API from an object.

        From a MigrationsList's object this method returns a list of
        primitive objects with the only necessary fields.
        """
        detail_keys = ['memory_total', 'memory_processed', 'memory_remaining',
                       'disk_total', 'disk_processed', 'disk_remaining']

        # TODO(Shaohe Feng) we should share the in-progress list.
        live_migration_in_progress = ['queued', 'preparing',
                                      'running', 'post-migrating']

        # Note(Shaohe Feng): We need to leverage the oslo.versionedobjects.
        # Then we can pass the target version to it's obj_to_primitive.
        objects = obj_base.obj_to_primitive(migrations_obj)
        objects = [x for x in objects if not x['hidden']]
        for obj in objects:
            del obj['deleted']
            del obj['deleted_at']
            del obj['hidden']
            if 'memory_total' in obj:
                for key in detail_keys:
                    del obj[key]
            # NOTE(Shaohe Feng) above version 2.23, add migration_type for all
            # kinds of migration, but we only add links just for in-progress
            # live-migration.
            if add_link and obj['migration_type'] == "live-migration" and (
                    obj["status"] in live_migration_in_progress):
                obj["links"] = self._view_builder._get_links(
                    req, obj["id"],
                    self._collection_name % obj['instance_uuid'])
            elif add_link is False:
                del obj['migration_type']

        return objects
コード例 #27
0
ファイル: request_spec.py プロジェクト: HybridF5/jacket
 def _to_legacy_image(self):
     return base.obj_to_primitive(self.image) if (
         self.obj_attr_is_set('image') and self.image) else {}
コード例 #28
0
ファイル: manager.py プロジェクト: HybridF5/jacket
 def bdm_update_or_create_at_top(self, ctxt, bdm, create=None):
     """BDM was created/updated in this cell.  Tell the API cells."""
     # TODO(ndipanov): Move inter-cell RPC to use objects
     bdm = base_obj.obj_to_primitive(bdm)
     self.msg_runner.bdm_update_or_create_at_top(ctxt, bdm, create=create)
コード例 #29
0
ファイル: pci_device_pool.py プロジェクト: bopopescu/jacket
 def to_dict(self):
     pci_pool = base.obj_to_primitive(self)
     tags = pci_pool.pop('tags', {})
     for k, v in six.iteritems(tags):
         pci_pool[k] = v
     return pci_pool
コード例 #30
0
 def _to_legacy_image(self):
     return base.obj_to_primitive(self.image) if (
         self.obj_attr_is_set('image') and self.image) else {}
コード例 #31
0
 def bdm_update_or_create_at_top(self, ctxt, bdm, create=None):
     """BDM was created/updated in this cell.  Tell the API cells."""
     # TODO(ndipanov): Move inter-cell RPC to use objects
     bdm = base_obj.obj_to_primitive(bdm)
     self.msg_runner.bdm_update_or_create_at_top(ctxt, bdm, create=create)