Rollback quota when share network create API fails.

During share network create API, if failure occurs quota is not rolled
back and its usable only after quota reservations timed out (waiting
conf.reservation_expire seconds).

Closes-bug: #1975483
Change-Id: I3de8f5bfa6ac4580da9b1012caa25657a6df71ec
This commit is contained in:
Kiran Pawar 2022-05-26 10:23:46 +00:00
parent 5e139f95b0
commit 8c854a1c68
3 changed files with 28 additions and 1 deletions

View File

@ -391,6 +391,7 @@ class ShareNetworkController(wsgi.Controller, wsgi.AdminActionsMixin):
share_network = db_api.share_network_create(
context, share_network_values)
except db_exception.DBError as e:
QUOTAS.rollback(context, reservations)
LOG.exception(e)
msg = "Could not create share network."
raise exc.HTTPInternalServerError(explanation=msg)
@ -406,7 +407,8 @@ class ShareNetworkController(wsgi.Controller, wsgi.AdminActionsMixin):
context, share_network_subnet_values)
except db_exception.DBError:
db_api.share_network_delete(context, share_network['id'])
msg = _('Could not create share network.')
QUOTAS.rollback(context, reservations)
msg = _('Could not create share network subnet.')
raise exc.HTTPInternalServerError(explanation=msg)
QUOTAS.commit(context, reservations)

View File

@ -276,6 +276,19 @@ class ShareNetworkAPITest(test.TestCase):
req,
body)
def test_create_error_on_network_creation(self):
self.mock_object(share_networks.QUOTAS, 'reserve',
mock.Mock(return_value='fake_reservation'))
self.mock_object(share_networks.QUOTAS, 'rollback')
self.mock_object(db_api, 'share_network_create',
mock.Mock(side_effect=db_exception.DBError()))
self.assertRaises(webob_exc.HTTPInternalServerError,
self.controller.create,
self.req,
self.body)
self.assertTrue(share_networks.QUOTAS.rollback.called)
def test_create_error_on_subnet_creation(self):
data = {
'neutron_net_id': 'fake',
@ -283,6 +296,9 @@ class ShareNetworkAPITest(test.TestCase):
'id': fake_share_network['id']
}
subnet_data = copy.deepcopy(data)
self.mock_object(share_networks.QUOTAS, 'reserve',
mock.Mock(return_value='fake_reservation'))
self.mock_object(share_networks.QUOTAS, 'rollback')
self.mock_object(db_api, 'share_network_create',
mock.Mock(return_value=fake_share_network))
self.mock_object(db_api, 'share_network_subnet_create',
@ -302,6 +318,7 @@ class ShareNetworkAPITest(test.TestCase):
self.context, subnet_data)
db_api.share_network_delete.assert_called_once_with(
self.context, fake_share_network['id'])
self.assertTrue(share_networks.QUOTAS.rollback.called)
def test_delete_nominal(self):
share_nw = fake_share_network.copy()

View File

@ -0,0 +1,8 @@
---
fixes:
- |
During share network create API, if either share network or share network
subnet db creation fails, manila raises an exception. However quota is not
rolled back and its usable only after quota reservations timed out (waiting
conf.reservation_expire seconds). Fixed by introducing immediate quota
rollback in case any db create api fails.