Merge "Validate OS::Nova::Server block_device_mapping property"
This commit is contained in:
commit
6370a8790e
|
@ -360,14 +360,30 @@ class Server(resource.Resource):
|
|||
if key_name:
|
||||
nova_utils.get_keypair(self.nova(), key_name)
|
||||
|
||||
# either volume_id or snapshot_id needs to be specified, but not both
|
||||
# for block device mapping.
|
||||
bdm = self.properties.get('block_device_mapping') or []
|
||||
bootable_vol = False
|
||||
for mapping in bdm:
|
||||
if mapping['device_name'] is 'vda':
|
||||
bootable_vol = True
|
||||
|
||||
if mapping.get('volume_id') and mapping.get('snapshot_id'):
|
||||
raise exception.ResourcePropertyConflict('volume_id',
|
||||
'snapshot_id')
|
||||
if not mapping.get('volume_id') and not mapping.get('snapshot_id'):
|
||||
msg = _('Either volume_id or snapshot_id must be specified for'
|
||||
' device mapping %s') % mapping['device_name']
|
||||
raise exception.StackValidationFailed(message=msg)
|
||||
|
||||
# make sure the image exists if specified.
|
||||
image = self.properties.get('image', None)
|
||||
if image:
|
||||
nova_utils.get_image_id(self.nova(), image)
|
||||
else:
|
||||
# TODO(sbaker) confirm block_device_mapping is populated
|
||||
# for boot-by-volume (see LP bug #1215267)
|
||||
pass
|
||||
elif not image and not bootable_vol:
|
||||
msg = _('Neither image nor bootable volume is specified for'
|
||||
' instance %s') % self.name
|
||||
raise exception.StackValidationFailed(message=msg)
|
||||
|
||||
def handle_delete(self):
|
||||
'''
|
||||
|
|
|
@ -799,3 +799,61 @@ class ServersTest(HeatTestCase):
|
|||
'delete_on_termination': True
|
||||
}
|
||||
]))
|
||||
|
||||
def test_validate_conflict_block_device_mapping_props(self):
|
||||
stack_name = 'test_validate_conflict_block_device_mapping_props'
|
||||
(t, stack) = self._setup_test_stack(stack_name)
|
||||
|
||||
bdm = [{'device_name': 'vdb', 'snapshot_id': '1234',
|
||||
'volume_id': '1234'}]
|
||||
t['Resources']['WebServer']['Properties']['block_device_mapping'] = bdm
|
||||
server = servers.Server('server_create_image_err',
|
||||
t['Resources']['WebServer'], stack)
|
||||
self.m.StubOutWithMock(server, 'nova')
|
||||
server.nova().MultipleTimes().AndReturn(self.fc)
|
||||
self.m.ReplayAll()
|
||||
|
||||
self.assertRaises(exception.ResourcePropertyConflict, server.validate)
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_validate_insufficient_block_device_mapping_props(self):
|
||||
stack_name = 'test_validate_insufficient_block_device_mapping_props'
|
||||
(t, stack) = self._setup_test_stack(stack_name)
|
||||
|
||||
bdm = [{'device_name': 'vdb', 'volume_size': '1',
|
||||
'delete_on_termination': True}]
|
||||
t['Resources']['WebServer']['Properties']['block_device_mapping'] = bdm
|
||||
server = servers.Server('server_create_image_err',
|
||||
t['Resources']['WebServer'], stack)
|
||||
self.m.StubOutWithMock(server, 'nova')
|
||||
server.nova().MultipleTimes().AndReturn(self.fc)
|
||||
self.m.ReplayAll()
|
||||
|
||||
ex = self.assertRaises(exception.StackValidationFailed,
|
||||
server.validate)
|
||||
msg = 'Either volume_id or snapshot_id must be specified for device' +\
|
||||
' mapping vdb'
|
||||
self.assertEqual(msg, str(ex))
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_validate_without_image_or_bootable_volume(self):
|
||||
stack_name = 'test_validate_without_image_or_bootable_volume'
|
||||
(t, stack) = self._setup_test_stack(stack_name)
|
||||
|
||||
del t['Resources']['WebServer']['Properties']['image']
|
||||
bdm = [{'device_name': 'vdb', 'volume_id': '1234'}]
|
||||
t['Resources']['WebServer']['Properties']['block_device_mapping'] = bdm
|
||||
server = servers.Server('server_create_image_err',
|
||||
t['Resources']['WebServer'], stack)
|
||||
self.m.StubOutWithMock(server, 'nova')
|
||||
server.nova().MultipleTimes().AndReturn(self.fc)
|
||||
self.m.ReplayAll()
|
||||
|
||||
ex = self.assertRaises(exception.StackValidationFailed,
|
||||
server.validate)
|
||||
msg = 'Neither image nor bootable volume is specified for instance %s'\
|
||||
% server.name
|
||||
self.assertEqual(msg, str(ex))
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
|
Loading…
Reference in New Issue