From 3a01e33d7e4426426d913b480d202e21cdc83ae3 Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Wed, 19 Apr 2017 10:00:53 -0400 Subject: [PATCH] Add online data migration for populating services.uuid This adds the online data migration for populating the services.uuid column on older records. Part of blueprint service-hyper-uuid-in-api Change-Id: I6baf546d7075f7671df0abeb1e7d68372fd177ed --- nova/cmd/manage.py | 2 + nova/db/api.py | 4 ++ nova/db/sqlalchemy/api.py | 18 +++++++++ nova/tests/unit/db/test_db_api.py | 37 +++++++++++++++++++ ...uid-online-migration-17d48f198a6d4deb.yaml | 6 +++ 5 files changed, 67 insertions(+) create mode 100644 releasenotes/notes/service-uuid-online-migration-17d48f198a6d4deb.yaml diff --git a/nova/cmd/manage.py b/nova/cmd/manage.py index a3aad09054bc..06119cd8d7d9 100644 --- a/nova/cmd/manage.py +++ b/nova/cmd/manage.py @@ -620,6 +620,8 @@ class DbCommands(object): # NOTE(mriedem): This online migration is going to be backported to # Newton also since it's an upgrade issue when upgrading from Mitaka. build_request_obj.delete_build_requests_with_no_instance_uuid, + # Added in Pike + db.service_uuids_online_data_migration, ) def __init__(self): diff --git a/nova/db/api.py b/nova/db/api.py index 377178404bbf..83d7b10b1846 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -2057,6 +2057,10 @@ def pcidevice_online_data_migration(context, max_count): return IMPL.pcidevice_online_data_migration(context, max_count) +def service_uuids_online_data_migration(context, max_count): + return IMPL.service_uuids_online_data_migration(context, max_count) + + #################### diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 4980917378b9..a5c0720d1769 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -6524,6 +6524,24 @@ def archive_deleted_rows(max_rows=None): return table_to_rows_archived +@pick_context_manager_writer +def service_uuids_online_data_migration(context, max_count): + from nova.objects import service + + count_all = 0 + count_hit = 0 + + db_services = model_query(context, models.Service).filter_by( + uuid=None).limit(max_count) + for db_service in db_services: + count_all += 1 + service_obj = service.Service._from_db_object( + context, service.Service(), db_service) + if 'uuid' in service_obj: + count_hit += 1 + return count_all, count_hit + + #################### diff --git a/nova/tests/unit/db/test_db_api.py b/nova/tests/unit/db/test_db_api.py index 251a6def79db..33af2d768472 100644 --- a/nova/tests/unit/db/test_db_api.py +++ b/nova/tests/unit/db/test_db_api.py @@ -3764,6 +3764,43 @@ class ServiceTestCase(test.TestCase, ModelsObjectComparatorMixin): self.assertRaises(exception.ServiceTopicExists, db.service_create, self.ctxt, values) + def test_migrate_service_uuids(self): + # Start with nothing. + total, done = db.service_uuids_online_data_migration(self.ctxt, 10) + self.assertEqual(0, total) + self.assertEqual(0, done) + + # Create two services, one with a uuid and one without. + db.service_create(self.ctxt, + dict(host='host1', binary='nova-compute', + topic='compute', report_count=1, + disabled=False)) + db.service_create(self.ctxt, + dict(host='host2', binary='nova-compute', + topic='compute', report_count=1, + disabled=False, uuid=uuidsentinel.host2)) + + # Now migrate them, we should find one and update one. + total, done = db.service_uuids_online_data_migration( + self.ctxt, 10) + self.assertEqual(1, total) + self.assertEqual(1, done) + + # Get the services back to make sure the original uuid didn't change. + services = db.service_get_all_by_binary(self.ctxt, 'nova-compute') + self.assertEqual(2, len(services)) + for service in services: + if service['host'] == 'host2': + self.assertEqual(uuidsentinel.host2, service['uuid']) + else: + self.assertIsNotNone(service['uuid']) + + # Run the online migration again to see nothing was processed. + total, done = db.service_uuids_online_data_migration( + self.ctxt, 10) + self.assertEqual(0, total) + self.assertEqual(0, done) + class BaseInstanceTypeTestCase(test.TestCase, ModelsObjectComparatorMixin): def setUp(self): diff --git a/releasenotes/notes/service-uuid-online-migration-17d48f198a6d4deb.yaml b/releasenotes/notes/service-uuid-online-migration-17d48f198a6d4deb.yaml new file mode 100644 index 000000000000..b13c4e1033aa --- /dev/null +++ b/releasenotes/notes/service-uuid-online-migration-17d48f198a6d4deb.yaml @@ -0,0 +1,6 @@ +--- +upgrade: + - | + An online data migration has been added to populate the ``services.uuid`` + column in the nova database for non-deleted services records. Listing or + showing services out of the ``os-services`` API will have the same effect.