summaryrefslogtreecommitdiff
path: root/openstackclient/tests/functional/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/tests/functional/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/tests/functional/compute')
-rw-r--r--openstackclient/tests/functional/compute/v2/test_server.py87
1 files changed, 87 insertions, 0 deletions
diff --git a/openstackclient/tests/functional/compute/v2/test_server.py b/openstackclient/tests/functional/compute/v2/test_server.py
index e52a42d3..67e2a66e 100644
--- a/openstackclient/tests/functional/compute/v2/test_server.py
+++ b/openstackclient/tests/functional/compute/v2/test_server.py
@@ -614,6 +614,93 @@ class ServerTests(common.ComputeTestCase):
# the attached volume had been deleted
pass
+ def test_server_boot_with_bdm_image(self):
+ # Tests creating a server where the root disk is backed by the given
+ # --image but a --block-device-mapping with type=image is provided so
+ # that the compute service creates a volume from that image and
+ # attaches it as a non-root volume on the server. The block device is
+ # marked as delete_on_termination=True so it will be automatically
+ # deleted when the server is deleted.
+
+ # create server with bdm type=image
+ # NOTE(mriedem): This test is a bit unrealistic in that specifying the
+ # same image in the block device as the --image option does not really
+ # make sense, but we just want to make sure everything is processed
+ # as expected where nova creates a volume from the image and attaches
+ # that volume to the server.
+ server_name = uuid.uuid4().hex
+ server = json.loads(self.openstack(
+ 'server create -f json ' +
+ '--flavor ' + self.flavor_name + ' ' +
+ '--image ' + self.image_name + ' ' +
+ '--block-device-mapping '
+ # This means create a 1GB volume from the specified image, attach
+ # it to the server at /dev/vdb and delete the volume when the
+ # server is deleted.
+ 'vdb=' + self.image_name + ':image:1:true ' +
+ self.network_arg + ' ' +
+ '--wait ' +
+ server_name
+ ))
+ self.assertIsNotNone(server["id"])
+ self.assertEqual(
+ server_name,
+ server['name'],
+ )
+ self.wait_for_status(server_name, 'ACTIVE')
+
+ # check server volumes_attached, format is
+ # {"volumes_attached": "id='2518bc76-bf0b-476e-ad6b-571973745bb5'",}
+ cmd_output = json.loads(self.openstack(
+ 'server show -f json ' +
+ server_name
+ ))
+ volumes_attached = cmd_output['volumes_attached']
+ self.assertTrue(volumes_attached.startswith('id='))
+ attached_volume_id = volumes_attached.replace('id=', '')
+
+ # check the volume that attached on server
+ cmd_output = json.loads(self.openstack(
+ 'volume show -f json ' +
+ attached_volume_id
+ ))
+ attachments = cmd_output['attachments']
+ self.assertEqual(
+ 1,
+ len(attachments),
+ )
+ self.assertEqual(
+ server['id'],
+ attachments[0]['server_id'],
+ )
+ self.assertEqual(
+ "in-use",
+ cmd_output['status'],
+ )
+ # TODO(mriedem): If we can parse the volume_image_metadata field from
+ # the volume show output we could assert the image_name is what we
+ # specified. volume_image_metadata is something like this:
+ # {u'container_format': u'bare', u'min_ram': u'0',
+ # u'disk_format': u'qcow2', u'image_name': u'cirros-0.4.0-x86_64-disk',
+ # u'image_id': u'05496c83-e2df-4c2f-9e48-453b6e49160d',
+ # u'checksum': u'443b7623e27ecf03dc9e01ee93f67afe', u'min_disk': u'0',
+ # u'size': u'12716032'}
+
+ # delete server, then check the attached volume has been deleted
+ self.openstack('server delete --wait ' + server_name)
+ cmd_output = json.loads(self.openstack(
+ 'volume list -f json'
+ ))
+ target_volume = [each_volume
+ for each_volume in cmd_output
+ if each_volume['ID'] == attached_volume_id]
+ if target_volume:
+ # check the attached volume is 'deleting' status
+ self.assertEqual('deleting', target_volume[0]['Status'])
+ else:
+ # the attached volume had been deleted
+ pass
+
def test_server_create_with_none_network(self):
"""Test server create with none network option."""
server_name = uuid.uuid4().hex