Skip to content

Commit 8248efa

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "compute: Allow users to manually specify bootable volumes"
2 parents 5b42583 + 91277e7 commit 8248efa

3 files changed

Lines changed: 58 additions & 12 deletions

File tree

openstackclient/compute/v2/server.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -913,9 +913,7 @@ def get_parser(self, prog_name):
913913
required=True,
914914
help=_('Create server with this flavor (name or ID)'),
915915
)
916-
disk_group = parser.add_mutually_exclusive_group(
917-
required=True,
918-
)
916+
disk_group = parser.add_mutually_exclusive_group()
919917
disk_group.add_argument(
920918
'--image',
921919
metavar='<image>',
@@ -1473,14 +1471,14 @@ def _match_image(image_api, wanted_properties):
14731471
if volume:
14741472
block_device_mapping_v2 = [{
14751473
'uuid': volume,
1476-
'boot_index': '0',
1474+
'boot_index': 0,
14771475
'source_type': 'volume',
14781476
'destination_type': 'volume'
14791477
}]
14801478
elif snapshot:
14811479
block_device_mapping_v2 = [{
14821480
'uuid': snapshot,
1483-
'boot_index': '0',
1481+
'boot_index': 0,
14841482
'source_type': 'snapshot',
14851483
'destination_type': 'volume',
14861484
'delete_on_termination': False
@@ -1489,7 +1487,7 @@ def _match_image(image_api, wanted_properties):
14891487
# Tell nova to create a root volume from the image provided.
14901488
block_device_mapping_v2 = [{
14911489
'uuid': image.id,
1492-
'boot_index': '0',
1490+
'boot_index': 0,
14931491
'source_type': 'image',
14941492
'destination_type': 'volume',
14951493
'volume_size': parsed_args.boot_from_volume
@@ -1626,6 +1624,15 @@ def _match_image(image_api, wanted_properties):
16261624

16271625
block_device_mapping_v2.append(mapping)
16281626

1627+
if not image and not any(
1628+
[bdm.get('boot_index') == 0 for bdm in block_device_mapping_v2]
1629+
):
1630+
msg = _(
1631+
'An image (--image, --image-property) or bootable volume '
1632+
'(--volume, --snapshot, --block-device) is required'
1633+
)
1634+
raise exceptions.CommandError(msg)
1635+
16291636
nics = parsed_args.nics
16301637

16311638
if 'auto' in nics or 'none' in nics:

openstackclient/tests/unit/compute/v2/test_server.py

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2470,7 +2470,7 @@ def test_server_create_with_volume(self):
24702470
'admin_pass': None,
24712471
'block_device_mapping_v2': [{
24722472
'uuid': self.volume.id,
2473-
'boot_index': '0',
2473+
'boot_index': 0,
24742474
'source_type': 'volume',
24752475
'destination_type': 'volume',
24762476
}],
@@ -2521,7 +2521,7 @@ def test_server_create_with_snapshot(self):
25212521
'admin_pass': None,
25222522
'block_device_mapping_v2': [{
25232523
'uuid': self.snapshot.id,
2524-
'boot_index': '0',
2524+
'boot_index': 0,
25252525
'source_type': 'snapshot',
25262526
'destination_type': 'volume',
25272527
'delete_on_termination': False,
@@ -2544,20 +2544,20 @@ def test_server_create_with_snapshot(self):
25442544
self.assertEqual(self.datalist(), data)
25452545

25462546
def test_server_create_with_block_device(self):
2547-
block_device = f'uuid={self.volume.id},source_type=volume'
2547+
block_device = f'uuid={self.volume.id},source_type=volume,boot_index=0'
25482548
arglist = [
2549-
'--image', 'image1',
25502549
'--flavor', self.flavor.id,
25512550
'--block-device', block_device,
25522551
self.new_server.name,
25532552
]
25542553
verifylist = [
2555-
('image', 'image1'),
2554+
('image', None),
25562555
('flavor', self.flavor.id),
25572556
('block_devices', [
25582557
{
25592558
'uuid': self.volume.id,
25602559
'source_type': 'volume',
2560+
'boot_index': '0',
25612561
},
25622562
]),
25632563
('server_name', self.new_server.name),
@@ -2584,6 +2584,7 @@ def test_server_create_with_block_device(self):
25842584
'uuid': self.volume.id,
25852585
'source_type': 'volume',
25862586
'destination_type': 'volume',
2587+
'boot_index': 0,
25872588
},
25882589
],
25892590
'nics': [],
@@ -2593,7 +2594,7 @@ def test_server_create_with_block_device(self):
25932594
# ServerManager.create(name, image, flavor, **kwargs)
25942595
self.servers_mock.create.assert_called_with(
25952596
self.new_server.name,
2596-
self.image,
2597+
None,
25972598
self.flavor,
25982599
**kwargs
25992600
)
@@ -3521,6 +3522,37 @@ def test_server_create_image_property_with_image_list(self):
35213522
self.assertEqual(self.columns, columns)
35223523
self.assertEqual(self.datalist(), data)
35233524

3525+
def test_server_create_no_boot_device(self):
3526+
block_device = f'uuid={self.volume.id},source_type=volume,boot_index=1'
3527+
arglist = [
3528+
'--block-device', block_device,
3529+
'--flavor', self.flavor.id,
3530+
self.new_server.name,
3531+
]
3532+
verifylist = [
3533+
('image', None),
3534+
('flavor', self.flavor.id),
3535+
('block_devices', [
3536+
{
3537+
'uuid': self.volume.id,
3538+
'source_type': 'volume',
3539+
'boot_index': '1',
3540+
},
3541+
]),
3542+
('server_name', self.new_server.name),
3543+
]
3544+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
3545+
exc = self.assertRaises(
3546+
exceptions.CommandError,
3547+
self.cmd.take_action,
3548+
parsed_args,
3549+
)
3550+
self.assertIn(
3551+
'An image (--image, --image-property) or bootable volume '
3552+
'(--volume, --snapshot, --block-device) is required',
3553+
str(exc),
3554+
)
3555+
35243556
def test_server_create_with_swap(self):
35253557
arglist = [
35263558
'--image', 'image1',
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
fixes:
3+
- |
4+
The ``server create`` command will no longer insist on an ``--image``,
5+
``--image-property``, ``--volume`` or ``--snapshot`` argument when a
6+
volume is provided with a boot index of ``0`` via the ``--block-device``
7+
option.

0 commit comments

Comments
 (0)