[openstack-neutron] Drop and recreate FK to support MariaDB 10, rhbz#1157599

Alan Pevec apevec at fedoraproject.org
Tue Nov 25 14:04:08 UTC 2014


commit e498dc2bca59c50333ea40318d31b6c0a3ba0cd7
Author: Alan Pevec <alan.pevec at redhat.com>
Date:   Tue Nov 25 14:39:34 2014 +0100

    Drop and recreate FK to support MariaDB 10, rhbz#1157599

 0002-Create-DHCP-port-for-IPv6-subnet.patch        |   77 -------
 ...create-FK-if-adding-new-PK-to-routerl3bin.patch |  222 ++++++++++++++++++++
 openstack-neutron.spec                             |    9 +-
 3 files changed, 229 insertions(+), 79 deletions(-)
---
diff --git a/0002-Drop-and-recreate-FK-if-adding-new-PK-to-routerl3bin.patch b/0002-Drop-and-recreate-FK-if-adding-new-PK-to-routerl3bin.patch
new file mode 100644
index 0000000..754dc94
--- /dev/null
+++ b/0002-Drop-and-recreate-FK-if-adding-new-PK-to-routerl3bin.patch
@@ -0,0 +1,222 @@
+From 0d208c542d8a3cbf3ccf9985e5452fc829df7895 Mon Sep 17 00:00:00 2001
+From: Jakub Libosvar <libosvar at redhat.com>
+Date: Fri, 31 Oct 2014 15:49:40 +0100
+Subject: [PATCH] Drop and recreate FK if adding new PK to routerl3bindings
+
+Since MySQL 5.6 FK columns cannot be altered. As a workaround we can
+drop the FK before ALTER COLUMN and then recreate it.
+
+Change-Id: Icd1b3075cf29a6b0c477a4ddea2e6ebee91baef8
+Closes-Bug: 1384555
+(cherry picked from commit b5f1cc48b877caaebc944154d56a8bb4060aa9b0)
+(cherry picked from commit 467a4496cfcd74b473730d2baa667fd633e4d0b3)
+---
+ neutron/db/migration/__init__.py                   |  34 ++++++
+ .../31d7f831a591_add_constraint_for_routerid.py    | 115 +++++----------------
+ 2 files changed, 58 insertions(+), 91 deletions(-)
+
+diff --git a/neutron/db/migration/__init__.py b/neutron/db/migration/__init__.py
+index 55c1443..86cce38 100644
+--- a/neutron/db/migration/__init__.py
++++ b/neutron/db/migration/__init__.py
+@@ -12,11 +12,13 @@
+ #    License for the specific language governing permissions and limitations
+ #    under the License.
+ 
++import contextlib
+ import functools
+ 
+ from alembic import context
+ from alembic import op
+ import sqlalchemy as sa
++from sqlalchemy.engine import reflection
+ 
+ 
+ def skip_if_offline(func):
+@@ -122,3 +124,35 @@ def create_table_if_not_exist_psql(table_name, values):
+                "WHERE NOT table_exist(%(name)r);" %
+                {'name': table_name,
+                 'columns': values})
++
++
++def remove_foreign_keys(table, foreign_keys):
++    for fk in foreign_keys:
++        op.drop_constraint(
++            name=fk['name'],
++            table_name=table,
++            type_='foreignkey'
++        )
++
++
++def create_foreign_keys(table, foreign_keys):
++    for fk in foreign_keys:
++        op.create_foreign_key(
++            name=fk['name'],
++            source=table,
++            referent=fk['referred_table'],
++            local_cols=fk['constrained_columns'],
++            remote_cols=fk['referred_columns'],
++            ondelete='CASCADE'
++        )
++
++
++ at contextlib.contextmanager
++def remove_fks_from_table(table):
++    try:
++        inspector = reflection.Inspector.from_engine(op.get_bind())
++        foreign_keys = inspector.get_foreign_keys(table)
++        remove_foreign_keys(table, foreign_keys)
++        yield
++    finally:
++        create_foreign_keys(table, foreign_keys)
+diff --git a/neutron/db/migration/alembic_migrations/versions/31d7f831a591_add_constraint_for_routerid.py b/neutron/db/migration/alembic_migrations/versions/31d7f831a591_add_constraint_for_routerid.py
+index 0ba5f58..2321567 100644
+--- a/neutron/db/migration/alembic_migrations/versions/31d7f831a591_add_constraint_for_routerid.py
++++ b/neutron/db/migration/alembic_migrations/versions/31d7f831a591_add_constraint_for_routerid.py
+@@ -27,22 +27,12 @@ down_revision = '37f322991f59'
+ 
+ from alembic import op
+ import sqlalchemy as sa
+-from sqlalchemy.engine import reflection
++
++from neutron.db import migration
+ 
+ TABLE_NAME = 'routerl3agentbindings'
+ PK_NAME = 'pk_routerl3agentbindings'
+ 
+-fk_names = {'postgresql':
+-            {'router_id':
+-                'routerl3agentbindings_router_id_fkey',
+-             'l3_agent_id':
+-                'routerl3agentbindings_l3_agent_id_fkey'},
+-            'mysql':
+-            {'router_id':
+-                'routerl3agentbindings_ibfk_2',
+-             'l3_agent_id':
+-                'routerl3agentbindings_ibfk_1'}}
+-
+ 
+ def upgrade():
+     # In order to sanitize the data during migration,
+@@ -66,60 +56,32 @@ def upgrade():
+ 
+     op.drop_column(TABLE_NAME, 'id')
+ 
+-    # DB2 doesn't support nullable column in primary key
+-    if context.bind.dialect.name == 'ibm_db_sa':
+-        op.alter_column(
+-            table_name=TABLE_NAME,
+-            column_name='router_id',
+-            nullable=False
+-        )
+-        op.alter_column(
++    with migration.remove_fks_from_table(TABLE_NAME):
++        # DB2 doesn't support nullable column in primary key
++        if context.bind.dialect.name == 'ibm_db_sa':
++            op.alter_column(
++                table_name=TABLE_NAME,
++                column_name='router_id',
++                nullable=False
++            )
++            op.alter_column(
++                table_name=TABLE_NAME,
++                column_name='l3_agent_id',
++                nullable=False
++            )
++
++        op.create_primary_key(
++            name=PK_NAME,
+             table_name=TABLE_NAME,
+-            column_name='l3_agent_id',
+-            nullable=False
++            cols=['router_id', 'l3_agent_id']
+         )
+ 
+-    op.create_primary_key(
+-        name=PK_NAME,
+-        table_name=TABLE_NAME,
+-        cols=['router_id', 'l3_agent_id']
+-    )
+-
+ 
+ def downgrade():
+ 
+     context = op.get_context()
+     dialect = context.bind.dialect.name
+ 
+-    # Drop the existed foreign key constraints
+-    # In order to perform primary key changes
+-    db2fks = {}
+-    if dialect == 'ibm_db_sa':
+-        # NOTE(mriedem): In DB2 the foreign key names are randomly generated
+-        # if you didn't originally explicitly name them, so the name is like
+-        # SQLxxxxx where the suffix is a random integer.  Therefore we go
+-        # through and just drop all of the foreign keys and save them so we
+-        # can re-create them later after the primary key is dropped.
+-        inspector = reflection.Inspector.from_engine(op.get_bind().engine)
+-        db2fks = inspector.get_foreign_keys(TABLE_NAME)
+-        for fk in db2fks:
+-            op.drop_constraint(
+-                name=fk.get('name'),
+-                table_name=TABLE_NAME,
+-                type_='foreignkey'
+-            )
+-    else:
+-        op.drop_constraint(
+-            name=fk_names[dialect]['l3_agent_id'],
+-            table_name=TABLE_NAME,
+-            type_='foreignkey'
+-        )
+-        op.drop_constraint(
+-            name=fk_names[dialect]['router_id'],
+-            table_name=TABLE_NAME,
+-            type_='foreignkey'
+-        )
+-
+     op.drop_constraint(
+         name=PK_NAME,
+         table_name=TABLE_NAME,
+@@ -139,38 +101,9 @@ def downgrade():
+             nullable=False
+         )
+ 
+-    op.create_primary_key(
+-        name=PK_NAME,
+-        table_name=TABLE_NAME,
+-        cols=['id']
+-    )
+-
+-    # Restore the foreign key constraints
+-    if dialect == 'ibm_db_sa':
+-        for fk in db2fks:
+-            op.create_foreign_key(
+-                name=fk.get('name'),
+-                source=TABLE_NAME,
+-                referent=fk.get('referred_table'),
+-                local_cols=fk.get('constrained_columns'),
+-                remote_cols=fk.get('referred_columns'),
+-                ondelete='CASCADE'
+-            )
+-    else:
+-        op.create_foreign_key(
+-            name=fk_names[dialect]['router_id'],
+-            source=TABLE_NAME,
+-            referent='routers',
+-            local_cols=['router_id'],
+-            remote_cols=['id'],
+-            ondelete='CASCADE'
+-        )
+-
+-        op.create_foreign_key(
+-            name=fk_names[dialect]['l3_agent_id'],
+-            source=TABLE_NAME,
+-            referent='agents',
+-            local_cols=['l3_agent_id'],
+-            remote_cols=['id'],
+-            ondelete='CASCADE'
++    with migration.remove_fks_from_table(TABLE_NAME):
++        op.create_primary_key(
++            name=PK_NAME,
++            table_name=TABLE_NAME,
++            cols=['id']
+         )
diff --git a/openstack-neutron.spec b/openstack-neutron.spec
index a6bb5e0..9b523c3 100644
--- a/openstack-neutron.spec
+++ b/openstack-neutron.spec
@@ -2,7 +2,7 @@
 
 Name:		openstack-neutron
 Version:	2014.2
-Release:	9%{?dist}
+Release:	10%{?dist}
 Provides:	openstack-quantum = %{version}-%{release}
 Obsoletes:	openstack-quantum < 2013.2-0.4.b3
 Summary:	OpenStack Networking Service
@@ -41,7 +41,7 @@ Source40:	neutron-dist.conf
 # patches_base=+1
 #
 Patch0001: 0001-remove-runtime-dependency-on-pbr.patch
-Patch0002: 0002-Create-DHCP-port-for-IPv6-subnet.patch
+Patch0002: 0002-Drop-and-recreate-FK-if-adding-new-PK-to-routerl3bin.patch
 
 BuildArch:	noarch
 
@@ -976,6 +976,11 @@ exit 0
 
 
 %changelog
+* Tue Nov 25 2014 Alan Pevec <apevec at redhat.com> 2014.2-10
+- Drop and recreate FK to support MariaDB 10, rhbz#1157599
+- Drop "Create DHCP port for IPv6 subnet" due to regression:
+  https://bugs.launchpad.net/neutron/+bug/1392564
+
 * Thu Nov 13 2014 Ihar Hrachyshka <ihrachys at redhat.com> 2014.2-9
 - Revert to 755 permissions for /var/lib/neutron since dnsmasq drops
   'neutron' user and runs as 'nobody' by default, rhbz#1163759


More information about the scm-commits mailing list