Add migration_type to Migration object
From the records that could be in the database prior to now, we can determine their type by the flavor ids on the record. So, we do that live-ly so that we don't need to (a) bother layers above with the potential for a migration_type=None and (b) do the conversion in a db migration. Note that this includes a change to the API to not show this field to the user. It will be exposed in v2.1 in a later patch. Related to blueprint robustify-evacuate Change-Id: Id78c91357c892e684cfd8eeb1f000a57180865bb
This commit is contained in:
parent
5c151d0807
commit
13fb2d26d4
|
@ -32,9 +32,12 @@ def output(migrations_obj):
|
|||
primitive objects with the only necessary fields.
|
||||
"""
|
||||
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']
|
||||
return objects
|
||||
|
||||
|
||||
|
|
|
@ -30,9 +30,12 @@ def output(migrations_obj):
|
|||
primitive objects with the only necessary fields.
|
||||
"""
|
||||
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']
|
||||
return objects
|
||||
|
||||
|
||||
|
|
|
@ -17,6 +17,14 @@ from nova import exception
|
|||
from nova import objects
|
||||
from nova.objects import base
|
||||
from nova.objects import fields
|
||||
from nova import utils
|
||||
|
||||
|
||||
def _determine_migration_type(migration):
|
||||
if migration['old_instance_type_id'] != migration['new_instance_type_id']:
|
||||
return 'resize'
|
||||
else:
|
||||
return 'migration'
|
||||
|
||||
|
||||
# TODO(berrange): Remove NovaObjectDictCompat
|
||||
|
@ -24,7 +32,8 @@ class Migration(base.NovaPersistentObject, base.NovaObject,
|
|||
base.NovaObjectDictCompat):
|
||||
# Version 1.0: Initial version
|
||||
# Version 1.1: String attributes updated to support unicode
|
||||
VERSION = '1.1'
|
||||
# Version 1.2: Added migration_type and hidden
|
||||
VERSION = '1.2'
|
||||
|
||||
fields = {
|
||||
'id': fields.IntegerField(),
|
||||
|
@ -37,16 +46,42 @@ class Migration(base.NovaPersistentObject, base.NovaObject,
|
|||
'new_instance_type_id': fields.IntegerField(nullable=True),
|
||||
'instance_uuid': fields.StringField(nullable=True),
|
||||
'status': fields.StringField(nullable=True),
|
||||
'migration_type': fields.EnumField(['migration', 'resize',
|
||||
'live-migration', 'evacuate'],
|
||||
nullable=False),
|
||||
'hidden': fields.BooleanField(nullable=False, default=False),
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _from_db_object(context, migration, db_migration):
|
||||
for key in migration.fields:
|
||||
migration[key] = db_migration[key]
|
||||
value = db_migration[key]
|
||||
if key == 'migration_type' and value is None:
|
||||
value = _determine_migration_type(db_migration)
|
||||
migration[key] = value
|
||||
|
||||
migration._context = context
|
||||
migration.obj_reset_changes()
|
||||
return migration
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
super(Migration, self).obj_make_compatible(primitive, target_version)
|
||||
target_version = utils.convert_version_to_tuple(target_version)
|
||||
if target_version < (1, 2):
|
||||
if 'migration_type' in primitive:
|
||||
del primitive['migration_type']
|
||||
del primitive['hidden']
|
||||
|
||||
def obj_load_attr(self, attrname):
|
||||
if attrname == 'migration_type':
|
||||
# NOTE(danms): The only reason we'd need to load this is if
|
||||
# some older node sent us one. So, guess the type.
|
||||
self.migration_type = _determine_migration_type(self)
|
||||
elif attrname == 'hidden':
|
||||
self.hidden = False
|
||||
else:
|
||||
super(Migration, self).obj_load_attr(attrname)
|
||||
|
||||
@base.remotable_classmethod
|
||||
def get_by_id(cls, context, migration_id):
|
||||
db_migration = db.migration_get(context, migration_id)
|
||||
|
@ -84,7 +119,8 @@ class MigrationList(base.ObjectListBase, base.NovaObject):
|
|||
# Version 1.0: Initial version
|
||||
# Migration <= 1.1
|
||||
# Version 1.1: Added use_slave to get_unconfirmed_by_dest_compute
|
||||
VERSION = '1.1'
|
||||
# Version 1.2: Migration version 1.2
|
||||
VERSION = '1.2'
|
||||
|
||||
fields = {
|
||||
'objects': fields.ListOfObjectsField('Migration'),
|
||||
|
@ -93,6 +129,7 @@ class MigrationList(base.ObjectListBase, base.NovaObject):
|
|||
'1.0': '1.1',
|
||||
# NOTE(danms): Migration was at 1.1 before we added this
|
||||
'1.1': '1.1',
|
||||
'1.2': '1.2',
|
||||
}
|
||||
|
||||
@base.remotable_classmethod
|
||||
|
|
|
@ -53,6 +53,8 @@ class MigrationsSamplesJsonTest(api_sample_base.ApiSampleTestBaseV3):
|
|||
'instance_uuid': 'instance_id_123',
|
||||
'old_instance_type_id': 1,
|
||||
'new_instance_type_id': 2,
|
||||
'migration_type': 'resize',
|
||||
'hidden': False,
|
||||
'created_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
|
||||
'updated_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
|
||||
'deleted_at': None,
|
||||
|
@ -69,6 +71,8 @@ class MigrationsSamplesJsonTest(api_sample_base.ApiSampleTestBaseV3):
|
|||
'instance_uuid': 'instance_id_456',
|
||||
'old_instance_type_id': 5,
|
||||
'new_instance_type_id': 6,
|
||||
'migration_type': 'resize',
|
||||
'hidden': False,
|
||||
'created_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
|
||||
'updated_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
|
||||
'deleted_at': None,
|
||||
|
|
|
@ -38,6 +38,8 @@ fake_migrations = [
|
|||
'instance_uuid': 'instance_id_123',
|
||||
'old_instance_type_id': 1,
|
||||
'new_instance_type_id': 2,
|
||||
'migration_type': 'resize',
|
||||
'hidden': False,
|
||||
'created_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
|
||||
'updated_at': datetime.datetime(2012, 10, 29, 13, 42, 2),
|
||||
'deleted_at': None,
|
||||
|
@ -54,6 +56,8 @@ fake_migrations = [
|
|||
'instance_uuid': 'instance_id_456',
|
||||
'old_instance_type_id': 5,
|
||||
'new_instance_type_id': 6,
|
||||
'migration_type': 'resize',
|
||||
'hidden': False,
|
||||
'created_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
|
||||
'updated_at': datetime.datetime(2013, 10, 22, 13, 42, 2),
|
||||
'deleted_at': None,
|
||||
|
|
|
@ -12,11 +12,13 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
from oslo_utils import timeutils
|
||||
|
||||
from nova import context
|
||||
from nova import db
|
||||
from nova import exception
|
||||
from nova import objects
|
||||
from nova.objects import migration
|
||||
from nova.tests.unit import fake_instance
|
||||
from nova.tests.unit.objects import test_objects
|
||||
|
@ -41,6 +43,8 @@ def fake_db_migration(**updates):
|
|||
'new_instance_type_id': 84,
|
||||
'instance_uuid': 'fake-uuid',
|
||||
'status': 'migrating',
|
||||
'migration_type': 'resize',
|
||||
'hidden': False,
|
||||
}
|
||||
|
||||
if updates:
|
||||
|
@ -173,6 +177,36 @@ class _TestMigrationObject(object):
|
|||
for index, db_migration in enumerate(db_migrations):
|
||||
self.compare_obj(migrations[index], db_migration)
|
||||
|
||||
def test_migrate_old_resize_record(self):
|
||||
db_migration = dict(fake_db_migration(), migration_type=None)
|
||||
with mock.patch('nova.db.migration_get') as fake_get:
|
||||
fake_get.return_value = db_migration
|
||||
mig = objects.Migration.get_by_id(context.get_admin_context(), 1)
|
||||
self.assertTrue(mig.obj_attr_is_set('migration_type'))
|
||||
self.assertEqual('resize', mig.migration_type)
|
||||
|
||||
def test_migrate_old_migration_record(self):
|
||||
db_migration = dict(
|
||||
fake_db_migration(), migration_type=None,
|
||||
old_instance_type_id=1, new_instance_type_id=1)
|
||||
with mock.patch('nova.db.migration_get') as fake_get:
|
||||
fake_get.return_value = db_migration
|
||||
mig = objects.Migration.get_by_id(context.get_admin_context(), 1)
|
||||
self.assertTrue(mig.obj_attr_is_set('migration_type'))
|
||||
self.assertEqual('migration', mig.migration_type)
|
||||
|
||||
def test_migrate_unset_type_resize(self):
|
||||
mig = objects.Migration(old_instance_type_id=1,
|
||||
new_instance_type_id=2)
|
||||
self.assertEqual('resize', mig.migration_type)
|
||||
self.assertTrue(mig.obj_attr_is_set('migration_type'))
|
||||
|
||||
def test_migrate_unset_type_migration(self):
|
||||
mig = objects.Migration(old_instance_type_id=1,
|
||||
new_instance_type_id=1)
|
||||
self.assertEqual('migration', mig.migration_type)
|
||||
self.assertTrue(mig.obj_attr_is_set('migration_type'))
|
||||
|
||||
|
||||
class TestMigrationObject(test_objects._LocalTest,
|
||||
_TestMigrationObject):
|
||||
|
|
|
@ -1151,8 +1151,8 @@ object_data = {
|
|||
'InstancePCIRequests': '1.1-4825b599f000538991fdc9972a92c2c6',
|
||||
'KeyPair': '1.3-2d7c9ccade5532f7cd185110a9367e6a',
|
||||
'KeyPairList': '1.2-41b7c9ab5fd2a216be4bbce011a55eff',
|
||||
'Migration': '1.1-dc2db9e6e625bd3444a5a114438b298d',
|
||||
'MigrationList': '1.1-45a973ee70500f799da67491edabc5d4',
|
||||
'Migration': '1.2-0554a9f061ec0e9fefe43773bc426fcf',
|
||||
'MigrationList': '1.2-e772d7d6ae0581ec72042d50c6bdf6ec',
|
||||
'MyObj': '1.6-fce707f79d6fee00f0ebbac98816a380',
|
||||
'MyOwnedObject': '1.0-0f3d6c028543d7f3715d121db5b8e298',
|
||||
'NUMACell': '1.2-cb9c3b08cc1c418d021492f788d04173',
|
||||
|
|
Loading…
Reference in New Issue