diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-04-30 22:23:11 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-04-30 22:23:11 +0000 |
| commit | dda036044e2ddb249aef8d483269bcbf97141abd (patch) | |
| tree | 86c4f07c5198265e06752b26a7120371307f9db0 /nova/db | |
| parent | 2c72cb3bcee6b64fff6e3eaa738e4bc80828a830 (diff) | |
| parent | 58af96d3e01c7fbe993344374190d8afe1a1d0ff (diff) | |
| download | nova-dda036044e2ddb249aef8d483269bcbf97141abd.tar.gz nova-dda036044e2ddb249aef8d483269bcbf97141abd.tar.xz nova-dda036044e2ddb249aef8d483269bcbf97141abd.zip | |
Merge "Migrate block_device_mapping to use instance uuids."
Diffstat (limited to 'nova/db')
| -rw-r--r-- | nova/db/api.py | 9 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/api.py | 14 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/088_change_instance_id_to_uuid_in_block_device_mapping.py | 81 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/088_sqlite_downgrade.sql | 97 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/088_sqlite_upgrade.sql | 97 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migration.py | 5 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/models.py | 10 |
7 files changed, 298 insertions, 15 deletions
diff --git a/nova/db/api.py b/nova/db/api.py index 184c2ab55..5de921667 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -1086,9 +1086,10 @@ def block_device_mapping_update_or_create(context, values): return IMPL.block_device_mapping_update_or_create(context, values) -def block_device_mapping_get_all_by_instance(context, instance_id): +def block_device_mapping_get_all_by_instance(context, instance_uuid): """Get all block device mapping belonging to a instance""" - return IMPL.block_device_mapping_get_all_by_instance(context, instance_id) + return IMPL.block_device_mapping_get_all_by_instance(context, + instance_uuid) def block_device_mapping_destroy(context, bdm_id): @@ -1096,11 +1097,11 @@ def block_device_mapping_destroy(context, bdm_id): return IMPL.block_device_mapping_destroy(context, bdm_id) -def block_device_mapping_destroy_by_instance_and_volume(context, instance_id, +def block_device_mapping_destroy_by_instance_and_volume(context, instance_uuid, volume_id): """Destroy the block device mapping or raise if it does not exist.""" return IMPL.block_device_mapping_destroy_by_instance_and_volume( - context, instance_id, volume_id) + context, instance_uuid, volume_id) #################### diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 2785b2b03..1d7509aef 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -1316,7 +1316,7 @@ def instance_destroy(context, instance_id): 'deleted_at': utils.utcnow(), 'updated_at': literal_column('updated_at')}) session.query(models.BlockDeviceMapping).\ - filter_by(instance_id=instance_id).\ + filter_by(instance_uuid=instance_ref['uuid']).\ update({'deleted': True, 'deleted_at': utils.utcnow(), 'updated_at': literal_column('updated_at')}) @@ -2726,7 +2726,7 @@ def block_device_mapping_update_or_create(context, values): session = get_session() with session.begin(): result = _block_device_mapping_get_query(context, session=session).\ - filter_by(instance_id=values['instance_id']).\ + filter_by(instance_uuid=values['instance_uuid']).\ filter_by(device_name=values['device_name']).\ first() if not result: @@ -2742,7 +2742,7 @@ def block_device_mapping_update_or_create(context, values): if (virtual_name is not None and block_device.is_swap_or_ephemeral(virtual_name)): session.query(models.BlockDeviceMapping).\ - filter_by(instance_id=values['instance_id']).\ + filter_by(instance_uuid=values['instance_uuid']).\ filter_by(virtual_name=virtual_name).\ filter(models.BlockDeviceMapping.device_name != values['device_name']).\ @@ -2752,9 +2752,9 @@ def block_device_mapping_update_or_create(context, values): @require_context -def block_device_mapping_get_all_by_instance(context, instance_id): +def block_device_mapping_get_all_by_instance(context, instance_uuid): return _block_device_mapping_get_query(context).\ - filter_by(instance_id=instance_id).\ + filter_by(instance_uuid=instance_uuid).\ all() @@ -2770,12 +2770,12 @@ def block_device_mapping_destroy(context, bdm_id): @require_context -def block_device_mapping_destroy_by_instance_and_volume(context, instance_id, +def block_device_mapping_destroy_by_instance_and_volume(context, instance_uuid, volume_id): session = get_session() with session.begin(): _block_device_mapping_get_query(context, session=session).\ - filter_by(instance_id=instance_id).\ + filter_by(instance_uuid=instance_uuid).\ filter_by(volume_id=volume_id).\ update({'deleted': True, 'deleted_at': utils.utcnow(), diff --git a/nova/db/sqlalchemy/migrate_repo/versions/088_change_instance_id_to_uuid_in_block_device_mapping.py b/nova/db/sqlalchemy/migrate_repo/versions/088_change_instance_id_to_uuid_in_block_device_mapping.py new file mode 100644 index 000000000..524d04d3f --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/088_change_instance_id_to_uuid_in_block_device_mapping.py @@ -0,0 +1,81 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# Copyright 2012 Michael Still and Canonical Inc +# All Rights Reserved. +# +# 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. + +from sqlalchemy import select, Column, ForeignKey, Integer +from sqlalchemy import MetaData, String, Table +from migrate import ForeignKeyConstraint + +from nova import log as logging + + +LOG = logging.getLogger(__name__) + + +def upgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + dialect = migrate_engine.url.get_dialect().name + block_device_mapping = Table('block_device_mapping', meta, autoload=True) + instances = Table('instances', meta, autoload=True) + uuid_column = Column('instance_uuid', String(36)) + uuid_column.create(block_device_mapping) + + try: + block_device_mapping.update().values( + instance_uuid=select( + [instances.c.uuid], + instances.c.id == block_device_mapping.c.instance_id) + ).execute() + except Exception: + uuid_column.drop() + raise + + fkeys = list(block_device_mapping.c.instance_id.foreign_keys) + if fkeys: + try: + fkey_name = fkeys[0].constraint.name + ForeignKeyConstraint( + columns=[block_device_mapping.c.instance_id], + refcolumns=[instances.c.id], + name=fkey_name).drop() + except Exception: + LOG.error(_("foreign key constraint couldn't be removed")) + raise + + block_device_mapping.c.instance_id.drop() + + +def downgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + block_device_mapping = Table('block_device_mapping', meta, autoload=True) + instances = Table('instances', meta, autoload=True) + id_column = Column('instance_id', Integer, ForeignKey('instances.id')) + id_column.create(block_device_mapping) + + try: + block_device_mapping.update().values( + instance_id=select( + [instances.c.id], + instances.c.uuid == block_device_mapping.c.instance_uuid) + ).execute() + except Exception: + id_column.drop() + raise + + block_device_mapping.c.instance_uuid.drop() diff --git a/nova/db/sqlalchemy/migrate_repo/versions/088_sqlite_downgrade.sql b/nova/db/sqlalchemy/migrate_repo/versions/088_sqlite_downgrade.sql new file mode 100644 index 000000000..3699ce9ab --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/088_sqlite_downgrade.sql @@ -0,0 +1,97 @@ +BEGIN TRANSACTION; + CREATE TEMPORARY TABLE block_device_mapping_backup ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + instance_id INTEGER NOT NULL, + device_name VARCHAR(255) NOT NULL, + delete_on_termination BOOLEAN, + virtual_name VARCHAR(255), + snapshot_id INTEGER, + volume_id INTEGER, + volume_size INTEGER, + no_device BOOLEAN, + connection_info TEXT, + instance_uuid VARCHAR(36), + PRIMARY KEY (id), + FOREIGN KEY(snapshot_id) REFERENCES snapshots (id), + CHECK (deleted IN (0, 1)), + CHECK (delete_on_termination IN (0, 1)), + CHECK (no_device IN (0, 1)), + FOREIGN KEY(volume_id) REFERENCES volumes (id), + FOREIGN KEY(instance_id) REFERENCES instances (id) + ); + + INSERT INTO block_device_mapping_backup + SELECT created_at, + updated_at, + deleted_at, + deleted, + id, + NULL, + device_name, + delete_on_termination, + virtual_name, + snapshot_id, + volume_id, + volume_size, + no_device, + connection_info, + instance_uuid + FROM block_device_mapping; + + UPDATE block_device_mapping_backup + SET instance_id= + (SELECT id + FROM instances + WHERE block_device_mapping_backup.instance_uuid = instances.uuid + ); + + DROP TABLE block_device_mapping; + + CREATE TABLE block_device_mapping ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + instance_id INTEGER NOT NULL, + device_name VARCHAR(255) NOT NULL, + delete_on_termination BOOLEAN, + virtual_name VARCHAR(255), + snapshot_id INTEGER, + volume_id INTEGER, + volume_size INTEGER, + no_device BOOLEAN, + connection_info TEXT, + PRIMARY KEY (id), + FOREIGN KEY(snapshot_id) REFERENCES snapshots (id), + CHECK (deleted IN (0, 1)), + CHECK (delete_on_termination IN (0, 1)), + CHECK (no_device IN (0, 1)), + FOREIGN KEY(volume_id) REFERENCES volumes (id), + FOREIGN KEY(instance_id) REFERENCES instances (id) + ); + + INSERT INTO block_device_mapping + SELECT created_at, + updated_at, + deleted_at, + deleted, + id, + instance_id, + device_name, + delete_on_termination, + virtual_name, + snapshot_id, + volume_id, + volume_size, + no_device, + connection_info + FROM block_device_mapping_backup; + + DROP TABLE block_device_mapping_backup; + +COMMIT;
\ No newline at end of file diff --git a/nova/db/sqlalchemy/migrate_repo/versions/088_sqlite_upgrade.sql b/nova/db/sqlalchemy/migrate_repo/versions/088_sqlite_upgrade.sql new file mode 100644 index 000000000..d75d2ffa2 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/088_sqlite_upgrade.sql @@ -0,0 +1,97 @@ +BEGIN TRANSACTION; + CREATE TEMPORARY TABLE block_device_mapping_backup ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + instance_id INTEGER NOT NULL, + device_name VARCHAR(255) NOT NULL, + delete_on_termination BOOLEAN, + virtual_name VARCHAR(255), + snapshot_id INTEGER, + volume_id INTEGER, + volume_size INTEGER, + no_device BOOLEAN, + connection_info TEXT, + instance_uuid VARCHAR(36), + PRIMARY KEY (id), + FOREIGN KEY(snapshot_id) REFERENCES snapshots (id), + CHECK (deleted IN (0, 1)), + CHECK (delete_on_termination IN (0, 1)), + CHECK (no_device IN (0, 1)), + FOREIGN KEY(volume_id) REFERENCES volumes (id), + FOREIGN KEY(instance_id) REFERENCES instances (id) + ); + + INSERT INTO block_device_mapping_backup + SELECT created_at, + updated_at, + deleted_at, + deleted, + id, + instance_id, + device_name, + delete_on_termination, + virtual_name, + snapshot_id, + volume_id, + volume_size, + no_device, + connection_info, + NULL + FROM block_device_mapping; + + UPDATE block_device_mapping_backup + SET instance_uuid= + (SELECT uuid + FROM instances + WHERE block_device_mapping_backup.instance_id = instances.id + ); + + DROP TABLE block_device_mapping; + + CREATE TABLE block_device_mapping ( + created_at DATETIME, + updated_at DATETIME, + deleted_at DATETIME, + deleted BOOLEAN, + id INTEGER NOT NULL, + device_name VARCHAR(255) NOT NULL, + delete_on_termination BOOLEAN, + virtual_name VARCHAR(255), + snapshot_id INTEGER, + volume_id INTEGER, + volume_size INTEGER, + no_device BOOLEAN, + connection_info TEXT, + instance_uuid VARCHAR(36), + PRIMARY KEY (id), + FOREIGN KEY(snapshot_id) REFERENCES snapshots (id), + CHECK (deleted IN (0, 1)), + CHECK (delete_on_termination IN (0, 1)), + CHECK (no_device IN (0, 1)), + FOREIGN KEY(volume_id) REFERENCES volumes (id), + FOREIGN KEY(instance_uuid) REFERENCES instances (uuid) + ); + + INSERT INTO block_device_mapping + SELECT created_at, + updated_at, + deleted_at, + deleted, + id, + device_name, + delete_on_termination, + virtual_name, + snapshot_id, + volume_id, + volume_size, + no_device, + connection_info, + instance_uuid + FROM block_device_mapping_backup; + + DROP TABLE block_device_mapping_backup; + +COMMIT; diff --git a/nova/db/sqlalchemy/migration.py b/nova/db/sqlalchemy/migration.py index 7338a6a80..452c78c19 100644 --- a/nova/db/sqlalchemy/migration.py +++ b/nova/db/sqlalchemy/migration.py @@ -23,12 +23,17 @@ import sys from nova.db.sqlalchemy.session import get_engine from nova import exception from nova import flags +from nova import log as logging + import sqlalchemy import migrate from migrate.versioning import util as migrate_util +LOG = logging.getLogger(__name__) + + @migrate_util.decorator def patched_with_engine(f, *a, **kw): url = a[0] diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index c79db1f04..1544629ff 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -482,12 +482,14 @@ class BlockDeviceMapping(BASE, NovaBase): __tablename__ = "block_device_mapping" id = Column(Integer, primary_key=True, autoincrement=True) - instance_id = Column(Integer, ForeignKey('instances.id'), nullable=False) + instance_uuid = Column(Integer, ForeignKey('instances.uuid'), + nullable=False) instance = relationship(Instance, backref=backref('balock_device_mapping'), - foreign_keys=instance_id, - primaryjoin='and_(BlockDeviceMapping.instance_id==' - 'Instance.id,' + foreign_keys=instance_uuid, + primaryjoin='and_(BlockDeviceMapping.' + 'instance_uuid==' + 'Instance.uuid,' 'BlockDeviceMapping.deleted==' 'False)') device_name = Column(String(255), nullable=False) |
