Merge "objects: Hook migration object into Instance"
This commit is contained in:
commit
3f0c42325a
|
@ -57,7 +57,8 @@ class BlockDeviceMapping(base.NovaPersistentObject, base.NovaObject,
|
|||
# Version 1.12: Changed device_type field to BlockDeviceTypeField.
|
||||
# Version 1.13: Instance version 1.21
|
||||
# Version 1.14: Instance version 1.22
|
||||
VERSION = '1.14'
|
||||
# Version 1.15: Instance version 1.23
|
||||
VERSION = '1.15'
|
||||
|
||||
fields = {
|
||||
'id': fields.IntegerField(),
|
||||
|
@ -84,7 +85,7 @@ class BlockDeviceMapping(base.NovaPersistentObject, base.NovaObject,
|
|||
'instance': [('1.0', '1.13'), ('1.2', '1.14'), ('1.3', '1.15'),
|
||||
('1.4', '1.16'), ('1.5', '1.17'), ('1.6', '1.18'),
|
||||
('1.8', '1.19'), ('1.9', '1.20'), ('1.13', '1.21'),
|
||||
('1.14', '1.22')],
|
||||
('1.14', '1.22'), ('1.15', '1.23')],
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
@ -272,7 +273,8 @@ class BlockDeviceMappingList(base.ObjectListBase, base.NovaObject):
|
|||
# Version 1.13: BlockDeviceMapping <= version 1.12
|
||||
# Version 1.14: BlockDeviceMapping <= version 1.13
|
||||
# Version 1.15: BlockDeviceMapping <= version 1.14
|
||||
VERSION = '1.15'
|
||||
# Version 1.16: BlockDeviceMapping <= version 1.15
|
||||
VERSION = '1.16'
|
||||
|
||||
fields = {
|
||||
'objects': fields.ListOfObjectsField('BlockDeviceMapping'),
|
||||
|
@ -283,7 +285,7 @@ class BlockDeviceMappingList(base.ObjectListBase, base.NovaObject):
|
|||
('1.6', '1.5'), ('1.7', '1.6'), ('1.8', '1.7'),
|
||||
('1.9', '1.8'), ('1.10', '1.9'), ('1.11', '1.10'),
|
||||
('1.12', '1.11'), ('1.13', '1.12'), ('1.14', '1.13'),
|
||||
('1.15', '1.14')],
|
||||
('1.15', '1.14'), ('1.16', '1.15')],
|
||||
}
|
||||
|
||||
@base.remotable_classmethod
|
||||
|
|
|
@ -43,7 +43,8 @@ class FixedIP(obj_base.NovaPersistentObject, obj_base.NovaObject,
|
|||
# Version 1.10: Instance 1.20
|
||||
# Version 1.11: Instance 1.21
|
||||
# Version 1.12: Instance 1.22, FloatingIPList 1.9
|
||||
VERSION = '1.12'
|
||||
# Version 1.13: Instance 1.23, FloatingIPList 1.10
|
||||
VERSION = '1.13'
|
||||
|
||||
fields = {
|
||||
'id': fields.IntegerField(),
|
||||
|
@ -70,10 +71,11 @@ class FixedIP(obj_base.NovaPersistentObject, obj_base.NovaObject,
|
|||
'instance': [('1.0', '1.13'), ('1.2', '1.14'), ('1.3', '1.15'),
|
||||
('1.6', '1.16'), ('1.7', '1.17'), ('1.8', '1.18'),
|
||||
('1.9', '1.19'), ('1.10', '1.20'), ('1.11', '1.21'),
|
||||
('1.12', '1.22')],
|
||||
('1.12', '1.22'), ('1.13', '1.23')],
|
||||
'network': [('1.0', '1.2')],
|
||||
'virtual_interface': [('1.1', '1.0')],
|
||||
'floating_ips': [('1.5', '1.7'), ('1.11', '1.8'), ('1.12', '1.9')],
|
||||
'floating_ips': [('1.5', '1.7'), ('1.11', '1.8'), ('1.12', '1.9'),
|
||||
('1.13', '1.10')],
|
||||
}
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
|
@ -222,7 +224,8 @@ class FixedIPList(obj_base.ObjectListBase, obj_base.NovaObject):
|
|||
# Version 1.10: FixedIP <= version 1.10
|
||||
# Version 1.11: FixedIP <= version 1.11
|
||||
# Version 1.12: FixedIP <= version 1.12
|
||||
VERSION = '1.12'
|
||||
# Version 1.13: FixedIP <= version 1.13
|
||||
VERSION = '1.13'
|
||||
|
||||
fields = {
|
||||
'objects': fields.ListOfObjectsField('FixedIP'),
|
||||
|
@ -232,7 +235,7 @@ class FixedIPList(obj_base.ObjectListBase, obj_base.NovaObject):
|
|||
('1.3', '1.3'), ('1.4', '1.4'), ('1.5', '1.5'),
|
||||
('1.6', '1.6'), ('1.7', '1.7'), ('1.8', '1.8'),
|
||||
('1.9', '1.9'), ('1.10', '1.10'), ('1.11', '1.11'),
|
||||
('1.12', '1.12')],
|
||||
('1.12', '1.12'), ('1.13', '1.13')],
|
||||
}
|
||||
|
||||
@obj_base.remotable_classmethod
|
||||
|
|
|
@ -34,7 +34,8 @@ class FloatingIP(obj_base.NovaPersistentObject, obj_base.NovaObject,
|
|||
# Version 1.6: FixedIP <= version 1.6
|
||||
# Version 1.7: FixedIP <= version 1.11
|
||||
# Version 1.8: FixedIP <= version 1.12
|
||||
VERSION = '1.8'
|
||||
# Version 1.9: FixedIP <= version 1.13
|
||||
VERSION = '1.9'
|
||||
fields = {
|
||||
'id': fields.IntegerField(),
|
||||
'address': fields.IPAddressField(),
|
||||
|
@ -50,7 +51,7 @@ class FloatingIP(obj_base.NovaPersistentObject, obj_base.NovaObject,
|
|||
obj_relationships = {
|
||||
'fixed_ip': [('1.0', '1.1'), ('1.2', '1.2'), ('1.3', '1.3'),
|
||||
('1.4', '1.4'), ('1.5', '1.5'), ('1.6', '1.6'),
|
||||
('1.7', '1.11'), ('1.8', '1.12')],
|
||||
('1.7', '1.11'), ('1.8', '1.12'), ('1.9', '1.13')],
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
@ -175,6 +176,7 @@ class FloatingIPList(obj_base.ObjectListBase, obj_base.NovaObject):
|
|||
# Version 1.7: FloatingIP 1.6
|
||||
# Version 1.8: FloatingIP 1.7
|
||||
# Version 1.9: FloatingIP 1.8
|
||||
# Version 1.10: FloatingIP 1.9
|
||||
fields = {
|
||||
'objects': fields.ListOfObjectsField('FloatingIP'),
|
||||
}
|
||||
|
@ -182,9 +184,9 @@ class FloatingIPList(obj_base.ObjectListBase, obj_base.NovaObject):
|
|||
'objects': [('1.0', '1.0'), ('1.1', '1.1'), ('1.2', '1.1'),
|
||||
('1.3', '1.2'), ('1.4', '1.3'), ('1.5', '1.4'),
|
||||
('1.6', '1.5'), ('1.7', '1.6'), ('1.8', '1.7'),
|
||||
('1.9', '1.8')],
|
||||
('1.9', '1.8'), ('1.10', '1.9')],
|
||||
}
|
||||
VERSION = '1.9'
|
||||
VERSION = '1.10'
|
||||
|
||||
@obj_base.remotable_classmethod
|
||||
def get_all(cls, context):
|
||||
|
|
|
@ -26,7 +26,7 @@ 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
|
||||
from nova.i18n import _LE, _LW
|
||||
from nova import notifications
|
||||
from nova import objects
|
||||
from nova.objects import base
|
||||
|
@ -47,7 +47,7 @@ _INSTANCE_OPTIONAL_NON_COLUMN_FIELDS = ['fault', 'flavor', 'old_flavor',
|
|||
'new_flavor', 'ec2_ids']
|
||||
# These are fields that are optional and in instance_extra
|
||||
_INSTANCE_EXTRA_FIELDS = ['numa_topology', 'pci_requests',
|
||||
'flavor', 'vcpu_model']
|
||||
'flavor', 'vcpu_model', 'migration_context']
|
||||
|
||||
# These are fields that can be specified as expected_attrs
|
||||
INSTANCE_OPTIONAL_ATTRS = (_INSTANCE_OPTIONAL_JOINED_FIELDS +
|
||||
|
@ -79,6 +79,9 @@ def _expected_cols(expected_attrs):
|
|||
return simple_cols + complex_cols
|
||||
|
||||
|
||||
_NO_DATA_SENTINEL = object()
|
||||
|
||||
|
||||
# TODO(berrange): Remove NovaObjectDictCompat
|
||||
@base.NovaObjectRegistry.register
|
||||
class Instance(base.NovaPersistentObject, base.NovaObject,
|
||||
|
@ -108,7 +111,8 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
|
|||
# Version 1.20: Added ec2_ids
|
||||
# Version 1.21: TagList 1.1
|
||||
# Version 1.22: InstanceNUMATopology 1.2
|
||||
VERSION = '1.22'
|
||||
# Version 1.23: Added migration_context
|
||||
VERSION = '1.23'
|
||||
|
||||
fields = {
|
||||
'id': fields.IntegerField(),
|
||||
|
@ -206,6 +210,8 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
|
|||
'new_flavor': fields.ObjectField('Flavor', nullable=True),
|
||||
'vcpu_model': fields.ObjectField('VirtCPUModel', nullable=True),
|
||||
'ec2_ids': fields.ObjectField('EC2Ids'),
|
||||
'migration_context': fields.ObjectField('MigrationContext',
|
||||
nullable=True)
|
||||
}
|
||||
|
||||
obj_extra_fields = ['name']
|
||||
|
@ -223,6 +229,7 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
|
|||
'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 __init__(self, *args, **kwargs):
|
||||
|
@ -384,6 +391,12 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
|
|||
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['info_cache'] is None:
|
||||
instance.info_cache = None
|
||||
|
@ -604,6 +617,14 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
|
|||
# NOTE(hanlind): Read-only so no need to save this.
|
||||
pass
|
||||
|
||||
def _save_migration_context(self, context):
|
||||
if self.migration_context:
|
||||
self.migration_context.instance_uuid = self.uuid
|
||||
with self.migration_context.obj_alternate_context(context):
|
||||
self.migration_context._save()
|
||||
else:
|
||||
objects.MigrationContext._destroy(context, self.uuid)
|
||||
|
||||
@base.remotable
|
||||
def save(self, expected_vm_state=None,
|
||||
expected_task_state=None, admin_state_reset=False):
|
||||
|
@ -848,6 +869,42 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
|
|||
def _load_ec2_ids(self):
|
||||
self.ec2_ids = objects.EC2Ids.get_by_instance(self._context, self)
|
||||
|
||||
def _load_migration_context(self, db_context=_NO_DATA_SENTINEL):
|
||||
if db_context is _NO_DATA_SENTINEL:
|
||||
try:
|
||||
self.migration_context = (
|
||||
objects.MigrationContext.get_by_instance_uuid(
|
||||
self._context, self.uuid))
|
||||
except exception.MigrationContextNotFound:
|
||||
self.migration_context = None
|
||||
elif db_context is None:
|
||||
self.migration_context = None
|
||||
else:
|
||||
self.migration_context = objects.MigrationContext.obj_from_db_obj(
|
||||
db_context)
|
||||
|
||||
def apply_migration_context(self):
|
||||
if self.migration_context:
|
||||
self.numa_topology = self.migration_context.new_numa_topology
|
||||
else:
|
||||
LOG.warn(_LW("Trying to apply a migration context that does not "
|
||||
"seem to be set for this instance"),
|
||||
instance=self)
|
||||
|
||||
def revert_migration_context(self):
|
||||
if self.migration_context:
|
||||
self.numa_topology = self.migration_context.old_numa_topology
|
||||
else:
|
||||
LOG.warn(_LW("Trying to revert a migration context that does not "
|
||||
"seem to be set for this instance"),
|
||||
instance=self)
|
||||
|
||||
@base.remotable
|
||||
def drop_migration_context(self):
|
||||
if self.migration_context:
|
||||
objects.MigrationContext._destroy(self._context, self.uuid)
|
||||
self.migration_context = None
|
||||
|
||||
def obj_load_attr(self, attrname):
|
||||
if attrname not in INSTANCE_OPTIONAL_ATTRS:
|
||||
raise exception.ObjectActionError(
|
||||
|
@ -876,6 +933,8 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
|
|||
self._load_vcpu_model()
|
||||
elif attrname == 'ec2_ids':
|
||||
self._load_ec2_ids()
|
||||
elif attrname == 'migration_context':
|
||||
self._load_migration_context()
|
||||
elif 'flavor' in attrname:
|
||||
self._load_flavor()
|
||||
else:
|
||||
|
@ -1024,7 +1083,8 @@ class InstanceList(base.ObjectListBase, base.NovaObject):
|
|||
# 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.21'
|
||||
# Version 1.22: Instance <= version 1.23
|
||||
VERSION = '1.22'
|
||||
|
||||
fields = {
|
||||
'objects': fields.ListOfObjectsField('Instance'),
|
||||
|
@ -1037,7 +1097,8 @@ class InstanceList(base.ObjectListBase, base.NovaObject):
|
|||
('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.19', '1.21'), ('1.20', '1.22'), ('1.21', '1.22'),
|
||||
('1.22', '1.23')],
|
||||
}
|
||||
|
||||
@base.remotable_classmethod
|
||||
|
|
|
@ -40,6 +40,7 @@ from nova.tests.unit.objects import test_instance_fault
|
|||
from nova.tests.unit.objects import test_instance_info_cache
|
||||
from nova.tests.unit.objects import test_instance_numa_topology
|
||||
from nova.tests.unit.objects import test_instance_pci_requests
|
||||
from nova.tests.unit.objects import test_migration_context as test_mig_ctxt
|
||||
from nova.tests.unit.objects import test_objects
|
||||
from nova.tests.unit.objects import test_security_group
|
||||
from nova.tests.unit.objects import test_vcpu_model
|
||||
|
@ -132,9 +133,11 @@ class _TestInstanceObject(object):
|
|||
exp_cols.remove('pci_requests')
|
||||
exp_cols.remove('vcpu_model')
|
||||
exp_cols.remove('ec2_ids')
|
||||
exp_cols.remove('migration_context')
|
||||
exp_cols = list(filter(lambda x: 'flavor' not in x, exp_cols))
|
||||
exp_cols.extend(['extra', 'extra.numa_topology', 'extra.pci_requests',
|
||||
'extra.flavor', 'extra.vcpu_model'])
|
||||
'extra.flavor', 'extra.vcpu_model',
|
||||
'extra.migration_context'])
|
||||
|
||||
fake_topology = (test_instance_numa_topology.
|
||||
fake_db_topology['numa_topology'])
|
||||
|
@ -145,12 +148,15 @@ class _TestInstanceObject(object):
|
|||
'old': None, 'new': None})
|
||||
fake_vcpu_model = jsonutils.dumps(
|
||||
test_vcpu_model.fake_vcpumodel.obj_to_primitive())
|
||||
fake_mig_context = jsonutils.dumps(
|
||||
test_mig_ctxt.fake_migration_context_obj.obj_to_primitive())
|
||||
fake_instance = dict(self.fake_instance,
|
||||
extra={
|
||||
'numa_topology': fake_topology,
|
||||
'pci_requests': fake_requests,
|
||||
'flavor': fake_flavor,
|
||||
'vcpu_model': fake_vcpu_model,
|
||||
'migration_context': fake_mig_context,
|
||||
})
|
||||
db.instance_get_by_uuid(
|
||||
self.context, 'uuid',
|
||||
|
@ -502,6 +508,28 @@ class _TestInstanceObject(object):
|
|||
mock_update.assert_called_once_with(
|
||||
self.context, inst.uuid, {'vcpu_model': None})
|
||||
|
||||
@mock.patch('nova.db.instance_extra_update_by_uuid')
|
||||
def test_save_migration_context_model(self, mock_update):
|
||||
inst = fake_instance.fake_instance_obj(self.context)
|
||||
inst.migration_context = test_mig_ctxt.get_fake_migration_context_obj(
|
||||
self.context)
|
||||
inst.save()
|
||||
self.assertTrue(mock_update.called)
|
||||
self.assertEqual(mock_update.call_count, 1)
|
||||
actual_args = mock_update.call_args
|
||||
self.assertEqual(self.context, actual_args[0][0])
|
||||
self.assertEqual(inst.uuid, actual_args[0][1])
|
||||
self.assertEqual(list(actual_args[0][2].keys()), ['migration_context'])
|
||||
self.assertIsInstance(
|
||||
objects.MigrationContext.obj_from_db_obj(
|
||||
actual_args[0][2]['migration_context']),
|
||||
objects.MigrationContext)
|
||||
mock_update.reset_mock()
|
||||
inst.migration_context = None
|
||||
inst.save()
|
||||
mock_update.assert_called_once_with(
|
||||
self.context, inst.uuid, {'migration_context': None})
|
||||
|
||||
def test_save_flavor_skips_unchanged_flavors(self):
|
||||
inst = objects.Instance(context=self.context,
|
||||
flavor=objects.Flavor())
|
||||
|
@ -1160,6 +1188,61 @@ class _TestInstanceObject(object):
|
|||
inst.ec2_ids
|
||||
mock_load.assert_called_once_with()
|
||||
|
||||
def test_load_migration_context(self):
|
||||
inst = instance.Instance(context=self.context,
|
||||
uuid='fake-uuid')
|
||||
with mock.patch.object(
|
||||
objects.MigrationContext, 'get_by_instance_uuid',
|
||||
return_value=test_mig_ctxt.fake_migration_context_obj
|
||||
) as mock_get:
|
||||
inst.migration_context
|
||||
mock_get.assert_called_once_with(self.context, inst.uuid)
|
||||
|
||||
def test_load_migration_context_no_context(self):
|
||||
inst = instance.Instance(context=self.context,
|
||||
uuid='fake-uuid')
|
||||
with mock.patch.object(
|
||||
objects.MigrationContext, 'get_by_instance_uuid',
|
||||
side_effect=exception.MigrationContextNotFound(
|
||||
instance_uuid=inst.uuid)
|
||||
) as mock_get:
|
||||
mig_ctxt = inst.migration_context
|
||||
mock_get.assert_called_once_with(self.context, inst.uuid)
|
||||
self.assertIsNone(mig_ctxt)
|
||||
|
||||
def test_load_migration_context_no_data(self):
|
||||
inst = instance.Instance(context=self.context,
|
||||
uuid='fake-uuid')
|
||||
with mock.patch.object(
|
||||
objects.MigrationContext, 'get_by_instance_uuid') as mock_get:
|
||||
loaded_ctxt = inst._load_migration_context(db_context=None)
|
||||
self.assertFalse(mock_get.called)
|
||||
self.assertIsNone(loaded_ctxt)
|
||||
|
||||
def test_apply_revert_migration_context(self):
|
||||
inst = instance.Instance(context=self.context,
|
||||
uuid='fake-uuid', numa_topology=None)
|
||||
inst.migration_context = test_mig_ctxt.get_fake_migration_context_obj(
|
||||
self.context)
|
||||
inst.apply_migration_context()
|
||||
self.assertIsInstance(inst.numa_topology, objects.InstanceNUMATopology)
|
||||
inst.revert_migration_context()
|
||||
self.assertIsNone(inst.numa_topology)
|
||||
|
||||
def test_drop_migration_context(self):
|
||||
inst = instance.Instance(context=self.context,
|
||||
uuid='fake-uuid')
|
||||
inst.migration_context = test_mig_ctxt.get_fake_migration_context_obj(
|
||||
self.context)
|
||||
inst.migration_context.instance_uuid = inst.uuid
|
||||
inst.migration_context.id = 7
|
||||
with mock.patch(
|
||||
'nova.db.instance_extra_update_by_uuid') as update_extra:
|
||||
inst.drop_migration_context()
|
||||
self.assertIsNone(inst.migration_context)
|
||||
update_extra.assert_called_once_with(self.context, inst.uuid,
|
||||
{"migration_context": None})
|
||||
|
||||
@mock.patch.object(objects.Instance, 'get_by_uuid')
|
||||
def test_load_generic(self, mock_get):
|
||||
inst2 = instance.Instance(metadata={'foo': 'bar'})
|
||||
|
|
|
@ -1129,8 +1129,8 @@ object_data = {
|
|||
'AggregateList': '1.2-fb6e19f3c3a3186b04eceb98b5dadbfa',
|
||||
'BandwidthUsage': '1.2-c6e4c779c7f40f2407e3d70022e3cd1c',
|
||||
'BandwidthUsageList': '1.2-5fe7475ada6fe62413cbfcc06ec70746',
|
||||
'BlockDeviceMapping': '1.14-d44d8d694619e79c172a99b3c1d6261d',
|
||||
'BlockDeviceMappingList': '1.15-6fa262c059dad1d519b9fe05b9e4f404',
|
||||
'BlockDeviceMapping': '1.15-d44d8d694619e79c172a99b3c1d6261d',
|
||||
'BlockDeviceMappingList': '1.16-6fa262c059dad1d519b9fe05b9e4f404',
|
||||
'CellMapping': '1.0-7f1a7e85a22bbb7559fc730ab658b9bd',
|
||||
'ComputeNode': '1.14-a396975707b66281c5f404a68fccd395',
|
||||
'ComputeNodeList': '1.14-3b6f4f5ade621c40e70cb116db237844',
|
||||
|
@ -1140,17 +1140,17 @@ object_data = {
|
|||
'EC2InstanceMapping': '1.0-a4556eb5c5e94c045fe84f49cf71644f',
|
||||
'EC2SnapshotMapping': '1.0-47e7ddabe1af966dce0cfd0ed6cd7cd1',
|
||||
'EC2VolumeMapping': '1.0-5b713751d6f97bad620f3378a521020d',
|
||||
'FixedIP': '1.12-b5818a33996228fc146f096d1403742c',
|
||||
'FixedIPList': '1.12-87a39361c8f08f059004d6b15103cdfd',
|
||||
'FixedIP': '1.13-b5818a33996228fc146f096d1403742c',
|
||||
'FixedIPList': '1.13-87a39361c8f08f059004d6b15103cdfd',
|
||||
'Flavor': '1.1-b6bb7a730a79d720344accefafacf7ee',
|
||||
'FlavorList': '1.1-52b5928600e7ca973aa4fc1e46f3934c',
|
||||
'FloatingIP': '1.8-52a67d52d85eb8b3f324a5b7935a335b',
|
||||
'FloatingIPList': '1.9-7f2ba670714e1b7bab462ab3290f7159',
|
||||
'FloatingIP': '1.9-52a67d52d85eb8b3f324a5b7935a335b',
|
||||
'FloatingIPList': '1.10-7f2ba670714e1b7bab462ab3290f7159',
|
||||
'HostMapping': '1.0-1a3390a696792a552ab7bd31a77ba9ac',
|
||||
'HVSpec': '1.1-6b4f7c0f688cbd03e24142a44eb9010d',
|
||||
'ImageMeta': '1.6-642d1b2eb3e880a367f37d72dd76162d',
|
||||
'ImageMetaProps': '1.6-07a6d9f3576c4927220331584661ce45',
|
||||
'Instance': '1.22-260d385315d4868b6397c61a13109841',
|
||||
'Instance': '1.23-4e68422207667f4abff5fa730a5edc98',
|
||||
'InstanceAction': '1.1-f9f293e526b66fca0d05c3b3a2d13914',
|
||||
'InstanceActionEvent': '1.1-e56a64fa4710e43ef7af2ad9d6028b33',
|
||||
'InstanceActionEventList': '1.1-13d92fb953030cdbfee56481756e02be',
|
||||
|
@ -1161,7 +1161,7 @@ object_data = {
|
|||
'InstanceGroup': '1.10-1a0c8c7447dc7ecb9da53849430c4a5f',
|
||||
'InstanceGroupList': '1.7-be18078220513316abd0ae1b2d916873',
|
||||
'InstanceInfoCache': '1.5-cd8b96fefe0fc8d4d337243ba0bf0e1e',
|
||||
'InstanceList': '1.21-6c8ba6147cca3082b1e4643f795068bf',
|
||||
'InstanceList': '1.22-6c8ba6147cca3082b1e4643f795068bf',
|
||||
'InstanceMapping': '1.0-47ef26034dfcbea78427565d9177fe50',
|
||||
'InstanceMappingList': '1.0-9e982e3de1613b9ada85e35f69b23d47',
|
||||
'InstanceNUMACell': '1.2-535ef30e0de2d6a0d26a71bd58ecafc4',
|
||||
|
|
Loading…
Reference in New Issue