From 2cef12aeb25f6f024c0507c26b166d41d85bdd64 Mon Sep 17 00:00:00 2001 From: Yalei Wang Date: Wed, 11 Nov 2015 23:50:20 +0800 Subject: [PATCH] Add the missing arg of RetryRequest exception in _lock_subnetpool RetryRequest exception defined in oslo.db need be called with a arg which describes the inner exception. _lock_subnetpool method missed this arg, and this patch adds it. Change-Id: I44869c97ecd7d59d40d8793c71515067a237150b Closes-Bug: #1506818 --- neutron/common/exceptions.py | 10 ++++++++++ neutron/ipam/subnet_alloc.py | 3 ++- neutron/tests/unit/ipam/test_subnet_alloc.py | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/neutron/common/exceptions.py b/neutron/common/exceptions.py index a5752e58de4..69acf4e3661 100644 --- a/neutron/common/exceptions.py +++ b/neutron/common/exceptions.py @@ -161,6 +161,16 @@ class SubnetInUse(InUse): super(SubnetInUse, self).__init__(**kwargs) +class SubnetPoolInUse(InUse): + message = _("Unable to complete operation on subnet pool " + "%(subnet_pool_id)s. %(reason)s.") + + def __init__(self, **kwargs): + if 'reason' not in kwargs: + kwargs['reason'] = _("Two or more concurrent subnets allocated.") + super(SubnetPoolInUse, self).__init__(**kwargs) + + class PortInUse(InUse): message = _("Unable to complete operation on port %(port_id)s " "for network %(net_id)s. Port already has an attached " diff --git a/neutron/ipam/subnet_alloc.py b/neutron/ipam/subnet_alloc.py index 9711e89f8ff..60862abfdce 100644 --- a/neutron/ipam/subnet_alloc.py +++ b/neutron/ipam/subnet_alloc.py @@ -63,7 +63,8 @@ class SubnetAllocator(driver.Pool): id=self._subnetpool['id'], hash=current_hash) count = query.update({'hash': new_hash}) if not count: - raise db_exc.RetryRequest() + raise db_exc.RetryRequest(n_exc.SubnetPoolInUse( + subnet_pool_id=self._subnetpool['id'])) def _get_allocated_cidrs(self): query = self._context.session.query(models_v2.Subnet) diff --git a/neutron/tests/unit/ipam/test_subnet_alloc.py b/neutron/tests/unit/ipam/test_subnet_alloc.py index 79e168cef88..1c3eaf5958a 100644 --- a/neutron/tests/unit/ipam/test_subnet_alloc.py +++ b/neutron/tests/unit/ipam/test_subnet_alloc.py @@ -13,8 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +import mock import netaddr from oslo_config import cfg +from oslo_db import exception as db_exc from oslo_utils import uuidutils from neutron.api.v2 import attributes @@ -183,3 +185,15 @@ class TestSubnetAllocation(testlib_api.SqlTestCase): self.assertRaises(n_exc.SubnetPoolQuotaExceeded, sa.allocate_subnet, req) + + def test_subnetpool_concurrent_allocation_exception(self): + sp = self._create_subnet_pool(self.plugin, self.ctx, 'test-sp', + ['fe80::/48'], + 48, 6, default_quota=1) + sp = self.plugin._get_subnetpool(self.ctx, sp['id']) + sa = subnet_alloc.SubnetAllocator(sp, self.ctx) + req = ipam_req.SpecificSubnetRequest(self._tenant_id, + uuidutils.generate_uuid(), + 'fe80::/63') + with mock.patch("sqlalchemy.orm.query.Query.update", return_value=0): + self.assertRaises(db_exc.RetryRequest, sa.allocate_subnet, req)