diff options
| author | Brian Waldon <bcwaldon@gmail.com> | 2012-09-17 13:25:31 -0700 |
|---|---|---|
| committer | Brian Waldon <bcwaldon@gmail.com> | 2012-09-18 10:02:21 -0700 |
| commit | 82d33f51f0fa2258f2a8d4003520af560d8bef11 (patch) | |
| tree | 010c3b911f2630b5aeb30022cd843231cb6072b8 /nova/db | |
| parent | 5b8d9ada4b44ca7aac523f7e0ec4158bff08232d (diff) | |
Correct db migration 91
* Snapshot.id gets the new snapshot uuid rather than snapshot.volume_id
* Foreign keys are dropped before and recreated after updating id fields
* Snapshot id <-> uuid queries use snapshot_id_mappings.c.id rather
than volume_id_mappings.id
* Snapshot id <-> uuid queries are executed before passing the new id
values into subsequent UPDATE queries
* Thoroughly inspect the expected modifications in a new functional test
* Fixes bug 1052244
* Fixes bug 1052220
Change-Id: I22c820e5747562251c6447ac678c80dd9e0e2e20
Diffstat (limited to 'nova/db')
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/091_convert_volume_ids_to_uuid.py | 83 |
1 files changed, 77 insertions, 6 deletions
diff --git a/nova/db/sqlalchemy/migrate_repo/versions/091_convert_volume_ids_to_uuid.py b/nova/db/sqlalchemy/migrate_repo/versions/091_convert_volume_ids_to_uuid.py index 3c4183f68..3938107da 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/091_convert_volume_ids_to_uuid.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/091_convert_volume_ids_to_uuid.py @@ -15,6 +15,7 @@ # License for the specific language governing permissions and limitations # under the License. +from migrate import ForeignKeyConstraint from sqlalchemy import MetaData, select, Table from nova.openstack.common import log as logging @@ -38,10 +39,31 @@ def upgrade(migrate_engine): volume_mappings = Table('volume_id_mappings', meta, autoload=True) snapshot_mappings = Table('snapshot_id_mappings', meta, autoload=True) + fkey_columns = [ + iscsi_targets.c.volume_id, + volume_metadata.c.volume_id, + sm_volumes.c.id, + ] + for column in fkey_columns: + fkeys = list(column.foreign_keys) + if fkeys: + fkey_name = fkeys[0].constraint.name + LOG.info('Dropping foreign key %s' % fkey_name) + fkey = ForeignKeyConstraint(columns=[column], + refcolumns=[volumes.c.id], + name=fkey_name) + try: + fkey.drop() + except Exception: + if migrate_engine.url.get_dialect().name.startswith('sqlite'): + pass + else: + raise + volume_list = list(volumes.select().execute()) for v in volume_list: new_id = select([volume_mappings.c.uuid], - volume_mappings.c.id == v['id']) + volume_mappings.c.id == v['id']).execute().fetchone()[0] volumes.update().\ where(volumes.c.id == v['id']).\ @@ -70,7 +92,7 @@ def upgrade(migrate_engine): snapshot_list = list(snapshots.select().execute()) for s in snapshot_list: new_id = select([snapshot_mappings.c.uuid], - volume_mappings.c.id == s['id']) + snapshot_mappings.c.id == s['id']).execute().fetchone()[0] volumes.update().\ where(volumes.c.snapshot_id == s['id']).\ @@ -78,12 +100,26 @@ def upgrade(migrate_engine): snapshots.update().\ where(snapshots.c.id == s['id']).\ - values(volume_id=new_id).execute() + values(id=new_id).execute() block_device_mapping.update().\ where(block_device_mapping.c.snapshot_id == s['id']).\ values(snapshot_id=new_id).execute() + for column in fkey_columns: + fkeys = list(column.foreign_keys) + if fkeys: + fkey = ForeignKeyConstraint(columns=[column], + refcolumns=[volumes.c.id]) + try: + fkey.create() + LOG.info('Created foreign key %s' % fkey_name) + except Exception: + if migrate_engine.url.get_dialect().name.startswith('sqlite'): + pass + else: + raise + def downgrade(migrate_engine): """Convert volume and snapshot id columns back to int.""" @@ -100,10 +136,31 @@ def downgrade(migrate_engine): volume_mappings = Table('volume_id_mappings', meta, autoload=True) snapshot_mappings = Table('snapshot_id_mappings', meta, autoload=True) + fkey_columns = [ + iscsi_targets.c.volume_id, + volume_metadata.c.volume_id, + sm_volumes.c.id, + ] + for column in fkey_columns: + fkeys = list(column.foreign_keys) + if fkeys: + fkey_name = fkeys[0].constraint.name + LOG.info('Dropping foreign key %s' % fkey_name) + fkey = ForeignKeyConstraint(columns=[column], + refcolumns=[volumes.c.id], + name=fkey_name) + try: + fkey.drop() + except Exception: + if migrate_engine.url.get_dialect().name.startswith('sqlite'): + pass + else: + raise + volume_list = list(volumes.select().execute()) for v in volume_list: new_id = select([volume_mappings.c.id], - volume_mappings.c.uuid == v['id']) + volume_mappings.c.uuid == v['id']).execute().fetchone()[0] volumes.update().\ where(volumes.c.id == v['id']).\ @@ -132,7 +189,7 @@ def downgrade(migrate_engine): snapshot_list = list(snapshots.select().execute()) for s in snapshot_list: new_id = select([snapshot_mappings.c.id], - volume_mappings.c.uuid == s['id']) + snapshot_mappings.c.uuid == s['id']).execute().fetchone()[0] volumes.update().\ where(volumes.c.snapshot_id == s['id']).\ @@ -140,8 +197,22 @@ def downgrade(migrate_engine): snapshots.update().\ where(snapshots.c.id == s['id']).\ - values(volume_id=new_id).execute() + values(id=new_id).execute() block_device_mapping.update().\ where(block_device_mapping.c.snapshot_id == s['id']).\ values(snapshot_id=new_id).execute() + + for column in fkey_columns: + fkeys = list(column.foreign_keys) + if fkeys: + fkey = ForeignKeyConstraint(columns=[column], + refcolumns=[volumes.c.id]) + try: + fkey.create() + LOG.info('Created foreign key %s' % fkey_name) + except Exception: + if migrate_engine.url.get_dialect().name.startswith('sqlite'): + pass + else: + raise |
