Make snapshot_volume_backed use new-world objects

This patch makes snapshotting of a volume backed instance code path use
new-world block device objects, and thus transitions snapshotting to use
block device mapping v2 data format.

This means that all images that are created by snapshotting volume
backed instances after this change will have new block device mapping
format in their properties. To be able to distinguish between those, an
additional field (bdm_v2) was added to the image properties. This flag
will be taken into account when booting an instance and all necessary
conversions will be done so that both formats are supported. The legacy
block device format will continue to be supported in images, even when
we deprecate it in the API (after v2).

Another noteworthy point is that block device mapping data added to the
image will no longer contain the device name, as it will be dependent on
the configuration when booting a new instance. The mapping will however
keep the boot order.

The code in snapshot will also take care that all of the mappings
present in the image properties are handled and not re-created on
booting an instance from the snapshot image.

Part of the blueprint: icehouse-objects
Part of the blueprint: clean-up-legacy-block-device-mapping

Change-Id: I441cf8f2df0b92a9cc4096e77a90c37a06270eb5
This commit is contained in:
Nikola Dipanov
2013-11-28 14:59:57 +01:00
parent 15e91d7a61
commit 33e3d4c6b9
7 changed files with 249 additions and 63 deletions

View File

@@ -223,6 +223,14 @@ class BlockDeviceDict(dict):
return legacy_block_device
def get_image_mapping(self):
drop_fields = (set(['connection_info', 'device_name']) |
self._db_only_fields)
mapping_dict = dict(self)
for fld in drop_fields:
mapping_dict.pop(fld, None)
return mapping_dict
def is_safe_for_update(block_device_dict):
"""Determine if passed dict is a safe subset for update.
@@ -252,6 +260,18 @@ def create_image_bdm(image_ref, boot_index=0):
'destination_type': 'local'})
def snapshot_from_bdm(snapshot_id, template):
"""Create a basic volume snapshot BDM from a given template bdm."""
copy_from_template = ['disk_bus', 'device_type', 'boot_index']
snapshot_dict = {'source_type': 'snapshot',
'destination_type': 'volume',
'snapshot_id': snapshot_id}
for key in copy_from_template:
snapshot_dict[key] = template.get(key)
return BlockDeviceDict(snapshot_dict)
def legacy_mapping(block_device_mapping):
"""Transform a list of block devices of an instance back to the
legacy data format.
@@ -277,11 +297,19 @@ def legacy_mapping(block_device_mapping):
def from_legacy_mapping(legacy_block_device_mapping, image_uuid='',
root_device_name=None):
root_device_name=None, no_root=False):
"""Transform a legacy list of block devices to the new data format."""
new_bdms = [BlockDeviceDict.from_legacy(legacy_bdm)
for legacy_bdm in legacy_block_device_mapping]
# NOTE (ndipanov): We will not decide which device is root here - we assume
# that it will be supplied later. This is useful for having the root device
# as part of the image defined mappings that are already in the v2 format.
if no_root:
for bdm in new_bdms:
bdm['boot_index'] = -1
return new_bdms
image_bdm = None
volume_backed = False