]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Fix 033 add encryption unique key migration
authorAnton Arefiev <aarefiev@mirantis.com>
Wed, 18 Mar 2015 12:59:59 +0000 (14:59 +0200)
committerAnton Arefiev <aarefiev@mirantis.com>
Tue, 21 Jul 2015 08:47:10 +0000 (11:47 +0300)
SQLite doesn't support 'drop constraint' statament. So it notifies:
SAWarning: Table 'encryption' specifies columns 'volume_type_id'
as primary_key=True, not matching locally specified columns
'encryption_id'; setting the current primary key columns to
'encryption_id'. This warning may become an exception in a future
release.

Add new strategy for sqlite upgrade: table is renamed to temporary
name, new table is created followed by INSERT statements, and
renamed to original one.

Change-Id: I723fdadb946f6944dde03954409899a9ddc3ee0e
Closes-Bug: #1431374

cinder/db/sqlalchemy/migrate_repo/versions/033_add_encryption_unique_key.py
tools/lintstack.py

index a37fa114b29a008cfd572a74e3eaabf0f10bb376..3c347d4e2fa9f0e7ef1ac969e99ca3ad73ffcecf 100644 (file)
@@ -13,8 +13,8 @@
 import uuid
 
 from migrate import PrimaryKeyConstraint, ForeignKeyConstraint
-from sqlalchemy import Column
-from sqlalchemy import MetaData, String, Table
+from sqlalchemy import Column, MetaData, Table
+from sqlalchemy import String, Integer, Boolean, DateTime
 
 
 def upgrade(migrate_engine):
@@ -24,45 +24,42 @@ def upgrade(migrate_engine):
 
     encryptions = Table('encryption', meta, autoload=True)
 
-    encryption_id_column_kwargs = {}
-    if migrate_engine.name == 'ibm_db_sa':
-        # NOTE(junxiebj): DB2 10.5 doesn't support primary key
-        # constraints over nullable columns, so we have to
-        # make the column non-nullable in the DB2 case.
-        encryption_id_column_kwargs['nullable'] = False
-    encryption_id = Column('encryption_id', String(36),
-                           **encryption_id_column_kwargs)
-    encryptions.create_column(encryption_id)
+    # NOTE: SQLite doesn't support 'drop constraint' statament
+    if migrate_engine.name == 'sqlite':
+        _upgrade_sqlite(meta, encryptions)
+    else:
+        encryption_id_column_kwargs = {}
+        if migrate_engine.name == 'ibm_db_sa':
+            # NOTE(junxiebj): DB2 10.5 doesn't support primary key
+            # constraints over nullable columns, so we have to
+            # make the column non-nullable in the DB2 case.
+            encryption_id_column_kwargs['nullable'] = False
+        encryption_id = Column('encryption_id', String(36),
+                               **encryption_id_column_kwargs)
+        encryptions.create_column(encryption_id)
+
+        encryption_items = list(encryptions.select().execute())
+
+        for item in encryption_items:
+            encryptions.update().\
+                where(encryptions.c.volume_type_id == item['volume_type_id']).\
+                values(encryption_id=str(uuid.uuid4())).execute()
+
+        # NOTE (e0ne): need to drop FK first for MySQL
+        if migrate_engine.name == 'mysql':
+            ref_table = Table('volume_types', meta, autoload=True)
+            params = {'columns': [encryptions.c['volume_type_id']],
+                      'refcolumns': [ref_table.c['id']],
+                      'name': 'encryption_ibfk_1'}
+            volume_type_fk = ForeignKeyConstraint(**params)
+            volume_type_fk.drop()
 
-    encryption_items = list(encryptions.select().execute())
-
-    for item in encryption_items:
-        encryptions.update().\
-            where(encryptions.c.volume_type_id == item['volume_type_id']).\
-            values(encryption_id=str(uuid.uuid4())).execute()
-
-    # NOTE (e0ne): need to drop FK first for MySQL
-    if migrate_engine.name == 'mysql':
-        ref_table = Table('volume_types', meta, autoload=True)
-        params = {'columns': [encryptions.c['volume_type_id']],
-                  'refcolumns': [ref_table.c['id']],
-                  'name': 'encryption_ibfk_1'}
-        volume_type_fk = ForeignKeyConstraint(**params)
-        volume_type_fk.drop()
-
-    try:
         volume_type_pk = PrimaryKeyConstraint('volume_type_id',
                                               table=encryptions)
         volume_type_pk.drop()
-    except Exception:
-        # NOTE (e0ne): SQLite doesn't support 'drop constraint' statament
-        if migrate_engine.url.get_dialect().name.startswith('sqlite'):
-            pass
-        else:
-            raise
 
-    pkey = PrimaryKeyConstraint(encryptions.columns.encryption_id)
-    pkey.create()
+        pkey = PrimaryKeyConstraint(encryptions.columns.encryption_id)
+        pkey.create()
 
 
 def downgrade(migrate_engine):
@@ -84,3 +81,36 @@ def downgrade(migrate_engine):
               'name': 'encryption_ibfk_1'}
     volume_type_fk = ForeignKeyConstraint(**params)
     volume_type_fk.create()
+
+
+def _upgrade_sqlite(meta, encryptions):
+    new_encryptions = Table(
+        'encryption_33', meta,
+        Column('created_at', DateTime(timezone=False)),
+        Column('updated_at', DateTime(timezone=False)),
+        Column('deleted_at', DateTime(timezone=False)),
+        Column('deleted', Boolean(create_constraint=True, name=None)),
+        Column('cipher', String(255)),
+        Column('key_size', Integer),
+        Column('provider', String(255)),
+        Column('control_location', String(255)),
+        Column('encryption_id', String(36), primary_key=True),
+        Column('volume_type_id', String(36))
+    )
+    new_encryptions.create()
+    encryption_items = list(encryptions.select().execute())
+    for item in encryption_items:
+        new_encryptions.insert().\
+            values(created_at=item['created_at'],
+                   updated_at=item['updated_at'],
+                   deleted_at=item['deleted_at'],
+                   deleted=item['deleted'],
+                   cipher=item['cipher'],
+                   key_size=item['key_size'],
+                   provider=item['provider'],
+                   control_location=item['control_location'],
+                   encryption_id=str(uuid.uuid4()),
+                   volume_type_id=item['volume_type_id']).execute()
+
+    encryptions.drop()
+    new_encryptions.rename('encryption')
index 51bf094eba249f5324bf30e5468d0bddcd358810..27c3c5a83c7a22abb0af0ff703462074a90f8bec 100755 (executable)
@@ -37,11 +37,14 @@ ignore_codes = ["E1103"]
 # Note(xyang): the fourth and fifth error messages are for the code [E1101].
 # They should be ignored because 'sha256' and 'sha224' are functions in
 # 'hashlib'.
+# Note(aarefiev): the sixth error message is for SQLAlchemy rename calls in
+# DB migration(033_add_encryption_unique_key).
 ignore_messages = ["An attribute affected in cinder.tests",
                    "No name 'urllib' in module '_MovedItems'",
                    "No value passed for parameter 'dml'",
                    "Module 'hashlib' has no 'sha256' member",
-                   "Module 'hashlib' has no 'sha224' member"]
+                   "Module 'hashlib' has no 'sha224' member",
+                   "Instance of 'Table' has no 'rename' member"]
 # Note(maoy): we ignore all errors in openstack.common because it should be
 # checked elsewhere. We also ignore cinder.tests for now due to high false
 # positive rate.