Drop Instance v1.x support
This drops compatibility for Instance V1. Liberty supports both versions, which means we're outside the support envelope for V1 and can remove it. Note that this also snips out a few V1-specific compatibility bits from what was the common base now that we don't have to support them. UpgradeImpact: This drops support for an instance major version, which means that you must have deployed at least commit 713d8cb0777afb9fe4f665b9a40cac894b04aacb before deploying this one. Change-Id: I2d26399ed0d97234f240292d023769c264be2efd
This commit is contained in:
parent
fd2e946b62
commit
1337890ace
@ -1762,7 +1762,7 @@ class ComputeManager(manager.Manager):
|
||||
"""
|
||||
if not self.send_instance_updates:
|
||||
return
|
||||
if isinstance(instance, obj_instance._BaseInstance):
|
||||
if isinstance(instance, obj_instance.Instance):
|
||||
instance = objects.InstanceList(objects=[instance])
|
||||
context = context.elevated()
|
||||
self.scheduler_client.update_instance_info(context, self.host,
|
||||
|
@ -23,7 +23,6 @@ from oslo_utils import timeutils
|
||||
from nova.cells import opts as cells_opts
|
||||
from nova.cells import rpcapi as cells_rpcapi
|
||||
from nova.cells import utils as cells_utils
|
||||
from nova.compute import flavors
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova.i18n import _LE, _LW
|
||||
@ -83,8 +82,12 @@ _NO_DATA_SENTINEL = object()
|
||||
|
||||
|
||||
# TODO(berrange): Remove NovaObjectDictCompat
|
||||
class _BaseInstance(base.NovaPersistentObject, base.NovaObject,
|
||||
base.NovaObjectDictCompat):
|
||||
@base.NovaObjectRegistry.register
|
||||
class Instance(base.NovaPersistentObject, base.NovaObject,
|
||||
base.NovaObjectDictCompat):
|
||||
# Version 2.0: Initial version
|
||||
VERSION = '2.0'
|
||||
|
||||
fields = {
|
||||
'id': fields.IntegerField(),
|
||||
|
||||
@ -185,7 +188,7 @@ class _BaseInstance(base.NovaPersistentObject, base.NovaObject,
|
||||
obj_extra_fields = ['name']
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(_BaseInstance, self).__init__(*args, **kwargs)
|
||||
super(Instance, self).__init__(*args, **kwargs)
|
||||
self._reset_metadata_tracking()
|
||||
|
||||
def _reset_metadata_tracking(self, fields=None):
|
||||
@ -197,12 +200,12 @@ class _BaseInstance(base.NovaPersistentObject, base.NovaObject,
|
||||
'metadata' in self else {})
|
||||
|
||||
def obj_reset_changes(self, fields=None, recursive=False):
|
||||
super(_BaseInstance, self).obj_reset_changes(fields,
|
||||
recursive=recursive)
|
||||
super(Instance, self).obj_reset_changes(fields,
|
||||
recursive=recursive)
|
||||
self._reset_metadata_tracking(fields=fields)
|
||||
|
||||
def obj_what_changed(self):
|
||||
changes = super(_BaseInstance, self).obj_what_changed()
|
||||
changes = super(Instance, self).obj_what_changed()
|
||||
if 'metadata' in self and self.metadata != self._orig_metadata:
|
||||
changes.add('metadata')
|
||||
if 'system_metadata' in self and (self.system_metadata !=
|
||||
@ -212,8 +215,8 @@ class _BaseInstance(base.NovaPersistentObject, base.NovaObject,
|
||||
|
||||
@classmethod
|
||||
def _obj_from_primitive(cls, context, objver, primitive):
|
||||
self = super(_BaseInstance, cls)._obj_from_primitive(context, objver,
|
||||
primitive)
|
||||
self = super(Instance, cls)._obj_from_primitive(context, objver,
|
||||
primitive)
|
||||
self._reset_metadata_tracking()
|
||||
return self
|
||||
|
||||
@ -275,8 +278,6 @@ class _BaseInstance(base.NovaPersistentObject, base.NovaObject,
|
||||
instance.deleted = db_inst['deleted'] == db_inst['id']
|
||||
elif field == 'cleaned':
|
||||
instance.cleaned = db_inst['cleaned'] == 1
|
||||
elif field == 'scheduled_at':
|
||||
instance.scheduled_at = None
|
||||
else:
|
||||
instance[field] = db_inst[field]
|
||||
|
||||
@ -391,9 +392,6 @@ class _BaseInstance(base.NovaPersistentObject, base.NovaObject,
|
||||
updates = self.obj_get_changes()
|
||||
expected_attrs = [attr for attr in INSTANCE_DEFAULT_FIELDS
|
||||
if attr in updates]
|
||||
if 'scheduled_at' in updates:
|
||||
# NOTE(sbiswas7): 'scheduled_at' is not present in models.
|
||||
del updates['scheduled_at']
|
||||
if 'security_groups' in updates:
|
||||
updates['security_groups'] = [x.name for x in
|
||||
updates['security_groups']]
|
||||
@ -600,10 +598,6 @@ class _BaseInstance(base.NovaPersistentObject, base.NovaObject,
|
||||
|
||||
updates = {}
|
||||
changes = self.obj_what_changed()
|
||||
if 'scheduled_at' in changes:
|
||||
# NOTE(sbiswas7): Since 'scheduled_at' is removed from models,
|
||||
# we need to discard it.
|
||||
changes.remove('scheduled_at')
|
||||
|
||||
for field in self.fields:
|
||||
# NOTE(danms): For object fields, we construct and call a
|
||||
@ -645,13 +639,6 @@ class _BaseInstance(base.NovaPersistentObject, base.NovaObject,
|
||||
updates['cleaned'] = 0
|
||||
|
||||
if expected_task_state is not None:
|
||||
if (self.VERSION == '1.9' and
|
||||
expected_task_state == 'image_snapshot'):
|
||||
# NOTE(danms): Icehouse introduced a pending state which
|
||||
# Havana doesn't know about. If we're an old instance,
|
||||
# tolerate the pending state as well
|
||||
expected_task_state = [
|
||||
expected_task_state, 'image_snapshot_pending']
|
||||
updates['expected_task_state'] = expected_task_state
|
||||
if expected_vm_state is not None:
|
||||
updates['expected_vm_state'] = expected_vm_state
|
||||
@ -752,23 +739,9 @@ class _BaseInstance(base.NovaPersistentObject, base.NovaObject,
|
||||
self._context, self.uuid)
|
||||
|
||||
def _load_flavor(self):
|
||||
try:
|
||||
instance = self.__class__.get_by_uuid(
|
||||
self._context, uuid=self.uuid,
|
||||
expected_attrs=['flavor', 'system_metadata'])
|
||||
except exception.InstanceNotFound:
|
||||
# NOTE(danms): Before we had instance types in system_metadata,
|
||||
# we just looked up the instance_type_id. Since we could still
|
||||
# have an instance in the database that doesn't have either
|
||||
# newer setup, mirror the original behavior here if the instance
|
||||
# is deleted
|
||||
if not self.deleted:
|
||||
raise
|
||||
self.flavor = objects.Flavor.get_by_id(self._context,
|
||||
self.instance_type_id)
|
||||
self.old_flavor = None
|
||||
self.new_flavor = None
|
||||
return
|
||||
instance = self.__class__.get_by_uuid(
|
||||
self._context, uuid=self.uuid,
|
||||
expected_attrs=['flavor', 'system_metadata'])
|
||||
|
||||
# NOTE(danms): Orphan the instance to make sure we don't lazy-load
|
||||
# anything below
|
||||
@ -973,118 +946,6 @@ class _BaseInstance(base.NovaPersistentObject, base.NovaObject,
|
||||
finally:
|
||||
self._normalize_cell_name()
|
||||
|
||||
@classmethod
|
||||
def obj_name(cls):
|
||||
return 'Instance'
|
||||
|
||||
|
||||
@base.NovaObjectRegistry.register
|
||||
class InstanceV1(_BaseInstance):
|
||||
# Version 1.0: Initial version
|
||||
# Version 1.1: Added info_cache
|
||||
# Version 1.2: Added security_groups
|
||||
# Version 1.3: Added expected_vm_state and admin_state_reset to
|
||||
# save()
|
||||
# Version 1.4: Added locked_by and deprecated locked
|
||||
# Version 1.5: Added cleaned
|
||||
# Version 1.6: Added pci_devices
|
||||
# Version 1.7: String attributes updated to support unicode
|
||||
# Version 1.8: 'security_groups' and 'pci_devices' cannot be None
|
||||
# Version 1.9: Make uuid a non-None real string
|
||||
# Version 1.10: Added use_slave to refresh and get_by_uuid
|
||||
# Version 1.11: Update instance from database during destroy
|
||||
# Version 1.12: Added ephemeral_key_uuid
|
||||
# Version 1.13: Added delete_metadata_key()
|
||||
# Version 1.14: Added numa_topology
|
||||
# Version 1.15: PciDeviceList 1.1
|
||||
# Version 1.16: Added pci_requests
|
||||
# Version 1.17: Added tags
|
||||
# Version 1.18: Added flavor, old_flavor, new_flavor, will use
|
||||
# PciDeviceList version 1.2
|
||||
# Version 1.19: Added vcpu_model
|
||||
# Version 1.20: Added ec2_ids
|
||||
# Version 1.21: TagList 1.1
|
||||
# Version 1.22: InstanceNUMATopology 1.2
|
||||
# Version 1.23: Added migration_context
|
||||
VERSION = '1.23'
|
||||
|
||||
fields = {
|
||||
# NOTE(sbiswas7): this field is depcrecated,
|
||||
# will be removed in instance v2.0
|
||||
'scheduled_at': fields.DateTimeField(nullable=True),
|
||||
}
|
||||
|
||||
obj_relationships = {
|
||||
'fault': [('1.0', '1.0'), ('1.13', '1.2')],
|
||||
'info_cache': [('1.1', '1.0'), ('1.9', '1.4'), ('1.10', '1.5')],
|
||||
'security_groups': [('1.2', '1.0')],
|
||||
'pci_devices': [('1.6', '1.0'), ('1.15', '1.1'), ('1.18', '1.2')],
|
||||
'numa_topology': [('1.14', '1.0'), ('1.16', '1.1'), ('1.22', '1.2')],
|
||||
'pci_requests': [('1.16', '1.1')],
|
||||
'tags': [('1.17', '1.0'), ('1.21', '1.1')],
|
||||
'flavor': [('1.18', '1.1')],
|
||||
'old_flavor': [('1.18', '1.1')],
|
||||
'new_flavor': [('1.18', '1.1')],
|
||||
'vcpu_model': [('1.19', '1.0')],
|
||||
'ec2_ids': [('1.20', '1.0')],
|
||||
'migration_context': [('1.23', '1.0')],
|
||||
}
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
super(InstanceV1, self).obj_make_compatible(primitive, target_version)
|
||||
target_version = utils.convert_version_to_tuple(target_version)
|
||||
unicode_attributes = ['user_id', 'project_id', 'image_ref',
|
||||
'kernel_id', 'ramdisk_id', 'hostname',
|
||||
'key_name', 'key_data', 'host', 'node',
|
||||
'user_data', 'availability_zone',
|
||||
'display_name', 'display_description',
|
||||
'launched_on', 'locked_by', 'os_type',
|
||||
'architecture', 'vm_mode', 'root_device_name',
|
||||
'default_ephemeral_device',
|
||||
'default_swap_device', 'config_drive',
|
||||
'cell_name']
|
||||
if target_version < (1, 7):
|
||||
# NOTE(danms): Before 1.7, we couldn't handle unicode in
|
||||
# string fields, so squash it here
|
||||
for field in [x for x in unicode_attributes if x in primitive
|
||||
and primitive[x] is not None]:
|
||||
primitive[field] = primitive[field].encode('ascii', 'replace')
|
||||
if target_version < (1, 18):
|
||||
if 'system_metadata' in primitive:
|
||||
for ftype in ('', 'old_', 'new_'):
|
||||
attrname = '%sflavor' % ftype
|
||||
primitive.pop(attrname, None)
|
||||
if self[attrname] is not None:
|
||||
flavors.save_flavor_info(
|
||||
primitive['system_metadata'],
|
||||
getattr(self, attrname), ftype)
|
||||
|
||||
|
||||
@base.NovaObjectRegistry.register
|
||||
class InstanceV2(_BaseInstance):
|
||||
# Version 2.0: Initial version
|
||||
VERSION = '2.0'
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
if target_version.startswith('1.'):
|
||||
# NOTE(danms): Special case to backport to 1.x. Serialize
|
||||
# ourselves, change the version, deserialize that, and get
|
||||
# that to continue the backport of this primitive to
|
||||
# whatever 1.x version was actually requested. We can get
|
||||
# away with this because InstanceV2 is structurally a
|
||||
# subset of V1.
|
||||
# FIXME(danms): Remove this when we drop v1.x compatibility
|
||||
my_prim = self.obj_to_primitive()
|
||||
my_prim['nova_object.version'] = InstanceV1.VERSION
|
||||
instv1 = InstanceV1.obj_from_primitive(my_prim,
|
||||
context=self._context)
|
||||
return instv1.obj_make_compatible(primitive, target_version)
|
||||
super(InstanceV2, self).obj_make_compatible(primitive, target_version)
|
||||
|
||||
|
||||
# NOTE(danms): For the unit tests...
|
||||
Instance = InstanceV2
|
||||
|
||||
|
||||
def _make_instance_list(context, inst_list, db_inst_list, expected_attrs):
|
||||
get_fault = expected_attrs and 'fault' in expected_attrs
|
||||
@ -1099,7 +960,7 @@ def _make_instance_list(context, inst_list, db_inst_list, expected_attrs):
|
||||
if fault.instance_uuid not in inst_faults:
|
||||
inst_faults[fault.instance_uuid] = fault
|
||||
|
||||
inst_cls = inst_list.NOVA_OBJ_INSTANCE_CLS
|
||||
inst_cls = objects.Instance
|
||||
|
||||
inst_list.objects = []
|
||||
for db_inst in db_inst_list:
|
||||
@ -1113,7 +974,11 @@ def _make_instance_list(context, inst_list, db_inst_list, expected_attrs):
|
||||
return inst_list
|
||||
|
||||
|
||||
class _BaseInstanceList(base.ObjectListBase, base.NovaObject):
|
||||
@base.NovaObjectRegistry.register
|
||||
class InstanceList(base.ObjectListBase, base.NovaObject):
|
||||
# Version 2.0: Initial Version
|
||||
VERSION = '2.0'
|
||||
|
||||
fields = {
|
||||
'objects': fields.ListOfObjectsField('Instance'),
|
||||
}
|
||||
@ -1260,71 +1125,3 @@ class _BaseInstanceList(base.ObjectListBase, base.NovaObject):
|
||||
instance.obj_reset_changes(['fault'])
|
||||
|
||||
return faults_by_uuid.keys()
|
||||
|
||||
@classmethod
|
||||
def obj_name(cls):
|
||||
return 'InstanceList'
|
||||
|
||||
|
||||
@base.NovaObjectRegistry.register
|
||||
class InstanceListV1(_BaseInstanceList):
|
||||
# Version 1.0: Initial version
|
||||
# Version 1.1: Added use_slave to get_by_host
|
||||
# Instance <= version 1.9
|
||||
# Version 1.2: Instance <= version 1.11
|
||||
# Version 1.3: Added use_slave to get_by_filters
|
||||
# Version 1.4: Instance <= version 1.12
|
||||
# Version 1.5: Added method get_active_by_window_joined.
|
||||
# Version 1.6: Instance <= version 1.13
|
||||
# Version 1.7: Added use_slave to get_active_by_window_joined
|
||||
# Version 1.8: Instance <= version 1.14
|
||||
# Version 1.9: Instance <= version 1.15
|
||||
# Version 1.10: Instance <= version 1.16
|
||||
# Version 1.11: Added sort_keys and sort_dirs to get_by_filters
|
||||
# Version 1.12: Pass expected_attrs to instance_get_active_by_window_joined
|
||||
# Version 1.13: Instance <= version 1.17
|
||||
# Version 1.14: Instance <= version 1.18
|
||||
# Version 1.15: Instance <= version 1.19
|
||||
# Version 1.16: Added get_all() method
|
||||
# Version 1.17: Instance <= version 1.20
|
||||
# Version 1.18: Instance <= version 1.21
|
||||
# Version 1.19: Erronenous removal of get_hung_in_rebooting(). Reverted.
|
||||
# Version 1.20: Instance <= version 1.22
|
||||
# Version 1.21: New method get_by_grantee_security_group_ids()
|
||||
# Version 1.22: Instance <= version 1.23
|
||||
VERSION = '1.22'
|
||||
|
||||
NOVA_OBJ_INSTANCE_CLS = InstanceV1
|
||||
|
||||
# NOTE(danms): Instance was at 1.9 before we added this
|
||||
obj_relationships = {
|
||||
'objects': [('1.1', '1.9'), ('1.2', '1.11'), ('1.3', '1.11'),
|
||||
('1.4', '1.12'), ('1.5', '1.12'), ('1.6', '1.13'),
|
||||
('1.7', '1.13'), ('1.8', '1.14'), ('1.9', '1.15',),
|
||||
('1.10', '1.16'), ('1.11', '1.16'), ('1.12', '1.16'),
|
||||
('1.13', '1.17'), ('1.14', '1.18'), ('1.15', '1.19'),
|
||||
('1.16', '1.19'), ('1.17', '1.20'), ('1.18', '1.21'),
|
||||
('1.19', '1.21'), ('1.20', '1.22'), ('1.21', '1.22'),
|
||||
('1.22', '1.23')],
|
||||
}
|
||||
|
||||
|
||||
@base.NovaObjectRegistry.register
|
||||
class InstanceListV2(_BaseInstanceList):
|
||||
# Version 2.0: Initial version
|
||||
VERSION = '2.0'
|
||||
|
||||
NOVA_OBJ_INSTANCE_CLS = InstanceV2
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
if target_version.startswith('1.'):
|
||||
my_prim = self.obj_to_primitive()
|
||||
my_prim['nova_object.version'] = InstanceListV1.VERSION
|
||||
instv1 = InstanceListV1.obj_from_primitive(my_prim,
|
||||
context=self._context)
|
||||
return instv1.obj_make_compatible(primitive, target_version)
|
||||
super(InstanceListV2, self).obj_make_compatible(primitive,
|
||||
target_version)
|
||||
|
||||
# NOTE(danms): For the unit tests...
|
||||
InstanceList = InstanceListV2
|
||||
|
@ -86,7 +86,7 @@ class RequestSpec(base.NovaObject):
|
||||
self.image = None
|
||||
|
||||
def _from_instance(self, instance):
|
||||
if isinstance(instance, obj_instance._BaseInstance):
|
||||
if isinstance(instance, obj_instance.Instance):
|
||||
# NOTE(sbauza): Instance should normally be a NovaObject...
|
||||
getter = getattr
|
||||
elif isinstance(instance, dict):
|
||||
|
@ -57,12 +57,12 @@ def build_request_spec(ctxt, image, instances, instance_type=None):
|
||||
"""
|
||||
instance = instances[0]
|
||||
if instance_type is None:
|
||||
if isinstance(instance, obj_instance._BaseInstance):
|
||||
if isinstance(instance, obj_instance.Instance):
|
||||
instance_type = instance.get_flavor()
|
||||
else:
|
||||
instance_type = flavors.extract_flavor(instance)
|
||||
|
||||
if isinstance(instance, obj_instance._BaseInstance):
|
||||
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.
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
import datetime
|
||||
|
||||
import fixtures
|
||||
import mock
|
||||
from mox3 import mox
|
||||
import netaddr
|
||||
@ -368,11 +367,6 @@ class _TestInstanceObject(object):
|
||||
def test_save_exp_task_state(self):
|
||||
self._save_test_helper(None, {'expected_task_state': ['meow']})
|
||||
|
||||
def test_save_exp_task_state_havana(self):
|
||||
self._save_test_helper(None, {
|
||||
'expected_task_state': 'image_snapshot',
|
||||
'instance_version': '1.9'})
|
||||
|
||||
def test_save_exp_vm_state_api_cell(self):
|
||||
self._save_test_helper('api', {'expected_vm_state': ['meow']})
|
||||
|
||||
@ -428,7 +422,7 @@ class _TestInstanceObject(object):
|
||||
self.assertTrue(save_mock.called)
|
||||
|
||||
@mock.patch('nova.db.instance_update_and_get_original')
|
||||
@mock.patch.object(instance._BaseInstance, '_from_db_object')
|
||||
@mock.patch.object(instance.Instance, '_from_db_object')
|
||||
def test_save_does_not_refresh_pci_devices(self, mock_fdo, mock_update):
|
||||
# NOTE(danms): This tests that we don't update the pci_devices
|
||||
# field from the contents of the database. This is not because we
|
||||
@ -445,7 +439,7 @@ class _TestInstanceObject(object):
|
||||
|
||||
@mock.patch('nova.db.instance_extra_update_by_uuid')
|
||||
@mock.patch('nova.db.instance_update_and_get_original')
|
||||
@mock.patch.object(instance._BaseInstance, '_from_db_object')
|
||||
@mock.patch.object(instance.Instance, '_from_db_object')
|
||||
def test_save_updates_numa_topology(self, mock_fdo, mock_update,
|
||||
mock_extra_update):
|
||||
fake_obj_numa_topology = objects.InstanceNUMATopology(cells=[
|
||||
@ -1004,7 +998,7 @@ class _TestInstanceObject(object):
|
||||
inst.destroy()
|
||||
mock_destroy_at_top.assert_called_once_with(self.context, mock.ANY)
|
||||
actual_inst = mock_destroy_at_top.call_args[0][1]
|
||||
self.assertIsInstance(actual_inst, instance._BaseInstance)
|
||||
self.assertIsInstance(actual_inst, instance.Instance)
|
||||
|
||||
@mock.patch.object(cells_rpcapi.CellsAPI, 'instance_destroy_at_top')
|
||||
@mock.patch.object(db, 'instance_destroy')
|
||||
@ -1314,108 +1308,7 @@ class TestInstanceObject(test_objects._LocalTest,
|
||||
|
||||
class TestRemoteInstanceObject(test_objects._RemoteTest,
|
||||
_TestInstanceObject):
|
||||
def setUp(self):
|
||||
super(TestRemoteInstanceObject, self).setUp()
|
||||
self.useFixture(fixtures.MonkeyPatch('nova.objects.Instance',
|
||||
instance.InstanceV2))
|
||||
|
||||
|
||||
class TestInstanceV1RemoteObject(test_objects._RemoteTest,
|
||||
_TestInstanceObject):
|
||||
def setUp(self):
|
||||
super(TestInstanceV1RemoteObject, self).setUp()
|
||||
self.useFixture(fixtures.MonkeyPatch('nova.objects.Instance',
|
||||
instance.InstanceV1))
|
||||
|
||||
@mock.patch('nova.db.instance_update_and_get_original')
|
||||
@mock.patch.object(instance._BaseInstance, '_from_db_object')
|
||||
def test_save_skip_scheduled_at(self, mock_fdo, mock_update):
|
||||
mock_update.return_value = None, None
|
||||
inst = objects.Instance(context=self.context, id=123)
|
||||
inst.uuid = 'foo'
|
||||
inst.scheduled_at = None
|
||||
inst.save()
|
||||
self.assertNotIn('scheduled_at',
|
||||
mock_update.call_args_list[0][0][2])
|
||||
|
||||
def test_backport_flavor(self):
|
||||
flavor = flavors.get_default_flavor()
|
||||
inst = objects.Instance(context=self.context, flavor=flavor,
|
||||
system_metadata={'foo': 'bar'},
|
||||
new_flavor=None,
|
||||
old_flavor=None)
|
||||
primitive = inst.obj_to_primitive(target_version='1.17')
|
||||
self.assertIn('instance_type_id',
|
||||
primitive['nova_object.data']['system_metadata'])
|
||||
|
||||
def test_compat_strings(self):
|
||||
unicode_attributes = ['user_id', 'project_id', 'image_ref',
|
||||
'kernel_id', 'ramdisk_id', 'hostname',
|
||||
'key_name', 'key_data', 'host', 'node',
|
||||
'user_data', 'availability_zone',
|
||||
'display_name', 'display_description',
|
||||
'launched_on', 'locked_by', 'os_type',
|
||||
'architecture', 'vm_mode', 'root_device_name',
|
||||
'default_ephemeral_device',
|
||||
'default_swap_device', 'config_drive',
|
||||
'cell_name']
|
||||
inst = objects.Instance()
|
||||
expected = {}
|
||||
for key in unicode_attributes:
|
||||
inst[key] = u'\u2603'
|
||||
expected[key] = b'?'
|
||||
primitive = inst.obj_to_primitive(target_version='1.6')
|
||||
self.assertJsonEqual(expected, primitive['nova_object.data'])
|
||||
self.assertEqual('1.6', primitive['nova_object.version'])
|
||||
|
||||
def test_compat_pci_devices(self):
|
||||
inst = objects.Instance()
|
||||
inst.pci_devices = pci_device.PciDeviceList()
|
||||
primitive = inst.obj_to_primitive(target_version='1.5')
|
||||
self.assertNotIn('pci_devices', primitive)
|
||||
|
||||
def test_compat_info_cache(self):
|
||||
inst = objects.Instance()
|
||||
inst.info_cache = instance_info_cache.InstanceInfoCache()
|
||||
primitive = inst.obj_to_primitive(target_version='1.9')
|
||||
self.assertEqual(
|
||||
'1.4',
|
||||
primitive['nova_object.data']['info_cache']['nova_object.version'])
|
||||
|
||||
def test_backport_v2_to_v1(self):
|
||||
inst2 = fake_instance.fake_instance_obj(
|
||||
self.context, obj_instance_class=instance.InstanceV2)
|
||||
inst1 = instance.InstanceV1.obj_from_primitive(
|
||||
inst2.obj_to_primitive(target_version=instance.InstanceV1.VERSION))
|
||||
self.assertEqual(instance.InstanceV1.VERSION, inst1.VERSION)
|
||||
self.assertIsInstance(inst1, instance.InstanceV1)
|
||||
self.assertEqual(inst2.uuid, inst1.uuid)
|
||||
|
||||
def test_backport_list_v2_to_v1(self):
|
||||
inst2 = fake_instance.fake_instance_obj(
|
||||
self.context, obj_instance_class=instance.InstanceV2)
|
||||
list2 = instance.InstanceListV2(objects=[inst2])
|
||||
list1 = instance.InstanceListV1.obj_from_primitive(
|
||||
list2.obj_to_primitive(
|
||||
target_version=instance.InstanceListV1.VERSION))
|
||||
self.assertEqual(instance.InstanceListV1.VERSION, list1.VERSION)
|
||||
self.assertEqual(instance.InstanceV1.VERSION, list1[0].VERSION)
|
||||
self.assertIsInstance(list1, instance.InstanceListV1)
|
||||
self.assertIsInstance(list1[0], instance.InstanceV1)
|
||||
self.assertEqual(list2[0].uuid, list1[0].uuid)
|
||||
|
||||
def test_backport_v2_to_v1_uses_context(self):
|
||||
inst2 = instance.InstanceV2(context=self.context)
|
||||
with mock.patch.object(instance.InstanceV1, 'obj_from_primitive') as m:
|
||||
inst2.obj_make_compatible({}, '1.0')
|
||||
m.assert_called_once_with(mock.ANY, context=self.context)
|
||||
|
||||
def test_backport_list_v2_to_v1_uses_context(self):
|
||||
list2 = instance.InstanceListV2(context=self.context)
|
||||
with mock.patch.object(instance.InstanceListV1,
|
||||
'obj_from_primitive') as m:
|
||||
list2.obj_make_compatible({}, '1.0')
|
||||
m.assert_called_once_with(mock.ANY, context=self.context)
|
||||
pass
|
||||
|
||||
|
||||
class _TestInstanceListObject(object):
|
||||
@ -1452,7 +1345,7 @@ class _TestInstanceListObject(object):
|
||||
expected_attrs=['metadata'], use_slave=False)
|
||||
|
||||
for i in range(0, len(fakes)):
|
||||
self.assertIsInstance(inst_list.objects[i], instance._BaseInstance)
|
||||
self.assertIsInstance(inst_list.objects[i], instance.Instance)
|
||||
self.assertEqual(fakes[i]['uuid'], inst_list.objects[i].uuid)
|
||||
|
||||
def test_get_all_by_filters_sorted(self):
|
||||
@ -1470,7 +1363,7 @@ class _TestInstanceListObject(object):
|
||||
use_slave=False, sort_keys=['uuid'], sort_dirs=['asc'])
|
||||
|
||||
for i in range(0, len(fakes)):
|
||||
self.assertIsInstance(inst_list.objects[i], instance._BaseInstance)
|
||||
self.assertIsInstance(inst_list.objects[i], instance.Instance)
|
||||
self.assertEqual(fakes[i]['uuid'], inst_list.objects[i].uuid)
|
||||
|
||||
@mock.patch.object(db, 'instance_get_all_by_filters_sort')
|
||||
@ -1523,7 +1416,7 @@ class _TestInstanceListObject(object):
|
||||
expected_attrs=['metadata'], use_slave=False)
|
||||
|
||||
self.assertEqual(1, len(inst_list))
|
||||
self.assertIsInstance(inst_list.objects[0], instance._BaseInstance)
|
||||
self.assertIsInstance(inst_list.objects[0], instance.Instance)
|
||||
self.assertEqual(fakes[1]['uuid'], inst_list.objects[0].uuid)
|
||||
|
||||
def test_get_by_host(self):
|
||||
@ -1536,7 +1429,7 @@ class _TestInstanceListObject(object):
|
||||
self.mox.ReplayAll()
|
||||
inst_list = objects.InstanceList.get_by_host(self.context, 'foo')
|
||||
for i in range(0, len(fakes)):
|
||||
self.assertIsInstance(inst_list.objects[i], instance._BaseInstance)
|
||||
self.assertIsInstance(inst_list.objects[i], instance.Instance)
|
||||
self.assertEqual(fakes[i]['uuid'], inst_list.objects[i].uuid)
|
||||
self.assertEqual(self.context, inst_list.objects[i]._context)
|
||||
self.assertEqual(set(), inst_list.obj_what_changed())
|
||||
@ -1552,7 +1445,7 @@ class _TestInstanceListObject(object):
|
||||
inst_list = objects.InstanceList.get_by_host_and_node(self.context,
|
||||
'foo', 'bar')
|
||||
for i in range(0, len(fakes)):
|
||||
self.assertIsInstance(inst_list.objects[i], instance._BaseInstance)
|
||||
self.assertIsInstance(inst_list.objects[i], instance.Instance)
|
||||
self.assertEqual(fakes[i]['uuid'], inst_list.objects[i].uuid)
|
||||
|
||||
def test_get_by_host_and_not_type(self):
|
||||
@ -1566,7 +1459,7 @@ class _TestInstanceListObject(object):
|
||||
inst_list = objects.InstanceList.get_by_host_and_not_type(
|
||||
self.context, 'foo', 'bar')
|
||||
for i in range(0, len(fakes)):
|
||||
self.assertIsInstance(inst_list.objects[i], instance._BaseInstance)
|
||||
self.assertIsInstance(inst_list.objects[i], instance.Instance)
|
||||
self.assertEqual(fakes[i]['uuid'], inst_list.objects[i].uuid)
|
||||
|
||||
@mock.patch('nova.objects.instance._expected_cols')
|
||||
@ -1580,7 +1473,7 @@ class _TestInstanceListObject(object):
|
||||
mock_get_all.assert_called_once_with(
|
||||
self.context, columns_to_join=mock.sentinel.exp_att)
|
||||
for i in range(0, len(fakes)):
|
||||
self.assertIsInstance(inst_list.objects[i], instance._BaseInstance)
|
||||
self.assertIsInstance(inst_list.objects[i], instance.Instance)
|
||||
self.assertEqual(fakes[i]['uuid'], inst_list.objects[i].uuid)
|
||||
|
||||
def test_get_hung_in_rebooting(self):
|
||||
@ -1594,7 +1487,7 @@ class _TestInstanceListObject(object):
|
||||
inst_list = objects.InstanceList.get_hung_in_rebooting(self.context,
|
||||
dt)
|
||||
for i in range(0, len(fakes)):
|
||||
self.assertIsInstance(inst_list.objects[i], instance._BaseInstance)
|
||||
self.assertIsInstance(inst_list.objects[i], instance.Instance)
|
||||
self.assertEqual(fakes[i]['uuid'], inst_list.objects[i].uuid)
|
||||
|
||||
def test_get_active_by_window_joined(self):
|
||||
@ -1619,7 +1512,7 @@ class _TestInstanceListObject(object):
|
||||
self.context, dt, expected_attrs=['metadata'])
|
||||
|
||||
for fake, obj in zip(fakes, inst_list.objects):
|
||||
self.assertIsInstance(obj, instance._BaseInstance)
|
||||
self.assertIsInstance(obj, instance.Instance)
|
||||
self.assertEqual(fake['uuid'], obj.uuid)
|
||||
|
||||
def test_with_fault(self):
|
||||
@ -1683,7 +1576,7 @@ class _TestInstanceListObject(object):
|
||||
for inst in inst_list:
|
||||
self.assertEqual(set(), inst.obj_what_changed())
|
||||
|
||||
@mock.patch('nova.objects.instance.InstanceV1.obj_make_compatible')
|
||||
@mock.patch('nova.objects.instance.Instance.obj_make_compatible')
|
||||
def test_get_by_security_group(self, mock_compat):
|
||||
fake_secgroup = dict(test_security_group.fake_secgroup)
|
||||
fake_secgroup['instances'] = [
|
||||
@ -1696,7 +1589,7 @@ class _TestInstanceListObject(object):
|
||||
sgg.return_value = fake_secgroup
|
||||
secgroup = security_group.SecurityGroup()
|
||||
secgroup.id = fake_secgroup['id']
|
||||
instances = instance.InstanceListV2.get_by_security_group(
|
||||
instances = instance.InstanceList.get_by_security_group(
|
||||
self.context, secgroup)
|
||||
|
||||
self.assertEqual(2, len(instances))
|
||||
|
@ -1189,10 +1189,6 @@ object_data = {
|
||||
'ImageMeta': '1.7-642d1b2eb3e880a367f37d72dd76162d',
|
||||
'ImageMetaProps': '1.7-f12fc4cf3e25d616f69a66fb9d2a7aa6',
|
||||
'Instance': '2.0-ff56804dce87d81d9a04834d4bd1e3d2',
|
||||
# NOTE(danms): Reviewers: do not approve changes to the Instance1
|
||||
# object schema. It is frozen for Liberty and will be removed in
|
||||
# Mitaka.
|
||||
'Instance1': '1.23-4e68422207667f4abff5fa730a5edc98',
|
||||
'InstanceAction': '1.1-f9f293e526b66fca0d05c3b3a2d13914',
|
||||
'InstanceActionEvent': '1.1-e56a64fa4710e43ef7af2ad9d6028b33',
|
||||
'InstanceActionEventList': '1.1-13d92fb953030cdbfee56481756e02be',
|
||||
@ -1204,10 +1200,6 @@ object_data = {
|
||||
'InstanceGroupList': '1.7-be18078220513316abd0ae1b2d916873',
|
||||
'InstanceInfoCache': '1.5-cd8b96fefe0fc8d4d337243ba0bf0e1e',
|
||||
'InstanceList': '2.0-6c8ba6147cca3082b1e4643f795068bf',
|
||||
# NOTE(danms): Reviewers: do not approve changes to the InstanceList1
|
||||
# object schema. It is frozen for Liberty and will be removed in
|
||||
# Mitaka.
|
||||
'InstanceList1': '1.22-6c8ba6147cca3082b1e4643f795068bf',
|
||||
'InstanceMapping': '1.0-47ef26034dfcbea78427565d9177fe50',
|
||||
'InstanceMappingList': '1.0-9e982e3de1613b9ada85e35f69b23d47',
|
||||
'InstanceNUMACell': '1.2-535ef30e0de2d6a0d26a71bd58ecafc4',
|
||||
|
@ -1183,7 +1183,7 @@ def instance_topology_from_instance(instance):
|
||||
Instance object, this makes sure we get beck either None, or an instance
|
||||
of objects.InstanceNUMATopology class.
|
||||
"""
|
||||
if isinstance(instance, obj_instance._BaseInstance):
|
||||
if isinstance(instance, obj_instance.Instance):
|
||||
# NOTE (ndipanov): This may cause a lazy-load of the attribute
|
||||
instance_numa_topology = instance.numa_topology
|
||||
else:
|
||||
|
Loading…
x
Reference in New Issue
Block a user