from neutron.extensions import providernet as provider
from neutron import manager
from neutron.openstack.common import excutils
+from neutron.openstack.common.gettextutils import _LI
from neutron.openstack.common import importutils
from neutron.openstack.common import jsonutils
from neutron.openstack.common import lockutils
cur_binding = db.get_dvr_port_binding_by_host(session,
port_id,
host)
+ if not cur_binding:
+ LOG.info(_LI("Binding info for port %s was not found, "
+ "it might have been deleted already."),
+ port_id)
+ return
# Commit our binding results only if port has not been
# successfully bound concurrently by another thread or
# process and no binding inputs have been changed.
filter(models_v2.Port.id.startswith(port_id)).
one())
except sa_exc.NoResultFound:
+ LOG.debug("No ports have port_id starting with %s",
+ port_id)
return
except exc.MultipleResultsFound:
LOG.error(_("Multiple ports have port_id starting with %s"),
port_context = driver_context.DvrPortContext(
self, plugin_context, port, network, binding)
else:
+ # since eager loads are disabled in port_db query
+ # related attribute port_binding could disappear in
+ # concurrent port deletion.
+ # It's not an error condition.
+ binding = port_db.port_binding
+ if not binding:
+ LOG.info(_LI("Binding info for port %s was not found, "
+ "it might have been deleted already."),
+ port_id)
+ return
port_context = driver_context.PortContext(
- self, plugin_context, port, network, port_db.port_binding)
+ self, plugin_context, port, network, binding)
return self._bind_port_if_needed(port_context)
from neutron.extensions import portbindings
from neutron import manager
from neutron.plugins.ml2 import config as config
+from neutron.plugins.ml2 import models as ml2_models
from neutron.tests.unit import test_db_plugin as test_plugin
portbindings.VIF_TYPE_OVS,
True, True, 'ACTIVE')
+ def test_update_port_binding_no_binding(self):
+ ctx = context.get_admin_context()
+ with self.port(name='name') as port:
+ # emulating concurrent binding deletion
+ (ctx.session.query(ml2_models.PortBinding).
+ filter_by(port_id=port['port']['id']).delete())
+ self.assertIsNone(
+ self.plugin.get_bound_port_context(ctx, port['port']['id']))
+
+ def test_commit_dvr_port_binding(self):
+ ctx = context.get_admin_context()
+
+ class MechContext(object):
+ pass
+
+ mctx = MechContext()
+ mctx._binding = None
+ # making a shortcut: calling private method directly to
+ # avoid bothering with "concurrent" port binding deletion
+ res = self.plugin._commit_dvr_port_binding(ctx, 'anyUUID',
+ 'HostA', mctx)
+ self.assertIsNone(res)
+
def _test_update_port_binding(self, host, new_host=None):
with mock.patch.object(self.plugin,
'_notify_port_updated') as notify_mock: