Rename ml2_dvr_port_bindings to make it generic

Distributed port binding need to be implemented for HA router ports
to fix bug 1522980. HA ports can use existing DVR implementation for
multiple port binding. So we have to make current DVR port binding
implementation generic, so that all distributed ports(like DVR, HA)
can use it.

As part of making it generic, we rename 'ml2_dvr_port_bindings' table
to 'ml2_distributed_port_bindings', so that all distributed ports
(DVR, HA ..) can use this table.

Partial-Bug: #1595043
Partial-Bug: #1522980
Change-Id: I24650b7dee6305f801b457c4f21c8b16fb0eb6e0
This commit is contained in:
venkata anil 2016-06-01 15:42:38 +00:00
parent 96a195c064
commit 77bfd82c3c
9 changed files with 77 additions and 34 deletions

View File

@ -1 +1 @@
8fd3918ef6f4
4bcd4df1f426

View File

@ -0,0 +1,36 @@
# Copyright 2016 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""Rename ml2_dvr_port_bindings
Revision ID: 4bcd4df1f426
Revises: 8fd3918ef6f4
Create Date: 2016-06-02 14:06:04.112998
"""
# revision identifiers, used by Alembic.
revision = '4bcd4df1f426'
down_revision = '8fd3918ef6f4'
from alembic import op
OLD_REFERRED_TABLE_NAME = 'ml2_dvr_port_bindings'
NEW_REFERRED_TABLE_NAME = 'ml2_distributed_port_bindings'
def upgrade():
op.rename_table(OLD_REFERRED_TABLE_NAME, NEW_REFERRED_TABLE_NAME)

View File

@ -119,14 +119,14 @@ def clear_binding_levels(session, port_id, host):
def ensure_dvr_port_binding(session, port_id, host, router_id=None):
record = (session.query(models.DVRPortBinding).
record = (session.query(models.DistributedPortBinding).
filter_by(port_id=port_id, host=host).first())
if record:
return record
try:
with session.begin(subtransactions=True):
record = models.DVRPortBinding(
record = models.DistributedPortBinding(
port_id=port_id,
host=host,
router_id=router_id,
@ -137,7 +137,7 @@ def ensure_dvr_port_binding(session, port_id, host, router_id=None):
return record
except db_exc.DBDuplicateEntry:
LOG.debug("DVR Port %s already bound", port_id)
return (session.query(models.DVRPortBinding).
return (session.query(models.DistributedPortBinding).
filter_by(port_id=port_id, host=host).one())
@ -254,9 +254,9 @@ def get_port_binding_host(session, port_id):
def generate_dvr_port_status(session, port_id):
# an OR'ed value of status assigned to parent port from the
# dvrportbinding bucket
query = session.query(models.DVRPortBinding)
query = session.query(models.DistributedPortBinding)
final_status = n_const.PORT_STATUS_BUILD
for bind in query.filter(models.DVRPortBinding.port_id == port_id):
for bind in query.filter(models.DistributedPortBinding.port_id == port_id):
if bind.status == n_const.PORT_STATUS_ACTIVE:
return bind.status
elif bind.status == n_const.PORT_STATUS_DOWN:
@ -266,9 +266,9 @@ def generate_dvr_port_status(session, port_id):
def get_dvr_port_binding_by_host(session, port_id, host):
with session.begin(subtransactions=True):
binding = (session.query(models.DVRPortBinding).
filter(models.DVRPortBinding.port_id.startswith(port_id),
models.DVRPortBinding.host == host).first())
binding = (session.query(models.DistributedPortBinding).
filter(models.DistributedPortBinding.port_id.startswith(port_id),
models.DistributedPortBinding.host == host).first())
if not binding:
LOG.debug("No binding for DVR port %(port_id)s with host "
"%(host)s", {'port_id': port_id, 'host': host})
@ -277,9 +277,9 @@ def get_dvr_port_binding_by_host(session, port_id, host):
def get_dvr_port_bindings(session, port_id):
with session.begin(subtransactions=True):
bindings = (session.query(models.DVRPortBinding).
filter(models.DVRPortBinding.port_id.startswith(port_id)).
all())
bindings = (session.query(models.DistributedPortBinding).
filter(models.DistributedPortBinding.port_id.startswith(
port_id)).all())
if not bindings:
LOG.debug("No bindings for DVR port %s", port_id)
return bindings

View File

@ -80,10 +80,11 @@ def get_nondvr_active_network_ports(session, network_id):
def get_dvr_active_network_ports(session, network_id):
with session.begin(subtransactions=True):
query = session.query(ml2_models.DVRPortBinding, agents_db.Agent)
query = session.query(ml2_models.DistributedPortBinding,
agents_db.Agent)
query = query.join(agents_db.Agent,
agents_db.Agent.host ==
ml2_models.DVRPortBinding.host)
ml2_models.DistributedPortBinding.host)
query = query.join(models_v2.Port)
query = query.filter(models_v2.Port.network_id == network_id,
models_v2.Port.status == const.PORT_STATUS_ACTIVE,
@ -104,11 +105,12 @@ def get_agent_network_active_port_count(session, agent_host,
models_v2.Port.device_owner !=
const.DEVICE_OWNER_DVR_INTERFACE,
ml2_models.PortBinding.host == agent_host)
query2 = query.join(ml2_models.DVRPortBinding)
query2 = query.join(ml2_models.DistributedPortBinding)
query2 = query2.filter(models_v2.Port.network_id == network_id,
ml2_models.DVRPortBinding.status ==
ml2_models.DistributedPortBinding.status ==
const.PORT_STATUS_ACTIVE,
models_v2.Port.device_owner ==
const.DEVICE_OWNER_DVR_INTERFACE,
ml2_models.DVRPortBinding.host == agent_host)
ml2_models.DistributedPortBinding.host ==
agent_host)
return (query1.count() + query2.count())

View File

@ -78,13 +78,16 @@ class PortBindingLevel(model_base.BASEV2):
ondelete="SET NULL"))
class DVRPortBinding(model_base.BASEV2):
"""Represent binding-related state of a DVR port.
class DistributedPortBinding(model_base.BASEV2):
"""Represent binding-related state of a Distributed Router(DVR, HA) port.
Port binding for all the ports associated to a DVR identified by router_id.
Port binding for all the ports associated to a Distributed router(DVR, HA)
identified by router_id. Currently DEVICE_OWNER_ROUTER_SNAT(DVR+HA router),
DEVICE_OWNER_DVR_INTERFACE, DEVICE_OWNER_HA_REPLICATED_INT are distributed
router ports.
"""
__tablename__ = 'ml2_dvr_port_bindings'
__tablename__ = 'ml2_distributed_port_bindings'
port_id = sa.Column(sa.String(36),
sa.ForeignKey('ports.id', ondelete="CASCADE"),
@ -105,6 +108,6 @@ class DVRPortBinding(model_base.BASEV2):
# eagerly load port bindings
port = orm.relationship(
models_v2.Port,
backref=orm.backref("dvr_port_binding",
backref=orm.backref("distributed_port_binding",
lazy='joined',
cascade='delete'))

View File

@ -448,15 +448,15 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
# ml2_port_bindings table, returned as cur_binding
# from db.get_locked_port_and_binding() above, is
# currently not used for DVR distributed ports, and is
# replaced here with the DVRPortBinding instance from
# the ml2_dvr_port_bindings table specific to the host
# replaced here with the DistributedPortBinding instance from
# the ml2_distributed_port_bindings table specific to the host
# on which the distributed port is being bound. It
# would be possible to optimize this code to avoid
# fetching the PortBinding instance in the DVR case,
# and even to avoid creating the unused entry in the
# ml2_port_bindings table. But the upcoming resolution
# for bug 1367391 will eliminate the
# ml2_dvr_port_bindings table, use the
# ml2_distributed_port_bindings table, use the
# ml2_port_bindings table to store non-host-specific
# fields for both distributed and non-distributed
# ports, and introduce a new ml2_port_binding_hosts

View File

@ -57,7 +57,7 @@ class TestL2PopulationDBTestCase(testlib_api.SqlTestCase):
status=constants.PORT_STATUS_ACTIVE,
device_id='',
device_owner=device_owner))
port_binding_cls = (models.DVRPortBinding if dvr
port_binding_cls = (models.DistributedPortBinding if dvr
else models.PortBinding)
binding_kwarg = {
'port_id': 'port_id',

View File

@ -288,7 +288,7 @@ class Ml2DvrDBTestCase(testlib_api.SqlTestCase):
def _setup_dvr_binding(self, network_id, port_id, router_id, host_id):
with self.ctx.session.begin(subtransactions=True):
record = models.DVRPortBinding(
record = models.DistributedPortBinding(
port_id=port_id,
host=host_id,
router_id=router_id,
@ -321,7 +321,7 @@ class Ml2DvrDBTestCase(testlib_api.SqlTestCase):
router = self._setup_neutron_router()
ml2_db.ensure_dvr_port_binding(
self.ctx.session, port_id, 'foo_host', router.id)
expected = (self.ctx.session.query(models.DVRPortBinding).
expected = (self.ctx.session.query(models.DistributedPortBinding).
filter_by(port_id=port_id).one())
self.assertEqual(port_id, expected.port_id)
@ -334,7 +334,7 @@ class Ml2DvrDBTestCase(testlib_api.SqlTestCase):
self.ctx.session, port_id, 'foo_host_1', router.id)
ml2_db.ensure_dvr_port_binding(
self.ctx.session, port_id, 'foo_host_2', router.id)
bindings = (self.ctx.session.query(models.DVRPortBinding).
bindings = (self.ctx.session.query(models.DistributedPortBinding).
filter_by(port_id=port_id).all())
self.assertEqual(2, len(bindings))
@ -346,7 +346,7 @@ class Ml2DvrDBTestCase(testlib_api.SqlTestCase):
network_id, port_id, None, 'foo_host_id')
ml2_db.delete_dvr_port_binding_if_stale(self.ctx.session, binding)
count = (self.ctx.session.query(models.DVRPortBinding).
count = (self.ctx.session.query(models.DistributedPortBinding).
filter_by(port_id=binding.port_id).count())
self.assertFalse(count)
@ -393,9 +393,11 @@ class Ml2DvrDBTestCase(testlib_api.SqlTestCase):
'router_id': 'router_id',
'status': constants.PORT_STATUS_DOWN
}
self.ctx.session.add(models.DVRPortBinding(**binding_kwarg))
self.ctx.session.add(models.DistributedPortBinding(
**binding_kwarg))
binding_kwarg['host'] = 'another-host'
self.ctx.session.add(models.DVRPortBinding(**binding_kwarg))
self.ctx.session.add(models.DistributedPortBinding(
**binding_kwarg))
with warnings.catch_warnings(record=True) as warning_list:
with self.ctx.session.begin(subtransactions=True):
self.ctx.session.delete(port)

View File

@ -1281,7 +1281,7 @@ class TestMl2PortBinding(Ml2PluginV2TestCase,
def test_process_dvr_port_binding_update_router_id(self):
host_id = 'host'
binding = models.DVRPortBinding(
binding = models.DistributedPortBinding(
port_id='port_id',
host=host_id,
router_id='old_router_id',
@ -1959,7 +1959,7 @@ class TestFaultyMechansimDriver(Ml2PluginV2FaultyDriverTestCase):
def test_update_dvr_router_interface_port(self):
"""Test validate dvr router interface update succeeds."""
host_id = 'host'
binding = models.DVRPortBinding(
binding = models.DistributedPortBinding(
port_id='port_id',
host=host_id,
router_id='old_router_id',