From 91cc2d5f974d67d91e1e783aaec105c489a47cce Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Wed, 22 Jun 2011 12:54:22 +0900 Subject: volume/api: introduce create_snapshot_force() Introduce create_snapshot_force() which create snapshot even when the volume is in in-use. This is needed for CreateImage with no_reboot=true. --- nova/compute/api.py | 24 +++++++++++------------- nova/volume/api.py | 13 +++++++++++-- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index e2692a42f..884ec9198 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -264,7 +264,7 @@ class API(base.Base): for bdm in mappings: LOG.debug(_("bdm %s"), bdm) - virtual_name = bdm['virtualName'] + virtual_name = bdm['virtual'] if virtual_name == 'ami' or virtual_name == 'root': continue @@ -272,9 +272,10 @@ class API(base.Base): virtual_name.startswith('ephemeral')) values = { 'instance_id': instance_id, - 'device_name': bdm['deviceName'], + 'device_name': bdm['device'], 'virtual_name': virtual_name, } - self.db.block_device_mapping_create(elevated_context, values) + self.db.block_device_mapping_update_or_create(elevated_context, + values) def _update_block_device_mapping(self, elevated_context, instance_id, block_device_mapping): @@ -285,15 +286,11 @@ class API(base.Base): LOG.debug(_('bdm %s'), bdm) assert 'device_name' in bdm - values = { - 'instance_id': instance_id, - 'device_name': bdm['device_name'], - 'delete_on_termination': bdm.get('delete_on_termination'), - 'virtual_name': bdm.get('virtual_name'), - 'snapshot_id': bdm.get('snapshot_id'), - 'volume_id': bdm.get('volume_id'), - 'volume_size': bdm.get('volume_size'), - 'no_device': bdm.get('no_device')} + values = {'instance_id': instance_id} + for key in ('device_name', 'delete_on_termination', 'virtual_name', + 'snapshot_id', 'volume_id', 'volume_size', + 'no_device'): + values[key] = bdm.get(key) # NOTE(yamahata): NoDevice eliminates devices defined in image # files by command line option. @@ -305,7 +302,8 @@ class API(base.Base): 'virtual_name'): values[k] = None - self.db.block_device_mapping_create(elevated_context, values) + self.db.block_device_mapping_update_or_create(elevated_context, + values) def create_db_entry_for_new_instance(self, context, image, base_options, security_groups, block_device_mapping, num=1): diff --git a/nova/volume/api.py b/nova/volume/api.py index 7d27abff9..cfc274c77 100644 --- a/nova/volume/api.py +++ b/nova/volume/api.py @@ -140,9 +140,10 @@ class API(base.Base): {"method": "remove_volume", "args": {'volume_id': volume_id}}) - def create_snapshot(self, context, volume_id, name, description): + def _create_snapshot(self, context, volume_id, name, description, + force=False): volume = self.get(context, volume_id) - if volume['status'] != "available": + if ((not force) and (volume['status'] != "available")): raise exception.ApiError(_("Volume status must be available")) options = { @@ -164,6 +165,14 @@ class API(base.Base): "snapshot_id": snapshot['id']}}) return snapshot + def create_snapshot(self, context, volume_id, name, description): + return self._create_snapshot(context, volume_id, name, description, + False) + + def create_snapshot_force(self, context, volume_id, name, description): + return self._create_snapshot(context, volume_id, name, description, + True) + def delete_snapshot(self, context, snapshot_id): snapshot = self.get_snapshot(context, snapshot_id) if snapshot['status'] != "available": -- cgit