summaryrefslogtreecommitdiffstats
path: root/nova/db
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-04-30 22:23:11 +0000
committerGerrit Code Review <review@openstack.org>2012-04-30 22:23:11 +0000
commitdda036044e2ddb249aef8d483269bcbf97141abd (patch)
tree86c4f07c5198265e06752b26a7120371307f9db0 /nova/db
parent2c72cb3bcee6b64fff6e3eaa738e4bc80828a830 (diff)
parent58af96d3e01c7fbe993344374190d8afe1a1d0ff (diff)
downloadnova-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.py9
-rw-r--r--nova/db/sqlalchemy/api.py14
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/088_change_instance_id_to_uuid_in_block_device_mapping.py81
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/088_sqlite_downgrade.sql97
-rw-r--r--nova/db/sqlalchemy/migrate_repo/versions/088_sqlite_upgrade.sql97
-rw-r--r--nova/db/sqlalchemy/migration.py5
-rw-r--r--nova/db/sqlalchemy/models.py10
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)