Merge "[Live Migration] Extend ml2_port_binding table"

This commit is contained in:
Jenkins 2017-01-27 11:36:24 +00:00 committed by Gerrit Code Review
commit 5f3c28880e
9 changed files with 96 additions and 4 deletions

View File

@ -148,3 +148,9 @@ METADATA_CIDR = '169.254.169.254/32'
IPAM_ALLOCATION_STATUS_ALLOCATED = 'ALLOCATED'
VALID_IPAM_ALLOCATION_STATUSES = (IPAM_ALLOCATION_STATUS_ALLOCATED,)
# Port binding states for Live Migration
PORT_BINDING_STATUS_ACTIVE = 'ACTIVE'
PORT_BINDING_STATUS_INACTIVE = 'INACTIVE'
PORT_BINDING_STATUSES = (PORT_BINDING_STATUS_ACTIVE,
PORT_BINDING_STATUS_INACTIVE)

View File

@ -1 +1 @@
929c968efe70
a9c43481023c

View File

@ -0,0 +1,69 @@
# Copyright 2016 Intel Corporation
#
# 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.
#
"""extend_pk_with_host_and_add_status_to_ml2_port_binding
Revision ID: a9c43481023c
Revises: 5cd92597d11d
Create Date: 2016-11-22 11:48:43.479552
"""
# revision identifiers, used by Alembic.
revision = 'a9c43481023c'
down_revision = '929c968efe70'
from alembic import op
import sqlalchemy as sa
from sqlalchemy.engine.reflection import Inspector as insp
from neutron.common import constants
MYSQL_ENGINE = 'mysql'
ML2_PORT_BINDING = 'ml2_port_bindings'
def upgrade():
bind = op.get_bind()
engine = bind.engine
op.add_column(ML2_PORT_BINDING,
sa.Column('status',
sa.String(length=16),
nullable=False,
server_default=constants.PORT_BINDING_STATUS_ACTIVE))
if (engine.name == MYSQL_ENGINE):
op.execute("ALTER TABLE ml2_port_bindings DROP PRIMARY KEY,"
"ADD PRIMARY KEY(port_id, host);")
else:
inspector = insp.from_engine(bind)
pk_constraint = inspector.get_pk_constraint(ML2_PORT_BINDING)
op.drop_constraint(pk_constraint.get('name'), ML2_PORT_BINDING,
type_='primary')
op.create_primary_key(op.f('pk_ml2_port_bindings'),
ML2_PORT_BINDING, ['port_id', 'host'])
def expand_drop_exceptions():
"""
Drop the existing primary key constraint and then extend it to include
host as the primary key to support multiple bindings for the same port.
This is needed to use drop in expand migration to pass test_branches.
It is safe to recreate primary key in expand as it is backward compatible.
"""
return {
sa.Constraint: ['ml2_port_bindings_pkey']
}

View File

@ -185,6 +185,10 @@ class IpProtocolEnum(obj_fields.Enum):
**kwargs)
class PortBindingStatusEnumField(obj_fields.AutoTypedField):
AUTO_TYPE = obj_fields.Enum(valid_values=constants.PORT_BINDING_STATUSES)
class IpProtocolEnumField(obj_fields.AutoTypedField):
AUTO_TYPE = IpProtocolEnum()

View File

@ -16,6 +16,7 @@ import netaddr
from oslo_versionedobjects import base as obj_base
from oslo_versionedobjects import fields as obj_fields
from neutron.common import constants
from neutron.common import utils
from neutron.db import api as db_api
from neutron.db.models import dns as dns_models
@ -72,9 +73,11 @@ class PortBinding(PortBindingBase):
'vif_type': obj_fields.StringField(),
'vif_details': common_types.DictOfMiscValuesField(nullable=True),
'vnic_type': obj_fields.StringField(),
'status': common_types.PortBindingStatusEnumField(
default=constants.PORT_BINDING_STATUS_ACTIVE),
}
primary_keys = ['port_id']
primary_keys = ['port_id', 'host']
@obj_base.VersionedObjectRegistry.register

View File

@ -17,6 +17,7 @@ from neutron_lib.db import model_base
import sqlalchemy as sa
from sqlalchemy import orm
from neutron.common import constants
from neutron.db import models_v2
from neutron.extensions import portbindings
@ -38,7 +39,7 @@ class PortBinding(model_base.BASEV2):
sa.ForeignKey('ports.id', ondelete="CASCADE"),
primary_key=True)
host = sa.Column(sa.String(255), nullable=False, default='',
server_default='')
server_default='', primary_key=True)
vnic_type = sa.Column(sa.String(64), nullable=False,
default=portbindings.VNIC_NORMAL,
server_default=portbindings.VNIC_NORMAL)
@ -47,6 +48,9 @@ class PortBinding(model_base.BASEV2):
vif_type = sa.Column(sa.String(64), nullable=False)
vif_details = sa.Column(sa.String(4095), nullable=False, default='',
server_default='')
status = sa.Column(sa.String(16), nullable=False,
default=constants.PORT_BINDING_STATUS_ACTIVE,
server_default=constants.PORT_BINDING_STATUS_ACTIVE)
# Add a relationship to the Port model in order to instruct SQLAlchemy to
# eagerly load port bindings

View File

@ -299,6 +299,10 @@ def get_random_ip_protocol():
return random.choice(list(constants.IP_PROTOCOL_MAP.keys()))
def get_random_port_binding_statuses():
return random.choice(n_const.PORT_BINDING_STATUSES)
def is_bsd():
"""Return True on BSD-based systems."""

View File

@ -439,6 +439,8 @@ FIELD_TYPE_VALUE_GENERATOR_MAP = {
common_types.IpProtocolEnumField: tools.get_random_ip_protocol,
common_types.ListOfIPNetworksField: get_list_of_random_networks,
common_types.MACAddressField: tools.get_random_EUI,
common_types.PortBindingStatusEnumField:
tools.get_random_port_binding_statuses,
common_types.PortRangeField: tools.get_random_port,
common_types.PortRangeWith0Field: lambda: tools.get_random_port(0),
common_types.SetOfUUIDsField: get_set_of_random_uuids,

View File

@ -53,7 +53,7 @@ object_data = {
'NetworkPortSecurity': '1.0-b30802391a87945ee9c07582b4ff95e3',
'NetworkSegment': '1.0-40707ef6bd9a0bf095038158d995cc7d',
'Port': '1.0-638f6b09a3809ebd8b2b46293f56871b',
'PortBinding': '1.0-189fa2f450a1f24b1423df660eb43d71',
'PortBinding': '1.0-3306deeaa6deb01e33af06777d48d578',
'PortBindingLevel': '1.0-de66a4c61a083b8f34319fa9dde5b060',
'PortDNS': '1.0-201cf6d057fde75539c3d1f2bbf05902',
'PortSecurity': '1.0-b30802391a87945ee9c07582b4ff95e3',