|
|
|
@ -17,14 +17,9 @@ from oslo_db import exception as db_exc
|
|
|
|
|
from oslo_log import log
|
|
|
|
|
|
|
|
|
|
from neutron.common import exceptions as exc
|
|
|
|
|
from neutron.i18n import _LW
|
|
|
|
|
from neutron.plugins.ml2 import driver_api as api
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Number of attempts to find a valid segment candidate and allocate it
|
|
|
|
|
DB_MAX_ATTEMPTS = 10
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -108,37 +103,32 @@ class TypeDriverHelper(api.TypeDriver):
|
|
|
|
|
filter_by(allocated=False, **filters))
|
|
|
|
|
|
|
|
|
|
# Selected segment can be allocated before update by someone else,
|
|
|
|
|
# We retry until update success or DB_MAX_ATTEMPTS attempts
|
|
|
|
|
for attempt in range(1, DB_MAX_ATTEMPTS + 1):
|
|
|
|
|
alloc = select.first()
|
|
|
|
|
|
|
|
|
|
if not alloc:
|
|
|
|
|
# No resource available
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
raw_segment = dict((k, alloc[k]) for k in self.primary_keys)
|
|
|
|
|
LOG.debug("%(type)s segment allocate from pool, attempt "
|
|
|
|
|
"%(attempt)s started with %(segment)s ",
|
|
|
|
|
{"type": network_type, "attempt": attempt,
|
|
|
|
|
alloc = select.first()
|
|
|
|
|
|
|
|
|
|
if not alloc:
|
|
|
|
|
# No resource available
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
raw_segment = dict((k, alloc[k]) for k in self.primary_keys)
|
|
|
|
|
LOG.debug("%(type)s segment allocate from pool "
|
|
|
|
|
"started with %(segment)s ",
|
|
|
|
|
{"type": network_type,
|
|
|
|
|
"segment": raw_segment})
|
|
|
|
|
count = (session.query(self.model).
|
|
|
|
|
filter_by(allocated=False, **raw_segment).
|
|
|
|
|
update({"allocated": True}))
|
|
|
|
|
if count:
|
|
|
|
|
LOG.debug("%(type)s segment allocate from pool "
|
|
|
|
|
"success with %(segment)s ",
|
|
|
|
|
{"type": network_type,
|
|
|
|
|
"segment": raw_segment})
|
|
|
|
|
count = (session.query(self.model).
|
|
|
|
|
filter_by(allocated=False, **raw_segment).
|
|
|
|
|
update({"allocated": True}))
|
|
|
|
|
if count:
|
|
|
|
|
LOG.debug("%(type)s segment allocate from pool, attempt "
|
|
|
|
|
"%(attempt)s success with %(segment)s ",
|
|
|
|
|
{"type": network_type, "attempt": attempt,
|
|
|
|
|
"segment": raw_segment})
|
|
|
|
|
return alloc
|
|
|
|
|
|
|
|
|
|
# Segment allocated since select
|
|
|
|
|
LOG.debug("Allocate %(type)s segment from pool, "
|
|
|
|
|
"attempt %(attempt)s failed with segment "
|
|
|
|
|
"%(segment)s",
|
|
|
|
|
{"type": network_type, "attempt": attempt,
|
|
|
|
|
"segment": raw_segment})
|
|
|
|
|
|
|
|
|
|
LOG.warning(_LW("Allocate %(type)s segment from pool failed "
|
|
|
|
|
"after %(number)s failed attempts"),
|
|
|
|
|
{"type": network_type, "number": DB_MAX_ATTEMPTS})
|
|
|
|
|
raise exc.NoNetworkFoundInMaximumAllowedAttempts()
|
|
|
|
|
return alloc
|
|
|
|
|
|
|
|
|
|
# Segment allocated since select
|
|
|
|
|
LOG.debug("Allocate %(type)s segment from pool "
|
|
|
|
|
"failed with segment %(segment)s",
|
|
|
|
|
{"type": network_type,
|
|
|
|
|
"segment": raw_segment})
|
|
|
|
|
# saving real exception in case we exceeded amount of attempts
|
|
|
|
|
raise db_exc.RetryRequest(
|
|
|
|
|
exc.NoNetworkFoundInMaximumAllowedAttempts())
|
|
|
|
|