Migrate block_device_mapping to use instance uuids.

This started out as wanting cleanup_volumes to take a UUID instead
of an instance ID, and ended up as a wander through the joys of
schema updates. I am assuming that we actually want to transition
these tables across to using the instance UUID instead of just the
ID.

This is my first attempt at a schema update, so please review this
patch with skepticism. Resolves bug 977975. Partially resolves
blueprint finish-uuid-conversion.

Change-Id: Ib5a6f8a872ea0530e201c70e9ac01cd14f82c557
This commit is contained in:
Michael Still 2012-04-08 11:50:12 +10:00
parent 62bcf37959
commit 58af96d3e0
15 changed files with 390 additions and 102 deletions

View File

@ -998,7 +998,7 @@ class CloudController(object):
def _format_attr_block_device_mapping(instance, result):
tmp = {}
self._format_instance_root_device_name(instance, tmp)
self._format_instance_bdm(context, instance_id,
self._format_instance_bdm(context, instance['uuid'],
tmp['rootDeviceName'], result)
def _format_attr_disable_api_termination(instance, result):
@ -1098,13 +1098,13 @@ class CloudController(object):
instances_set.append(i)
return {'instancesSet': instances_set}
def _format_instance_bdm(self, context, instance_id, root_device_name,
def _format_instance_bdm(self, context, instance_uuid, root_device_name,
result):
"""Format InstanceBlockDeviceMappingResponseItemType"""
root_device_type = 'instance-store'
mapping = []
for bdm in db.block_device_mapping_get_all_by_instance(context,
instance_id):
instance_uuid):
volume_id = bdm['volume_id']
if (volume_id is None or bdm['no_device']):
continue
@ -1220,7 +1220,7 @@ class CloudController(object):
i['launchTime'] = instance['created_at']
i['amiLaunchIndex'] = instance['launch_index']
self._format_instance_root_device_name(instance, i)
self._format_instance_bdm(context, instance_id,
self._format_instance_bdm(context, instance['uuid'],
i['rootDeviceName'], i)
host = instance['host']
services = db.service_get_all_by_host(context.elevated(), host)

View File

@ -99,7 +99,7 @@ class MetadataRequestHandler(wsgi.Application):
# 'ephemeralN', 'swap' and ebs
for bdm in db.block_device_mapping_get_all_by_instance(
ctxt, instance_ref['id']):
ctxt, instance_ref['uuid']):
if bdm['no_device']:
continue

View File

@ -484,7 +484,7 @@ class API(BaseAPI):
return size
def _update_image_block_device_mapping(self, elevated_context,
instance_type, instance_id,
instance_type, instance_uuid,
mappings):
"""tell vm driver to create ephemeral/swap device at boot time by
updating BlockDeviceMapping
@ -507,7 +507,7 @@ class API(BaseAPI):
continue
values = {
'instance_id': instance_id,
'instance_uuid': instance_uuid,
'device_name': bdm['device'],
'virtual_name': virtual_name,
'volume_size': size}
@ -515,7 +515,7 @@ class API(BaseAPI):
values)
def _update_block_device_mapping(self, elevated_context,
instance_type, instance_id,
instance_type, instance_uuid,
block_device_mapping):
"""tell vm driver to attach volume at boot time by updating
BlockDeviceMapping
@ -524,7 +524,7 @@ class API(BaseAPI):
for bdm in block_device_mapping:
assert 'device_name' in bdm
values = {'instance_id': instance_id}
values = {'instance_uuid': instance_uuid}
for key in ('device_name', 'delete_on_termination', 'virtual_name',
'snapshot_id', 'volume_id', 'volume_size',
'no_device'):
@ -587,12 +587,13 @@ class API(BaseAPI):
# BlockDeviceMapping table
self._update_image_block_device_mapping(elevated, instance_type,
instance_id, image['properties'].get('mappings', []))
self._update_block_device_mapping(elevated, instance_type, instance_id,
instance_uuid, image['properties'].get('mappings', []))
self._update_block_device_mapping(elevated, instance_type,
instance_uuid,
image['properties'].get('block_device_mapping', []))
# override via command line option
self._update_block_device_mapping(elevated, instance_type, instance_id,
block_device_mapping)
self._update_block_device_mapping(elevated, instance_type,
instance_uuid, block_device_mapping)
# Set sane defaults if not specified
updates = {}

View File

@ -354,7 +354,7 @@ class ComputeManager(manager.SchedulerDependentManager):
swap = None
ephemerals = []
for bdm in self.db.block_device_mapping_get_all_by_instance(
context, instance['id']):
context, instance['uuid']):
LOG.debug(_('Setting up bdm %s'), bdm, instance=instance)
if bdm['no_device']:
@ -616,13 +616,13 @@ class ComputeManager(manager.SchedulerDependentManager):
instance=instance)
self.network_api.deallocate_for_instance(context, instance)
def _get_instance_volume_bdms(self, context, instance_id):
def _get_instance_volume_bdms(self, context, instance_uuid):
bdms = self.db.block_device_mapping_get_all_by_instance(context,
instance_id)
instance_uuid)
return [bdm for bdm in bdms if bdm['volume_id']]
def _get_instance_volume_bdm(self, context, instance_id, volume_id):
bdms = self._get_instance_volume_bdms(context, instance_id)
def _get_instance_volume_bdm(self, context, instance_uuid, volume_id):
bdms = self._get_instance_volume_bdms(context, instance_uuid)
for bdm in bdms:
# NOTE(vish): Comparing as strings because the os_api doesn't
# convert to integer and we may wish to support uuids
@ -630,8 +630,8 @@ class ComputeManager(manager.SchedulerDependentManager):
if str(bdm['volume_id']) == str(volume_id):
return bdm
def _get_instance_volume_block_device_info(self, context, instance_id):
bdms = self._get_instance_volume_bdms(context, instance_id)
def _get_instance_volume_block_device_info(self, context, instance_uuid):
bdms = self._get_instance_volume_bdms(context, instance_uuid)
block_device_mapping = []
for bdm in bdms:
cinfo = utils.loads(bdm['connection_info'])
@ -667,8 +667,6 @@ class ComputeManager(manager.SchedulerDependentManager):
def _shutdown_instance(self, context, instance, action_str):
"""Shutdown an instance on this host."""
context = context.elevated()
instance_id = instance['id']
instance_uuid = instance['uuid']
LOG.audit(_('%(action_str)s instance') % {'action_str': action_str},
context=context, instance=instance)
@ -680,9 +678,9 @@ class ComputeManager(manager.SchedulerDependentManager):
self._deallocate_network(context, instance)
# NOTE(vish) get bdms before destroying the instance
bdms = self._get_instance_volume_bdms(context, instance_id)
bdms = self._get_instance_volume_bdms(context, instance['uuid'])
block_device_info = self._get_instance_volume_block_device_info(
context, instance_id)
context, instance['uuid'])
self.driver.destroy(instance, self._legacy_nw_info(network_info),
block_device_info)
for bdm in bdms:
@ -701,11 +699,12 @@ class ComputeManager(manager.SchedulerDependentManager):
self._notify_about_instance_usage(context, instance, "shutdown.end")
def _cleanup_volumes(self, context, instance_id):
def _cleanup_volumes(self, context, instance_uuid):
bdms = self.db.block_device_mapping_get_all_by_instance(context,
instance_id)
instance_uuid)
for bdm in bdms:
LOG.debug(_("terminating bdm %s") % bdm)
LOG.debug(_("terminating bdm %s") % bdm,
instance_uuid=instance_uuid)
if bdm['volume_id'] and bdm['delete_on_termination']:
volume = self.volume_api.get(context, bdm['volume_id'])
self.volume_api.delete(context, volume)
@ -716,7 +715,7 @@ class ComputeManager(manager.SchedulerDependentManager):
instance_id = instance['id']
self._notify_about_instance_usage(context, instance, "delete.start")
self._shutdown_instance(context, instance, 'Terminating')
self._cleanup_volumes(context, instance_id)
self._cleanup_volumes(context, instance['uuid'])
instance = self._instance_update(context,
instance_id,
vm_state=vm_states.DELETED,
@ -1711,7 +1710,6 @@ class ComputeManager(manager.SchedulerDependentManager):
volume = self.volume_api.get(context, volume_id)
context = context.elevated()
instance_ref = self.db.instance_get_by_uuid(context, instance_uuid)
instance_id = instance_ref['id']
LOG.audit(_('Attaching volume %(volume_id)s to %(mountpoint)s'),
locals(), context=context, instance=instance_ref)
try:
@ -1740,9 +1738,9 @@ class ComputeManager(manager.SchedulerDependentManager):
volume,
connector)
self.volume_api.attach(context, volume, instance_id, mountpoint)
self.volume_api.attach(context, volume, instance_ref['id'], mountpoint)
values = {
'instance_id': instance_id,
'instance_uuid': instance_ref['uuid'],
'connection_info': utils.dumps(connection_info),
'device_name': mountpoint,
'delete_on_termination': False,
@ -1777,15 +1775,14 @@ class ComputeManager(manager.SchedulerDependentManager):
def detach_volume(self, context, instance_uuid, volume_id):
"""Detach a volume from an instance."""
instance_ref = self.db.instance_get_by_uuid(context, instance_uuid)
instance_id = instance_ref['id']
bdm = self._get_instance_volume_bdm(context, instance_id, volume_id)
bdm = self._get_instance_volume_bdm(context, instance_uuid, volume_id)
self._detach_volume(context, instance_ref, bdm)
volume = self.volume_api.get(context, volume_id)
connector = self.driver.get_volume_connector(instance_ref)
self.volume_api.terminate_connection(context, volume, connector)
self.volume_api.detach(context.elevated(), volume)
self.db.block_device_mapping_destroy_by_instance_and_volume(
context, instance_id, volume_id)
context, instance_uuid, volume_id)
return True
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@ -1888,7 +1885,7 @@ class ComputeManager(manager.SchedulerDependentManager):
# If any volume is mounted, prepare here.
block_device_info = self._get_instance_volume_block_device_info(
context, instance_id)
context, instance_ref['uuid'])
if not block_device_info['block_device_mapping']:
LOG.info(_('Instance has no volume.'), instance=instance_ref)
@ -1958,7 +1955,7 @@ class ComputeManager(manager.SchedulerDependentManager):
try:
# Checking volume node is working correctly when any volumes
# are attached to instances.
if self._get_instance_volume_bdms(context, instance_id):
if self._get_instance_volume_bdms(context, instance_ref['uuid']):
rpc.call(context,
FLAGS.volume_topic,
{'method': 'check_for_export',
@ -2010,7 +2007,7 @@ class ComputeManager(manager.SchedulerDependentManager):
instance=instance_ref)
# Detaching volumes.
for bdm in self._get_instance_volume_bdms(ctxt, instance_ref['id']):
for bdm in self._get_instance_volume_bdms(ctxt, instance_ref['uuid']):
# NOTE(vish): We don't want to actually mark the volume
# detached, or delete the bdm, just remove the
# connection from this host.
@ -2146,7 +2143,8 @@ class ComputeManager(manager.SchedulerDependentManager):
self.network_api.setup_networks_on_host(context, instance_ref,
self.host)
for bdm in self._get_instance_volume_bdms(context, instance_ref['id']):
for bdm in self._get_instance_volume_bdms(context,
instance_ref['uuid']):
volume_id = bdm['volume_id']
volume = self.volume_api.get(context, volume_id)
self.volume_api.update(context, volume, {'status': 'in-use'})
@ -2477,7 +2475,7 @@ class ComputeManager(manager.SchedulerDependentManager):
"DELETED but still present on host."),
locals(), instance=instance)
self._shutdown_instance(context, instance, 'Terminating')
self._cleanup_volumes(context, instance['id'])
self._cleanup_volumes(context, instance['uuid'])
else:
raise Exception(_("Unrecognized value '%(action)s'"
" for FLAGS.running_deleted_"

View File

@ -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)
####################

View File

@ -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(),

View File

@ -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()

View File

@ -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;

View File

@ -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;

View File

@ -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]

