Remove 'hardware.instance_topology_from_instance'
Yet another function that has outstayed its welcome. This one had to handle random object types that may have had a 'numa_topology' field or key, which, if present, contained an instance NUMA topology in either string, dict or object form. This was only called in two places, both of which don't need this complexity as described below, meaning we can remove this function. nova/objects/request_spec.py The 'from_components' static method and '_from_instance' helper function were both using this, by way of a call to '_from_instance_numa_topology'. However, the former always receives an actual 'NUMATopology' object, while the latter always receives an instance, albeit possibly in serialized form. We add a check to handle the serialized form and we're done. Change-Id: I5ded32a1cd33ab5b64ffa73fcfeb76683eb97df7 Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user