summaryrefslogtreecommitdiff
path: root/openstackclient/compute
diff options
context:
space:
mode:
authorMatt Riedemann <mriedem.os@gmail.com>2019-07-29 12:59:52 -0400
committerDean Troyer <dtroyer@gmail.com>2019-08-09 16:36:17 +0000
commit6a199bd14152889f18ad95919a4bee9c0c083d5d (patch)
treedc3e16951eaec250d7c151962365d94eecb50ebe /openstackclient/compute
parentc4743199096e77bdc89423dc37f632ac24acdba1 (diff)
downloadpython-openstackclient-6a199bd14152889f18ad95919a4bee9c0c083d5d.tar.gz
Support type=image with --block-device-mapping option
The --block-device-mapping option on the server create command currently only supports booting from volume and volume snapshot. A common boot-from-volume scenario is providing an image and letting nova orchestrate the creation of the image-backed volume and attaching it to the server. This adds support for type=image in the --block-device-mapping option. The volume size is required in this case. Note that the CLI currently says if type=snapshot that size is also required but that's technically not true. When booting from a volume snapshot, the compute API will use the size of the volume snapshot to create the volume if an explicit size is not provided. For the purposes of this patch, we need the size anyway for the image being the block device mapping source type. Change-Id: I57b3c261d8309f7b9f62a3e91612bce592a887a3 Story: 2006302 Task: 36016
Diffstat (limited to 'openstackclient/compute')
-rw-r--r--openstackclient/compute/v2/server.py30
1 files changed, 24 insertions, 6 deletions
diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index ea87d9ce..a0afa389 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -575,14 +575,17 @@ class CreateServer(command.ShowOne):
# NOTE(RuiChen): Add '\n' at the end of line to put each item in
# the separated line, avoid the help message looks
# messy, see _SmartHelpFormatter in cliff.
+ # FIXME(mriedem): Technically <id> can be the name or ID.
help=_('Create a block device on the server.\n'
'Block device mapping in the format\n'
'<dev-name>=<id>:<type>:<size(GB)>:<delete-on-terminate>\n'
'<dev-name>: block device name, like: vdb, xvdc '
'(required)\n'
- '<id>: UUID of the volume or snapshot (required)\n'
- '<type>: volume or snapshot; default: volume (optional)\n'
- '<size(GB)>: volume size if create from snapshot '
+ '<id>: UUID of the volume, volume snapshot or image '
+ '(required)\n'
+ '<type>: volume, snapshot or image; default: volume '
+ '(optional)\n'
+ '<size(GB)>: volume size if create from image or snapshot '
'(optional)\n'
'<delete-on-terminate>: true or false; default: false '
'(optional)\n'
@@ -793,7 +796,7 @@ class CreateServer(command.ShowOne):
mapping = {'device_name': dev_name}
# 1. decide source and destination type
if (len(dev_map) > 1 and
- dev_map[1] in ('volume', 'snapshot')):
+ dev_map[1] in ('volume', 'snapshot', 'image')):
mapping['source_type'] = dev_map[1]
else:
mapping['source_type'] = 'volume'
@@ -808,14 +811,29 @@ class CreateServer(command.ShowOne):
snapshot_id = utils.find_resource(
volume_client.volume_snapshots, dev_map[0]).id
mapping['uuid'] = snapshot_id
+ elif mapping['source_type'] == 'image':
+ # NOTE(mriedem): In case --image is specified with the same
+ # image, that becomes the root disk for the server. If the
+ # block device is specified with a root device name, e.g.
+ # vda, then the compute API will likely fail complaining
+ # that there is a conflict. So if using the same image ID,
+ # which doesn't really make sense but it's allowed, the
+ # device name would need to be a non-root device, e.g. vdb.
+ # Otherwise if the block device image is different from the
+ # one specified by --image, then the compute service will
+ # create a volume from the image and attach it to the
+ # server as a non-root volume.
+ image_id = utils.find_resource(
+ image_client.images, dev_map[0]).id
+ mapping['uuid'] = image_id
# 3. append size and delete_on_termination if exist
if len(dev_map) > 2 and dev_map[2]:
mapping['volume_size'] = dev_map[2]
if len(dev_map) > 3 and dev_map[3]:
mapping['delete_on_termination'] = dev_map[3]
else:
- msg = _("Volume or snapshot (name or ID) must be specified if "
- "--block-device-mapping is specified")
+ msg = _("Volume, volume snapshot or image (name or ID) must "
+ "be specified if --block-device-mapping is specified")
raise exceptions.CommandError(msg)
block_device_mapping_v2.append(mapping)