View File

@ -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)

View File

@ -945,42 +945,43 @@ class CloudTestCase(test.TestCase):
'root_device_name': '/dev/sdc1'})
instance_id = inst1['id']
instance_uuid = inst1['uuid']
mappings0 = [
{'instance_id': instance_id,
{'instance_uuid': instance_uuid,
'device_name': '/dev/sdb1',
'snapshot_id': '1',
'volume_id': '2'},
{'instance_id': instance_id,
{'instance_uuid': instance_uuid,
'device_name': '/dev/sdb2',
'volume_id': '3',
'volume_size': 1},
{'instance_id': instance_id,
{'instance_uuid': instance_uuid,
'device_name': '/dev/sdb3',
'delete_on_termination': True,
'snapshot_id': '4',
'volume_id': '5'},
{'instance_id': instance_id,
{'instance_uuid': instance_uuid,
'device_name': '/dev/sdb4',
'delete_on_termination': False,
'snapshot_id': '6',
'volume_id': '7'},
{'instance_id': instance_id,
{'instance_uuid': instance_uuid,
'device_name': '/dev/sdb5',
'snapshot_id': '8',
'volume_id': '9',
'volume_size': 0},
{'instance_id': instance_id,
{'instance_uuid': instance_uuid,
'device_name': '/dev/sdb6',
'snapshot_id': '10',
'volume_id': '11',
'volume_size': 1},
{'instance_id': instance_id,
{'instance_uuid': instance_uuid,
'device_name': '/dev/sdb7',
'no_device': True},
{'instance_id': instance_id,
{'instance_uuid': instance_uuid,
'device_name': '/dev/sdb8',
'virtual_name': 'swap'},
{'instance_id': instance_id,
{'instance_uuid': instance_uuid,
'device_name': '/dev/sdb9',
'virtual_name': 'ephemeral3'}]
@ -990,9 +991,9 @@ class CloudTestCase(test.TestCase):
def _tearDownBlockDeviceMapping(self, inst1, inst2, volumes):
for vol in volumes:
db.volume_destroy(self.context, vol['id'])
for id in (inst1['id'], inst2['id']):
for uuid in (inst1['uuid'], inst2['uuid']):
for bdm in db.block_device_mapping_get_all_by_instance(
self.context, id):
self.context, uuid):
db.block_device_mapping_destroy(self.context, bdm['id'])
db.instance_destroy(self.context, inst2['id'])
db.instance_destroy(self.context, inst1['id'])
@ -1043,8 +1044,8 @@ class CloudTestCase(test.TestCase):
(inst1, inst2, volumes) = self._setUpBlockDeviceMapping()
result = {}
self.cloud._format_instance_bdm(self.context, inst1['id'], '/dev/sdb1',
result)
self.cloud._format_instance_bdm(self.context, inst1['uuid'],
'/dev/sdb1', result)
self.assertSubDictMatch(
{'rootDeviceType': self._expected_instance_bdm1['rootDeviceType']},
result)
@ -1052,8 +1053,8 @@ class CloudTestCase(test.TestCase):
self._expected_block_device_mapping0, result['blockDeviceMapping'])
result = {}
self.cloud._format_instance_bdm(self.context, inst2['id'], '/dev/sdc1',
result)
self.cloud._format_instance_bdm(self.context, inst2['uuid'],
'/dev/sdc1', result)
self.assertSubDictMatch(
{'rootDeviceType': self._expected_instance_bdm2['rootDeviceType']},
result)
@ -2166,6 +2167,7 @@ class CloudTestCase(test.TestCase):
def fake_get(ctxt, instance_id):
return {
'id': 0,
'uuid': 'e5fe5518-0288-4fa3-b0c4-c79764101b85',
'root_device_name': '/dev/sdh',
'security_groups': [{'name': 'fake0'}, {'name': 'fake1'}],
'vm_state': vm_states.STOPPED,

View File

@ -124,7 +124,7 @@ class EC2ValidateTestCase(test.TestCase):
instance_id='i-1234',
device='/dev/vdc')
def test_describe_instance_ttribute(self):
def test_describe_instance_attribute(self):
for ec2_id, e in self.ec2_id_exception_map:
self.assertRaises(e,
self.cloud.describe_instance_attribute,

View File

@ -1402,37 +1402,38 @@ class ComputeTestCase(BaseTestCase):
"""Confirm exception when pre_live_migration fails."""
# creating instance testdata
inst_ref = self._create_fake_instance({'host': 'dummy'})
instance_id = inst_ref['id']
c = context.get_admin_context()
topic = db.queue_get_for(c, FLAGS.compute_topic, inst_ref['host'])
# creating volume testdata
volume_id = 1
db.volume_create(c, {'id': volume_id})
values = {'instance_id': instance_id, 'device_name': '/dev/vdc',
'delete_on_termination': False, 'volume_id': volume_id}
values = {'instance_uuid': inst_ref['uuid'], 'device_name': '/dev/vdc',
'delete_on_termination': False, 'volume_id': volume_id}
db.block_device_mapping_create(c, values)
# creating mocks
self.mox.StubOutWithMock(rpc, 'call')
rpc.call(c, FLAGS.volume_topic, {"method": "check_for_export",
"args": {'instance_id': instance_id}})
rpc.call(c, FLAGS.volume_topic,
{"method": "check_for_export",
"args": {'instance_id': inst_ref['id']}})
self.mox.StubOutWithMock(self.compute.driver, 'get_instance_disk_info')
self.compute.driver.get_instance_disk_info(inst_ref.name)
rpc.call(c, topic,
{"method": "pre_live_migration",
"args": {'instance_id': instance_id,
"args": {'instance_id': inst_ref['id'],
'block_migration': True,
'disk': None}
}).AndRaise(rpc.common.RemoteError('', '', ''))
# mocks for rollback
rpc.call(c, 'network', {'method': 'setup_networks_on_host',
'args': {'instance_id': instance_id,
'args': {'instance_id': inst_ref['id'],
'host': self.compute.host,
'teardown': False}})
rpc.call(c, topic, {"method": "remove_volume_connection",
"args": {'instance_id': instance_id,
"args": {'instance_id': inst_ref['id'],
'volume_id': volume_id}})
rpc.cast(c, topic, {"method": "rollback_live_migration_at_destination",
"args": {'instance_id': inst_ref['id']}})
@ -1441,11 +1442,11 @@ class ComputeTestCase(BaseTestCase):
self.mox.ReplayAll()
self.assertRaises(rpc_common.RemoteError,
self.compute.live_migration,
c, instance_id, inst_ref['host'], True)
c, inst_ref['id'], inst_ref['host'], True)
# cleanup
for bdms in db.block_device_mapping_get_all_by_instance(c,
instance_id):
for bdms in db.block_device_mapping_get_all_by_instance(
c, inst_ref['uuid']):
db.block_device_mapping_destroy(c, bdms['id'])
db.volume_destroy(c, volume_id)
db.instance_destroy(c, inst_ref['id'])
@ -1675,7 +1676,7 @@ class ComputeTestCase(BaseTestCase):
self.mox.StubOutWithMock(self.compute, "_cleanup_volumes")
self.compute._cleanup_volumes(admin_context,
instance['id']).AndReturn(None)
instance['uuid']).AndReturn(None)
self.mox.ReplayAll()
self.compute._cleanup_running_deleted_instances(admin_context)
@ -3095,11 +3096,11 @@ class ComputeAPITestCase(BaseTestCase):
'no_device': True}]
self.compute_api._update_image_block_device_mapping(
self.context, instance_type, instance['id'], mappings)
self.context, instance_type, instance['uuid'], mappings)
bdms = [self._parse_db_block_device_mapping(bdm_ref)
for bdm_ref in db.block_device_mapping_get_all_by_instance(
self.context, instance['id'])]
self.context, instance['uuid'])]
expected_result = [
{'virtual_name': 'swap', 'device_name': '/dev/sdb1',
'volume_size': swap_size},
@ -3116,10 +3117,10 @@ class ComputeAPITestCase(BaseTestCase):
self.compute_api._update_block_device_mapping(
self.context, instance_types.get_default_instance_type(),
instance['id'], block_device_mapping)
instance['uuid'], block_device_mapping)
bdms = [self._parse_db_block_device_mapping(bdm_ref)
for bdm_ref in db.block_device_mapping_get_all_by_instance(
self.context, instance['id'])]
self.context, instance['uuid'])]
expected_result = [
{'snapshot_id': 0x12345678, 'device_name': '/dev/sda1'},
@ -3143,7 +3144,7 @@ class ComputeAPITestCase(BaseTestCase):
self.assertDictListMatch(bdms, expected_result)
for bdm in db.block_device_mapping_get_all_by_instance(
self.context, instance['id']):
self.context, instance['uuid']):
db.block_device_mapping_destroy(self.context, bdm['id'])
instance = db.instance_get_by_uuid(self.context, instance['uuid'])
self.compute.terminate_instance(self.context, instance['uuid'])

View File

@ -47,20 +47,21 @@ class MetadataTestCase(test.TestCase):
def setUp(self):
super(MetadataTestCase, self).setUp()
self.instance = ({'id': 1,
'name': 'fake',
'project_id': 'test',
'key_name': None,
'host': 'test',
'launch_index': 1,
'instance_type': {'name': 'm1.tiny'},
'reservation_id': 'r-xxxxxxxx',
'user_data': '',
'image_ref': 7,
'vcpus': 1,
'fixed_ips': [],
'root_device_name': '/dev/sda1',
'info_cache': {'network_info': []},
'hostname': 'test'})
'uuid': 'b65cee2f-8c69-4aeb-be2f-f79742548fc2',
'name': 'fake',
'project_id': 'test',
'key_name': None,
'host': 'test',
'launch_index': 1,
'instance_type': {'name': 'm1.tiny'},
'reservation_id': 'r-xxxxxxxx',
'user_data': '',
'image_ref': 7,
'vcpus': 1,
'fixed_ips': [],
'root_device_name': '/dev/sda1',
'info_cache': {'network_info': []},
'hostname': 'test'})
def fake_get_floating_ips_by_fixed_address(self, context, fixed_ip):
return ['1.2.3.4', '5.6.7.8']
@ -144,11 +145,13 @@ class MetadataTestCase(test.TestCase):
"""Make sure that _get_instance_mapping works"""
ctxt = None
instance_ref0 = {'id': 0,
'uuid': 'e5fe5518-0288-4fa3-b0c4-c79764101b85',
'root_device_name': None}
instance_ref1 = {'id': 0,
'uuid': 'b65cee2f-8c69-4aeb-be2f-f79742548fc2',
'root_device_name': '/dev/sda1'}
def fake_bdm_get(ctxt, id):
def fake_bdm_get(ctxt, uuid):
return [{'volume_id': 87654321,
'snapshot_id': None,
'no_device': None,