summaryrefslogtreecommitdiffstats
path: root/nova/db
diff options
context:
space:
mode:
authorBrian Waldon <bcwaldon@gmail.com>2012-09-17 13:25:31 -0700
committerBrian Waldon <bcwaldon@gmail.com>2012-09-18 10:02:21 -0700
commit82d33f51f0fa2258f2a8d4003520af560d8bef11 (patch)
tree010c3b911f2630b5aeb30022cd843231cb6072b8 /nova/db
parent5b8d9ada4b44ca7aac523f7e0ec4158bff08232d (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.py83
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