Skip to content

Commit 8b23c26

Browse files
committed
Split the vol_id from a dev mapping
Add a split into the dev mapping to get the right vol_id. Change-Id: I1a7bf6351491b1321c5ca0fa4a27f29825400eaf Closes-Bug: #1514394
1 parent 6611f37 commit 8b23c26

3 files changed

Lines changed: 94 additions & 4 deletions

File tree

openstackclient/compute/v2/server.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,17 @@ def take_action(self, parsed_args):
425425
dev_key, dev_vol = dev_map.split('=', 1)
426426
block_volume = None
427427
if dev_vol:
428-
block_volume = utils.find_resource(
429-
volume_client.volumes,
430-
dev_vol,
431-
).id
428+
vol = dev_vol.split(':', 1)[0]
429+
if vol:
430+
vol_id = utils.find_resource(
431+
volume_client.volumes,
432+
vol,
433+
).id
434+
block_volume = dev_vol.replace(vol, vol_id)
435+
else:
436+
msg = _("Volume name or ID must be specified if "
437+
"--block-device-mapping is specified")
438+
raise exceptions.CommandError(msg)
432439
block_device_mapping.update({dev_key: block_volume})
433440

434441
nics = []

openstackclient/tests/compute/v2/fakes.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from openstackclient.tests.image.v2 import fakes as image_fakes
2121
from openstackclient.tests.network.v2 import fakes as network_fakes
2222
from openstackclient.tests import utils
23+
from openstackclient.tests.volume.v2 import fakes as volume_fakes
2324

2425

2526
server_id = 'serv1'
@@ -80,6 +81,8 @@
8081
QUOTA_columns = tuple(sorted(QUOTA))
8182
QUOTA_data = tuple(QUOTA[x] for x in sorted(QUOTA))
8283

84+
block_device_mapping = 'vda=' + volume_fakes.volume_name + ':::0'
85+
8386

8487
class FakeComputev2Client(object):
8588
def __init__(self, **kwargs):
@@ -95,6 +98,8 @@ def __init__(self, **kwargs):
9598
self.flavors.resource_class = fakes.FakeResource(None, {})
9699
self.quotas = mock.Mock()
97100
self.quotas.resource_class = fakes.FakeResource(None, {})
101+
self.volumes = mock.Mock()
102+
self.volumes.resource_class = fakes.FakeResource(None, {})
98103
self.auth_token = kwargs['token']
99104
self.management_url = kwargs['endpoint']
100105

@@ -122,3 +127,8 @@ def setUp(self):
122127
endpoint=fakes.AUTH_URL,
123128
token=fakes.AUTH_TOKEN,
124129
)
130+
131+
self.app.client_manager.volume = volume_fakes.FakeVolumeClient(
132+
endpoint=fakes.AUTH_URL,
133+
token=fakes.AUTH_TOKEN,
134+
)

openstackclient/tests/compute/v2/test_server.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from openstackclient.tests import fakes
2525
from openstackclient.tests.image.v2 import fakes as image_fakes
2626
from openstackclient.tests import utils
27+
from openstackclient.tests.volume.v2 import fakes as volume_fakes
2728

2829

2930
class TestServer(compute_fakes.TestComputev2):
@@ -47,6 +48,10 @@ def setUp(self):
4748
self.images_mock = self.app.client_manager.image.images
4849
self.images_mock.reset_mock()
4950

51+
# Get a shortcut to the VolumeManager Mock
52+
self.volumes_mock = self.app.client_manager.volume.volumes
53+
self.volumes_mock.reset_mock()
54+
5055

5156
class TestServerCreate(TestServer):
5257

@@ -80,6 +85,13 @@ def setUp(self):
8085
)
8186
self.flavors_mock.get.return_value = self.flavor
8287

88+
self.volume = fakes.FakeResource(
89+
None,
90+
copy.deepcopy(volume_fakes.VOLUME),
91+
loaded=True,
92+
)
93+
self.volumes_mock.get.return_value = self.volume
94+
8395
# Get the command object to test
8496
self.cmd = server.CreateServer(self.app, None)
8597

@@ -289,6 +301,67 @@ def test_server_create_userdata(self, mock_open):
289301
)
290302
self.assertEqual(datalist, data)
291303

304+
def test_server_create_with_block_device_mapping(self):
305+
arglist = [
306+
'--image', 'image1',
307+
'--flavor', compute_fakes.flavor_id,
308+
'--block-device-mapping', compute_fakes.block_device_mapping,
309+
compute_fakes.server_name,
310+
]
311+
verifylist = [
312+
('image', 'image1'),
313+
('flavor', compute_fakes.flavor_id),
314+
('block_device_mapping', [compute_fakes.block_device_mapping]),
315+
('config_drive', False),
316+
('server_name', compute_fakes.server_name),
317+
]
318+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
319+
320+
# CreateServer.take_action() returns two tuples
321+
columns, data = self.cmd.take_action(parsed_args)
322+
323+
real_volume_mapping = (
324+
(compute_fakes.block_device_mapping.split('=', 1)[1]).replace(
325+
volume_fakes.volume_name,
326+
volume_fakes.volume_id))
327+
328+
# Set expected values
329+
kwargs = dict(
330+
meta=None,
331+
files={},
332+
reservation_id=None,
333+
min_count=1,
334+
max_count=1,
335+
security_groups=[],
336+
userdata=None,
337+
key_name=None,
338+
availability_zone=None,
339+
block_device_mapping={
340+
'vda': real_volume_mapping
341+
},
342+
nics=[],
343+
scheduler_hints={},
344+
config_drive=None,
345+
)
346+
# ServerManager.create(name, image, flavor, **kwargs)
347+
self.servers_mock.create.assert_called_with(
348+
compute_fakes.server_name,
349+
self.image,
350+
self.flavor,
351+
**kwargs
352+
)
353+
354+
collist = ('addresses', 'flavor', 'id', 'name', 'properties')
355+
self.assertEqual(collist, columns)
356+
datalist = (
357+
'',
358+
'Large ()',
359+
compute_fakes.server_id,
360+
compute_fakes.server_name,
361+
'',
362+
)
363+
self.assertEqual(datalist, data)
364+
292365

293366
class TestServerDelete(TestServer):
294367

0 commit comments

Comments
 (0)