diff --git a/nova/objects/request_spec.py b/nova/objects/request_spec.py index 47462ef3e272..67dda6eefd41 100644 --- a/nova/objects/request_spec.py +++ b/nova/objects/request_spec.py @@ -11,13 +11,14 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. + import copy import itertools from oslo_log import log as logging from oslo_serialization import jsonutils from oslo_utils import versionutils - +import six from nova.db.sqlalchemy import api as db from nova.db.sqlalchemy import api_models @@ -26,7 +27,6 @@ from nova import objects from nova.objects import base from nova.objects import fields from nova.objects import instance as obj_instance -from nova.virt import hardware LOG = logging.getLogger(__name__) @@ -215,11 +215,11 @@ class RequestSpec(base.NovaObject): self.pci_requests = pci_requests def _from_instance_numa_topology(self, numa_topology): - if isinstance(numa_topology, dict): - self.numa_topology = hardware.instance_topology_from_instance( - dict(numa_topology=numa_topology)) - else: - self.numa_topology = numa_topology + if isinstance(numa_topology, six.string_types): + numa_topology = objects.InstanceNUMATopology.obj_from_primitive( + jsonutils.loads(numa_topology)) + + self.numa_topology = numa_topology def _from_flavor(self, flavor): if isinstance(flavor, objects.Flavor): diff --git a/nova/tests/unit/objects/test_request_spec.py b/nova/tests/unit/objects/test_request_spec.py index 9c754abf90df..d6a00d7d205c 100644 --- a/nova/tests/unit/objects/test_request_spec.py +++ b/nova/tests/unit/objects/test_request_spec.py @@ -152,15 +152,14 @@ class _TestRequestSpecObject(object): user_id=fakes.FAKE_USER_ID, availability_zone='nova', pci_requests=None, - numa_topology={'cells': [{'id': 1, 'cpuset': ['1'], 'memory': 8192, - 'pagesize': None, 'cpu_topology': None, - 'cpu_pinning_raw': None}]}) + numa_topology=fake_request_spec.INSTANCE_NUMA_TOPOLOGY, + ) spec = objects.RequestSpec() spec._from_instance(instance) self.assertIsInstance(spec.numa_topology, objects.InstanceNUMATopology) cells = spec.numa_topology.cells - self.assertEqual(1, len(cells)) + self.assertEqual(2, len(cells)) self.assertIsInstance(cells[0], objects.InstanceNUMACell) def test_from_flavor_as_object(self): diff --git a/nova/virt/hardware.py b/nova/virt/hardware.py index c71b74ec0ee1..e77fc66b3a83 100644 --- a/nova/virt/hardware.py +++ b/nova/virt/hardware.py @@ -18,18 +18,15 @@ import itertools import math from oslo_log import log as logging -from oslo_serialization import jsonutils from oslo_utils import strutils from oslo_utils import units import six import nova.conf -from nova import context from nova import exception from nova.i18n import _ from nova import objects from nova.objects import fields -from nova.objects import instance as obj_instance CONF = nova.conf.CONF @@ -1933,75 +1930,3 @@ def numa_usage_from_instances(host, instances, free=False): cells.append(newcell) return objects.NUMATopology(cells=cells) - - -# TODO(ndipanov): Remove when all code paths are using objects -def instance_topology_from_instance(instance): - """Extract numa topology from myriad instance representations. - - Until the RPC version is bumped to 5.x, an instance may be - represented as a dict, a db object, or an actual Instance object. - Identify the type received and return either an instance of - objects.InstanceNUMATopology if the instance's NUMA topology is - available, else None. - - :param host: nova.objects.ComputeNode instance, or a db object or - dict - - :returns: An instance of objects.NUMATopology or None - """ - if isinstance(instance, obj_instance.Instance): - # NOTE (ndipanov): This may cause a lazy-load of the attribute - instance_numa_topology = instance.numa_topology - else: - if 'numa_topology' in instance: - instance_numa_topology = instance['numa_topology'] - elif 'uuid' in instance: - try: - instance_numa_topology = ( - objects.InstanceNUMATopology.get_by_instance_uuid( - context.get_admin_context(), instance['uuid']) - ) - except exception.NumaTopologyNotFound: - instance_numa_topology = None - else: - instance_numa_topology = None - - if instance_numa_topology: - if isinstance(instance_numa_topology, six.string_types): - instance_numa_topology = ( - objects.InstanceNUMATopology.obj_from_primitive( - jsonutils.loads(instance_numa_topology))) - - elif isinstance(instance_numa_topology, dict): - # NOTE (ndipanov): A horrible hack so that we can use - # this in the scheduler, since the - # InstanceNUMATopology object is serialized raw using - # the obj_base.obj_to_primitive, (which is buggy and - # will give us a dict with a list of InstanceNUMACell - # objects), and then passed to jsonutils.to_primitive, - # which will make a dict out of those objects. All of - # this is done by scheduler.utils.build_request_spec - # called in the conductor. - # - # Remove when request_spec is a proper object itself! - dict_cells = instance_numa_topology.get('cells') - if dict_cells: - cells = [objects.InstanceNUMACell( - id=cell['id'], - cpuset=set(cell['cpuset']), - memory=cell['memory'], - pagesize=cell.get('pagesize'), - cpu_topology=cell.get('cpu_topology'), - cpu_pinning=cell.get('cpu_pinning_raw'), - cpu_policy=cell.get('cpu_policy'), - cpu_thread_policy=cell.get('cpu_thread_policy'), - cpuset_reserved=cell.get('cpuset_reserved')) - for cell in dict_cells] - emulator_threads_policy = instance_numa_topology.get( - 'emulator_threads_policy') - instance_numa_topology = objects.InstanceNUMATopology( - cells=cells, - emulator_threads_policy=emulator_threads_policy) - - return instance_numa_topology