Catch duplicate errors scheduling SNAT service

Catch DBDuplicateEntry errors when scheduling SNAT to
a service node to prevent harmless tracebacks in the log.
These can occur if scheduling occurs concurrently,
so they are safe to ignore.

Closes-Bug: #1381958
Change-Id: If242b04b372609f640f3ce88f4245c17a45bf69d
This commit is contained in:
Kevin Benton 2014-10-16 02:10:36 -07:00 committed by Kevin Benton
parent 3ead85af42
commit a93abbbfef
2 changed files with 22 additions and 3 deletions

View File

@ -15,6 +15,7 @@
import random
from oslo.db import exception as db_exc
import sqlalchemy as sa
from sqlalchemy import orm
from sqlalchemy.orm import exc
@ -26,7 +27,7 @@ from neutron.db import agents_db
from neutron.db import l3_agentschedulers_db as l3agent_sch_db
from neutron.db import model_base
from neutron.db import models_v2
from neutron.i18n import _LW
from neutron.i18n import _LI, _LW
from neutron.openstack.common import log as logging
from neutron.plugins.ml2 import db as ml2_db
@ -299,7 +300,11 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
snat_candidates = self.get_snat_candidates(sync_router,
active_l3_agents)
if snat_candidates:
chosen_agent = self.bind_snat_servicenode(
context, router_id, snat_candidates)
try:
chosen_agent = self.bind_snat_servicenode(
context, router_id, snat_candidates)
except db_exc.DBDuplicateEntry:
LOG.info(_LI("SNAT already bound to a service node."))
return
self.bind_dvr_router_servicenode(
context, router_id, chosen_agent)

View File

@ -19,6 +19,7 @@ import uuid
import mock
from oslo.config import cfg
from oslo.db import exception as db_exc
from oslo.utils import importutils
from oslo.utils import timeutils
from sqlalchemy.orm import query
@ -970,6 +971,19 @@ class L3DvrSchedulerTestCase(testlib_api.SqlTestCase,
}
return agent, router
def test_schedule_snat_router_duplicate_entry(self):
self._prepare_schedule_snat_tests()
with contextlib.nested(
mock.patch.object(self.dut, 'get_l3_agents'),
mock.patch.object(self.dut, 'get_snat_candidates'),
mock.patch.object(self.dut, 'bind_snat_servicenode',
side_effect=db_exc.DBDuplicateEntry()),
mock.patch.object(self.dut, 'bind_dvr_router_servicenode')
) as (mock_gl3, mock_snat_canidates, mock_bind_snat, mock_bind_dvr):
self.dut.schedule_snat_router(self.adminContext, 'foo', 'bar')
self.assertTrue(mock_bind_snat.called)
self.assertFalse(mock_bind_dvr.called)
def test_schedule_router_unbind_snat_servicenode_negativetest(self):
router = {
'id': 'foo_router_id',