Skip to content

Commit 72f9aa7

Browse files
melwittmriedem
authored andcommitted
Don't generate service UUID for deleted services
In Pike, we added a UUID field to services and during an upgrade from Ocata => Pike, when instances are accessed joined with their associated services, we generate a UUID for the services on-the-fly. This causes a problem in the scenario where an operator upgrades their cluster and has old, deleted services with hostnames matching existing services associated with instances. When we go to generate the service UUID for the old, deleted service, we hit a ServiceTooOld exception. This addresses the problem by not bothering to generate a UUID for a deleted service. One alternative would be to exclude deleted services when we join the 'instances' and 'services' tables, but I'm not sure whether that approach might cause unintended effects where service information that used to be viewable for instances becomes hidden. Closes-Bug: #1778305 Closes-Bug: #1764556 Conflicts: nova/tests/functional/regressions/test_bug_1764556.py NOTE(mriedem): The conflict is due to eadd78e removing the func_fixtures import. Change-Id: I347096a527c257075cefe7b81210622f6cd87daf (cherry picked from commit 16e1630) (cherry picked from commit 8601ca75b1515e7434f1d3c563a0e65458c8c86a)
1 parent 252118a commit 72f9aa7

File tree

3 files changed

+13
-26
lines changed

3 files changed

+13
-26
lines changed

nova/objects/service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ def _from_db_object(context, service, db_service):
272272
service.obj_reset_changes()
273273

274274
# TODO(dpeschman): Drop this once all services have uuids in database
275-
if 'uuid' not in service:
275+
if 'uuid' not in service and not service.deleted:
276276
service.uuid = uuidutils.generate_uuid()
277277
LOG.debug('Generated UUID %(uuid)s for service %(id)i',
278278
dict(uuid=service.uuid, id=service.id))

nova/tests/functional/regressions/test_bug_1764556.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,10 @@
1010
# License for the specific language governing permissions and limitations
1111
# under the License.
1212

13-
import six
14-
1513
from nova import context as nova_context
1614
from nova.db import api as db
1715
from nova import test
1816
from nova.tests import fixtures as nova_fixtures
19-
from nova.tests.functional.api import client as api_client
2017
from nova.tests.functional import integrated_helpers
2118
from nova.tests.unit.image import fake as fake_image
2219
from nova.tests.unit import policy_fixture
@@ -153,10 +150,6 @@ def test_instance_list_deleted_service_with_no_uuid(self):
153150

154151
# Finally, list servers as an admin so it joins on services to get host
155152
# information.
156-
# FIXME(mriedem): This is bug 1764556 where the join on the services
157-
# table also pulls the deleted service that doesn't have a uuid and
158-
# attempts to migrate that service to have a uuid, which fails because
159-
# it's not using a read_deleted='yes' context.
160-
ex = self.assertRaises(api_client.OpenStackApiException,
161-
self.admin_api.get_servers, detail=True)
162-
self.assertIn('ServiceNotFound', six.text_type(ex))
153+
servers = self.admin_api.get_servers(detail=True)
154+
for server in servers:
155+
self.assertEqual('UP', server['host_status'])

nova/tests/functional/regressions/test_bug_1778305.py

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,13 @@ def test_instance_list_old_deleted_service_with_no_uuid(self):
4949
host='fake-host')
5050
inst.create()
5151

52-
# TODO(melwitt): Remove this assert when the bug is fixed.
53-
self.assertRaises(nova.exception.ServiceTooOld,
54-
objects.InstanceList.get_by_filters,
55-
self.context, {}, expected_attrs=['services'])
56-
57-
# TODO(melwitt): Uncomment these asserts when the bug is fixed.
58-
# insts = objects.InstanceList.get_by_filters(
59-
# self.context, {}, expected_attrs=['services'])
60-
# self.assertEqual(1, len(insts))
61-
# self.assertEqual(2, len(insts[0].services))
52+
insts = objects.InstanceList.get_by_filters(
53+
self.context, {}, expected_attrs=['services'])
54+
self.assertEqual(1, len(insts))
55+
self.assertEqual(2, len(insts[0].services))
6256
# Deleted service should not have a UUID
63-
# for service in insts[0].services:
64-
# if service.deleted:
65-
# self.assertNotIn('uuid', service)
66-
# else:
67-
# self.assertIsNotNone(service.uuid)
57+
for service in insts[0].services:
58+
if service.deleted:
59+
self.assertNotIn('uuid', service)
60+
else:
61+
self.assertIsNotNone(service.uuid)

0 commit comments

Comments
 (0)