Skip to content

Commit 8652d71

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Fixes KeyError: 'sr_uuid' when booting from volume on xenapi"
2 parents 2e44437 + 503d572 commit 8652d71

File tree

4 files changed

+76
-81
lines changed

4 files changed

+76
-81
lines changed

nova/tests/xenapi/test_vm_utils.py

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,29 @@
1010
from nova.virt.xenapi import volume_utils
1111

1212

13+
XENSM_TYPE = 'xensm'
14+
ISCSI_TYPE = 'iscsi'
15+
16+
17+
def get_fake_dev_params(sr_type):
18+
fakes = {XENSM_TYPE: {'sr_uuid': 'falseSR',
19+
'name_label': 'fake_storage',
20+
'name_description': 'test purposes',
21+
'server': 'myserver',
22+
'serverpath': '/local/scratch/myname',
23+
'sr_type': 'nfs',
24+
'introduce_sr_keys': ['server',
25+
'serverpath',
26+
'sr_type'],
27+
'vdi_uuid': 'falseVDI'},
28+
ISCSI_TYPE: {'volume_id': 'fake_volume_id',
29+
'target_lun': 1,
30+
'target_iqn': 'fake_iqn:volume-fake_volume_id',
31+
'target_portal': u'localhost:3260',
32+
'target_discovered': False}, }
33+
return fakes[sr_type]
34+
35+
1336
class GetInstanceForVdisForSrTestCase(stubs.XenAPITestBase):
1437
def setUp(self):
1538
super(GetInstanceForVdisForSrTestCase, self).setUp()
@@ -50,15 +73,8 @@ def test_get_instance_vdis_for_sr_no_vbd(self):
5073

5174
self.assertEquals([], result)
5275

53-
def test_get_vdis_for_boot_from_vol(self):
54-
dev_params = {'sr_uuid': 'falseSR',
55-
'name_label': 'fake_storage',
56-
'name_description': 'test purposes',
57-
'server': 'myserver',
58-
'serverpath': '/local/scratch/myname',
59-
'sr_type': 'nfs',
60-
'introduce_sr_keys': ['server', 'serverpath', 'sr_type'],
61-
'vdi_uuid': 'falseVDI'}
76+
def test_get_vdis_for_boot_from_vol_with_sr_uuid(self):
77+
dev_params = get_fake_dev_params(XENSM_TYPE)
6278
stubs.stubout_session(self.stubs, fake.SessionBase)
6379
driver = xenapi_conn.XenAPIDriver(False)
6480

@@ -74,18 +90,20 @@ def bad_introduce_sr(session, sr_uuid, label, sr_params):
7490
return None
7591

7692
self.stubs.Set(volume_utils, 'introduce_sr', bad_introduce_sr)
77-
dev_params = {'sr_uuid': 'falseSR',
78-
'name_label': 'fake_storage',
79-
'name_description': 'test purposes',
80-
'server': 'myserver',
81-
'serverpath': '/local/scratch/myname',
82-
'sr_type': 'nfs',
83-
'introduce_sr_keys': ['server', 'serverpath', 'sr_type'],
84-
'vdi_uuid': 'falseVDI'}
93+
dev_params = get_fake_dev_params(XENSM_TYPE)
8594
self.assertRaises(exception.NovaException,
8695
vm_utils.get_vdis_for_boot_from_vol,
8796
driver._session, dev_params)
8897

98+
def test_get_vdis_for_boot_from_iscsi_vol_missing_sr_uuid(self):
99+
dev_params = get_fake_dev_params(ISCSI_TYPE)
100+
stubs.stubout_session(self.stubs, fake.SessionBase)
101+
driver = xenapi_conn.XenAPIDriver(False)
102+
103+
result = vm_utils.get_vdis_for_boot_from_vol(driver._session,
104+
dev_params)
105+
self.assertNotEquals(result['root']['uuid'], None)
106+
89107

90108
class VMRefOrRaiseVMFoundTestCase(test.TestCase):
91109

