Fix service version to update the DB
When new code is installed with a newer service version, the version in the DB should get updated. The fix here is to: 1) eliminate the special case for 'version' in save() 2) cause version to be saved on startup Change-Id: I96fa9dabfb9b7a5f1703baf80534d8b104dab4e6 Closes-Bug: 1579839
This commit is contained in:
parent
1801a48cc6
commit
854c39e26d
@ -291,11 +291,6 @@ class Service(base.NovaPersistentObject, base.NovaObject,
|
|||||||
def save(self):
|
def save(self):
|
||||||
updates = self.obj_get_changes()
|
updates = self.obj_get_changes()
|
||||||
updates.pop('id', None)
|
updates.pop('id', None)
|
||||||
if list(updates.keys()) == ['version']:
|
|
||||||
# NOTE(danms): Since we set/dirty version in init, don't
|
|
||||||
# do a save if that's all that has changed. This keeps the
|
|
||||||
# "save is a no-op if nothing has changed" behavior.
|
|
||||||
return
|
|
||||||
self._check_minimum_version()
|
self._check_minimum_version()
|
||||||
db_service = db.service_update(self._context, self.id, updates)
|
db_service = db.service_update(self._context, self.id, updates)
|
||||||
self._from_db_object(self._context, self, db_service)
|
self._from_db_object(self._context, self, db_service)
|
||||||
|
@ -58,21 +58,12 @@ def _create_service_ref(this_service, context):
|
|||||||
return service
|
return service
|
||||||
|
|
||||||
|
|
||||||
def _update_service_ref(this_service, context):
|
def _update_service_ref(service):
|
||||||
service = objects.Service.get_by_host_and_binary(context,
|
|
||||||
this_service.host,
|
|
||||||
this_service.binary)
|
|
||||||
if not service:
|
|
||||||
LOG.error(_LE('Unable to find a service record to update for '
|
|
||||||
'%(binary)s on %(host)s'),
|
|
||||||
{'binary': this_service.binary,
|
|
||||||
'host': this_service.host})
|
|
||||||
return
|
|
||||||
if service.version != service_obj.SERVICE_VERSION:
|
if service.version != service_obj.SERVICE_VERSION:
|
||||||
LOG.info(_LI('Updating service version for %(binary)s on '
|
LOG.info(_LI('Updating service version for %(binary)s on '
|
||||||
'%(host)s from %(old)i to %(new)i'),
|
'%(host)s from %(old)i to %(new)i'),
|
||||||
{'binary': this_service.binary,
|
{'binary': service.binary,
|
||||||
'host': this_service.host,
|
'host': service.host,
|
||||||
'old': service.version,
|
'old': service.version,
|
||||||
'new': service_obj.SERVICE_VERSION})
|
'new': service_obj.SERVICE_VERSION})
|
||||||
service.version = service_obj.SERVICE_VERSION
|
service.version = service_obj.SERVICE_VERSION
|
||||||
@ -128,7 +119,10 @@ class Service(service.Service):
|
|||||||
ctxt = context.get_admin_context()
|
ctxt = context.get_admin_context()
|
||||||
self.service_ref = objects.Service.get_by_host_and_binary(
|
self.service_ref = objects.Service.get_by_host_and_binary(
|
||||||
ctxt, self.host, self.binary)
|
ctxt, self.host, self.binary)
|
||||||
if not self.service_ref:
|
if self.service_ref:
|
||||||
|
_update_service_ref(self.service_ref)
|
||||||
|
|
||||||
|
else:
|
||||||
try:
|
try:
|
||||||
self.service_ref = _create_service_ref(self, ctxt)
|
self.service_ref = _create_service_ref(self, ctxt)
|
||||||
except (exception.ServiceTopicExists,
|
except (exception.ServiceTopicExists,
|
||||||
@ -360,7 +354,9 @@ class WSGIService(service.Service):
|
|||||||
ctxt = context.get_admin_context()
|
ctxt = context.get_admin_context()
|
||||||
service_ref = objects.Service.get_by_host_and_binary(ctxt, self.host,
|
service_ref = objects.Service.get_by_host_and_binary(ctxt, self.host,
|
||||||
self.binary)
|
self.binary)
|
||||||
if not service_ref:
|
if service_ref:
|
||||||
|
_update_service_ref(service_ref)
|
||||||
|
else:
|
||||||
try:
|
try:
|
||||||
service_ref = _create_service_ref(self, ctxt)
|
service_ref = _create_service_ref(self, ctxt)
|
||||||
except (exception.ServiceTopicExists,
|
except (exception.ServiceTopicExists,
|
||||||
@ -369,7 +365,6 @@ class WSGIService(service.Service):
|
|||||||
# don't fail here.
|
# don't fail here.
|
||||||
service_ref = objects.Service.get_by_host_and_binary(
|
service_ref = objects.Service.get_by_host_and_binary(
|
||||||
ctxt, self.host, self.binary)
|
ctxt, self.host, self.binary)
|
||||||
_update_service_ref(service_ref, ctxt)
|
|
||||||
|
|
||||||
if self.manager:
|
if self.manager:
|
||||||
self.manager.init_host()
|
self.manager.init_host()
|
||||||
|
@ -447,22 +447,6 @@ class TestServiceVersion(test.TestCase):
|
|||||||
obj._from_db_object(self.ctxt, obj, fake_different_service)
|
obj._from_db_object(self.ctxt, obj, fake_different_service)
|
||||||
self.assertEqual(fake_version, obj.version)
|
self.assertEqual(fake_version, obj.version)
|
||||||
|
|
||||||
def test_save_noop_with_only_version(self):
|
|
||||||
o = objects.Service(context=self.ctxt, id=fake_service['id'])
|
|
||||||
o.obj_reset_changes(['id'])
|
|
||||||
self.assertEqual(set(['version']), o.obj_what_changed())
|
|
||||||
with mock.patch('nova.db.service_update') as mock_update:
|
|
||||||
o.save()
|
|
||||||
self.assertFalse(mock_update.called)
|
|
||||||
o.host = 'foo'
|
|
||||||
with mock.patch('nova.db.service_update') as mock_update:
|
|
||||||
mock_update.return_value = fake_service
|
|
||||||
o.save()
|
|
||||||
mock_update.assert_called_once_with(
|
|
||||||
self.ctxt, fake_service['id'],
|
|
||||||
{'version': service.SERVICE_VERSION,
|
|
||||||
'host': 'foo'})
|
|
||||||
|
|
||||||
|
|
||||||
class TestServiceStatusNotification(test.TestCase):
|
class TestServiceStatusNotification(test.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -157,6 +157,23 @@ class ServiceTestCase(test.NoDBTestCase):
|
|||||||
'nova.tests.unit.test_service.FakeManager')
|
'nova.tests.unit.test_service.FakeManager')
|
||||||
serv.start()
|
serv.start()
|
||||||
|
|
||||||
|
@mock.patch('nova.objects.service.Service.get_by_host_and_binary')
|
||||||
|
def test_start_updates_version(self, mock_get_by_host_and_binary):
|
||||||
|
# test that the service version gets updated on services startup
|
||||||
|
service_obj = mock.Mock()
|
||||||
|
service_obj.binary = 'fake-binary'
|
||||||
|
service_obj.host = 'fake-host'
|
||||||
|
service_obj.version = -42
|
||||||
|
mock_get_by_host_and_binary.return_value = service_obj
|
||||||
|
|
||||||
|
serv = service.Service(self.host, self.binary, self.topic,
|
||||||
|
'nova.tests.unit.test_service.FakeManager')
|
||||||
|
serv.start()
|
||||||
|
|
||||||
|
# test service version got updated and saved:
|
||||||
|
service_obj.save.assert_called_once()
|
||||||
|
self.assertEqual(objects.service.SERVICE_VERSION, service_obj.version)
|
||||||
|
|
||||||
def _test_service_check_create_race(self, ex):
|
def _test_service_check_create_race(self, ex):
|
||||||
self.manager_mock = self.mox.CreateMock(FakeManager)
|
self.manager_mock = self.mox.CreateMock(FakeManager)
|
||||||
self.mox.StubOutWithMock(sys.modules[__name__], 'FakeManager',
|
self.mox.StubOutWithMock(sys.modules[__name__], 'FakeManager',
|
||||||
|
Loading…
Reference in New Issue
Block a user