virt: Make sure block device info is persisted

There are several methods that we wrap with a @update_db decorator,
which is to say that we want the data that changed on the object to be
persisted once the method has done it's work.

However in case of exceptions, we would do some local cleanup and
propagate the exception to through the stack, which would cause the db
save to not happen (due to the way the 'update_db' decorator was
written).

This is not ideal since some of those methods such as 'attach()' do
several interaction (with the Cinder API and libvirt for example), and
making sure that results of successfull ones are persisted in case of
a non immediate failure is important for later cleanup, and keeping
the system in a consistent state.

This patch makes sure that we persist data to the DB at all times.

Change-Id: Icf8dbe4e3b7fd65b3c7a5eb479d6be15ee504253
Closes-bug: #1439282
This commit is contained in:
Nikola Dipanov
2015-04-02 12:28:16 +01:00
parent 746843d710
commit c083743062
2 changed files with 8 additions and 3 deletions

View File

@@ -356,6 +356,7 @@ class TestDriverBlockDevice(test.NoDBTestCase):
self.volume_api.check_attach(self.context, fake_volume,
instance=instance).AndRaise(
test.TestingException)
driver_bdm._bdm_obj.save().AndReturn(None)
return instance, expected_conn_info
self.virt_driver.get_volume_connector(instance).AndReturn(connector)
@@ -383,9 +384,11 @@ class TestDriverBlockDevice(test.NoDBTestCase):
self.volume_api.terminate_connection(
elevated_context, fake_volume['id'],
connector).AndReturn(None)
driver_bdm._bdm_obj.save().AndReturn(None)
return instance, expected_conn_info
if volume_attach:
driver_bdm._bdm_obj.save().AndReturn(None)
if not fail_volume_attach:
self.volume_api.attach(elevated_context, fake_volume['id'],
'fake_uuid', bdm_dict['device_name'],
@@ -395,7 +398,7 @@ class TestDriverBlockDevice(test.NoDBTestCase):
'fake_uuid', bdm_dict['device_name'],
mode=access_mode).AndRaise(
test.TestingException)
driver_bdm._bdm_obj.save().MultipleTimes().AndReturn(None)
driver_bdm._bdm_obj.save().AndReturn(None)
return instance, expected_conn_info
def test_volume_attach(self):

View File

@@ -45,8 +45,10 @@ class _NoLegacy(Exception):
def update_db(method):
@functools.wraps(method)
def wrapped(obj, context, *args, **kwargs):
ret_val = method(obj, context, *args, **kwargs)
obj.save()
try:
ret_val = method(obj, context, *args, **kwargs)
finally:
obj.save()
return ret_val
return wrapped