nova/virt/xenapi/vm_utils.py

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -462,35 +462,29 @@ def create_vdi(session, sr_ref, instance, name_label, disk_type, virtual_size,
462462

463463
def get_vdis_for_boot_from_vol(session, dev_params):
464464
vdis = {}
465-
sr_uuid = dev_params['sr_uuid']
466-
sr_ref = volume_utils.find_sr_by_uuid(session,
467-
sr_uuid)
465+
sr_uuid, label, sr_params = volume_utils.parse_sr_info(dev_params)
466+
sr_ref = volume_utils.find_sr_by_uuid(session, sr_uuid)
468467
# Try introducing SR if it is not present
469468
if not sr_ref:
470-
if 'name_label' not in dev_params:
471-
label = 'tempSR-%s' % dev_params['volume_id']
472-
else:
473-
label = dev_params['name_label']
474-
475-
if 'name_description' not in dev_params:
476-
desc = ''
477-
else:
478-
desc = dev_params.get('name_description')
479-
sr_params = {}
480-
for k in dev_params['introduce_sr_keys']:
481-
sr_params[k] = dev_params[k]
482-
483-
sr_params['name_description'] = desc
484-
sr_ref = volume_utils.introduce_sr(session, sr_uuid, label,
485-
sr_params)
469+
sr_ref = volume_utils.introduce_sr(session, sr_uuid, label, sr_params)
486470

487471
if sr_ref is None:
488472
raise exception.NovaException(_('SR not present and could not be '
489473
'introduced'))
490474
else:
491-
session.call_xenapi("SR.scan", sr_ref)
492-
return {'root': dict(uuid=dev_params['vdi_uuid'],
493-
file=None, osvol=True)}
475+
if 'vdi_uuid' in dev_params:
476+
session.call_xenapi("SR.scan", sr_ref)
477+
vdis = {'root': dict(uuid=dev_params['vdi_uuid'],
478+
file=None, osvol=True)}
479+
else:
480+
try:
481+
vdi_ref = volume_utils.introduce_vdi(session, sr_ref)
482+
vdi_rec = session.call_xenapi("VDI.get_record", vdi_ref)
483+
vdis = {'root': dict(uuid=vdi_rec['uuid'],
484+
file=None, osvol=True)}
485+
except volume_utils.StorageError, exc:
486+
LOG.exception(exc)
487+
volume_utils.forget_sr(session, sr_uuid)
494488
return vdis
495489

496490

@@ -523,8 +517,7 @@ def get_vdis_for_instance(context, session, instance, name_label, image,
523517
bdm_root_dev = block_device_info['block_device_mapping'][0]
524518
dev_params = bdm_root_dev['connection_info']['data']
525519
LOG.debug(dev_params)
526-
return get_vdis_for_boot_from_vol(session,
527-
dev_params)
520+
return get_vdis_for_boot_from_vol(session, dev_params)
528521
return _create_image(context, session, instance, name_label, image,
529522
image_type)
530523

nova/virt/xenapi/volume_utils.py

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ def create_sr(session, label, params):
6767

6868
def introduce_sr(session, sr_uuid, label, params):
6969
LOG.debug(_("introducing sr within volume_utils"))
70-
type = params['sr_type']
71-
del params['sr_type']
70+
# If the sr_type is missing, we assume we are
71+
# using the default iscsi back-end
72+
type = params.pop('sr_type', 'iscsi')
7273
LOG.debug(_('type is = %s') % type)
7374
if 'name_description' in params:
7475
desc = params['name_description']
@@ -283,18 +284,29 @@ def get_device_number(mountpoint):
283284
return device_number
284285

285286

287+
def parse_sr_info(connection_data, description=''):
288+
label = connection_data.pop('name_label',
289+
'tempSR-%s' % connection_data.get('volume_id'))
290+
params = {}
291+
if 'sr_uuid' not in connection_data:
292+
params = parse_volume_info(connection_data)
293+
# This magic label sounds a lot like 'False Disc' in leet-speak
294+
uuid = "FA15E-D15C-" + str(params['id'])
295+
else:
296+
uuid = connection_data['sr_uuid']
297+
for k in connection_data.get('introduce_sr_keys', {}):
298+
params[k] = connection_data[k]
299+
params['name_description'] = connection_data.get('name_description',
300+
description)
301+
302+
return (uuid, label, params)
303+
304+
286305
def parse_volume_info(connection_data):
287306
"""
288307
Parse device_path and mountpoint as they can be used by XenAPI.
289308
In particular, the mountpoint (e.g. /dev/sdc) must be translated
290309
into a numeric literal.
291-
FIXME(armando):
292-
As for device_path, currently cannot be used as it is,
293-
because it does not contain target information. As for interim
294-
solution, target details are passed either via Flags or obtained
295-
by iscsiadm. Long-term solution is to add a few more fields to the
296-
db in the iscsi_target table with the necessary info and modify
297-
the iscsi driver to set them.
298310
"""
299311
volume_id = connection_data['volume_id']
300312
target_portal = connection_data['target_portal']
@@ -369,12 +381,3 @@ def _get_target_port(iscsi_string):
369381
return iscsi_string[iscsi_string.find(':') + 1:]
370382
elif iscsi_string is None or CONF.target_port:
371383
return CONF.target_port
372-
373-
374-
def _get_iqn(iscsi_string, id):
375-
"""Retrieve target IQN"""
376-
if iscsi_string:
377-
return iscsi_string
378-
elif iscsi_string is None or CONF.iqn_prefix:
379-
volume_id = _get_volume_id(id)
380-
return '%s:%s' % (CONF.iqn_prefix, volume_id)

nova/virt/xenapi/volumeops.py

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -130,28 +130,9 @@ def attach_volume(self, connection_info, instance_name, mountpoint):
130130
def connect_volume(self, connection_data, dev_number, instance_name,
131131
vm_ref):
132132

133-
if 'name_label' not in connection_data:
134-
label = 'tempSR-%s' % connection_data['volume_id']
135-
else:
136-
label = connection_data['name_label']
137-
del connection_data['name_label']
138-
139-
if 'name_description' not in connection_data:
140-
desc = 'Disk-for:%s' % instance_name
141-
else:
142-
desc = connection_data['name_description']
143-
144-
sr_params = {}
145-
if u'sr_uuid' not in connection_data:
146-
sr_params = volume_utils.parse_volume_info(connection_data)
147-
uuid = "FA15E-D15C-" + str(sr_params['id'])
148-
sr_params['sr_type'] = 'iscsi'
149-
else:
150-
uuid = connection_data['sr_uuid']
151-
for k in connection_data['introduce_sr_keys']:
152-
sr_params[k] = connection_data[k]
153-
154-
sr_params['name_description'] = desc
133+
description = 'Disk-for:%s' % instance_name
134+
uuid, label, sr_params = volume_utils.parse_sr_info(connection_data,
135+
description)
155136

156137
# Introduce SR
157138
try:

0 commit comments

Comments
 (0)