From a93abbbfef7f0b88be0ad42048d52b658c29e1c4 Mon Sep 17 00:00:00 2001 From: Kevin Benton Date: Thu, 16 Oct 2014 02:10:36 -0700 Subject: [PATCH] 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 --- neutron/db/l3_dvrscheduler_db.py | 11 ++++++++--- neutron/tests/unit/test_l3_schedulers.py | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/neutron/db/l3_dvrscheduler_db.py b/neutron/db/l3_dvrscheduler_db.py index 8aab28d36..ca6ed9509 100644 --- a/neutron/db/l3_dvrscheduler_db.py +++ b/neutron/db/l3_dvrscheduler_db.py @@ -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) diff --git a/neutron/tests/unit/test_l3_schedulers.py b/neutron/tests/unit/test_l3_schedulers.py index c6c1a10da..99b5ebc52 100644 --- a/neutron/tests/unit/test_l3_schedulers.py +++ b/neutron/tests/unit/test_l3_schedulers.py @@ -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', -- 2.45.2