Fix migrate_flavor_data() to catch instances with no instance_extra rows
The way the query was being performed previously, we would not see any
instances that didn't have a row in instance_extra. This could happen if
an instance hasn't been touched for several releases, or if the data
set is old.
The fix is a simple change to use outerjoin instead of join. This patch
includes a test that ensures that instances with no instance_extra rows
are included in the migration. If we query an instance without such a
row, we create it before doing a save on the instance.
Closes-Bug: #1447132
Change-Id: I2620a8a4338f5c493350f26cdba3e41f3cb28de7
(cherry picked from commit 92714accc4
)
This commit is contained in:
parent
a0efbbcfc7
commit
a2872a9262
|
@ -6041,7 +6041,7 @@ def migrate_flavor_data(context, max_count, flavor_cache):
|
|||
from nova import objects
|
||||
|
||||
query = _instance_get_all_query(context, joins=['extra', 'extra.flavor']).\
|
||||
join(models.Instance.extra).\
|
||||
outerjoin(models.Instance.extra).\
|
||||
filter(models.InstanceExtra.flavor.is_(None))
|
||||
if max_count is not None:
|
||||
instances = query.limit(max_count)
|
||||
|
@ -6069,6 +6069,11 @@ def migrate_flavor_data(context, max_count, flavor_cache):
|
|||
|
||||
_augment_flavors_to_migrate(instance, flavor_cache)
|
||||
if instance.obj_what_changed():
|
||||
if db_instance.get('extra') is None:
|
||||
_instance_extra_create(context,
|
||||
{'instance_uuid': db_instance['uuid']})
|
||||
LOG.debug(
|
||||
'Created instance_extra for %s' % db_instance['uuid'])
|
||||
instance.save(expected_task_state=[None])
|
||||
count_hit += 1
|
||||
|
||||
|
|
|
@ -7629,6 +7629,31 @@ class FlavorMigrationTestCase(test.TestCase):
|
|||
self.assertEqual(3, match)
|
||||
self.assertEqual(0, done)
|
||||
|
||||
def test_migrate_flavor_gets_missing_extra_rows(self):
|
||||
ctxt = context.get_admin_context()
|
||||
flavor = flavors.get_default_flavor()
|
||||
sysmeta = flavors.save_flavor_info({}, flavor)
|
||||
values1 = {'uuid': str(stdlib_uuid.uuid4()),
|
||||
'system_metadata': sysmeta,
|
||||
'extra': {'flavor': None},
|
||||
}
|
||||
db.instance_create(ctxt, values1)
|
||||
values2 = {'uuid': str(stdlib_uuid.uuid4()),
|
||||
'system_metadata': sysmeta,
|
||||
}
|
||||
inst2 = db.instance_create(ctxt, values2)
|
||||
sqlalchemy_api.model_query(ctxt, models.InstanceExtra).\
|
||||
filter_by(instance_uuid=inst2.uuid).delete()
|
||||
|
||||
self.assertIsNone(db.instance_extra_get_by_instance_uuid(
|
||||
ctxt, inst2.uuid))
|
||||
match, done = db.migrate_flavor_data(ctxt, None, {})
|
||||
self.assertEqual(2, match)
|
||||
self.assertEqual(2, done)
|
||||
extra = db.instance_extra_get_by_instance_uuid(ctxt, inst2.uuid)
|
||||
self.assertIsNotNone(extra)
|
||||
self.assertIsNotNone(extra.flavor)
|
||||
|
||||
|
||||
class ArchiveTestCase(test.TestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue