Allow support for multipath volumes
Updates the generated iscsi url if the `target_portals` volume property is set. Change-Id: Ie9849d5dec4da50c65e2e864041e07924ae21df7
This commit is contained in:
parent
f1641468bb
commit
0354940e44
@ -861,12 +861,7 @@ def get_volume_pxe_options(task):
|
||||
return prop
|
||||
return __return_item_or_first_if_list(properties.get(key + 's', ''))
|
||||
|
||||
def __generate_iscsi_url(properties):
|
||||
"""Returns iscsi url."""
|
||||
portal = __get_property(properties, 'target_portal')
|
||||
iqn = __get_property(properties, 'target_iqn')
|
||||
lun = __get_property(properties, 'target_lun')
|
||||
|
||||
def __format_portal(portal, iqn, lun):
|
||||
if ':' in portal:
|
||||
host, port = portal.split(':')
|
||||
else:
|
||||
@ -875,6 +870,20 @@ def get_volume_pxe_options(task):
|
||||
return ("iscsi:%(host)s::%(port)s:%(lun)s:%(iqn)s" %
|
||||
{'host': host, 'port': port, 'lun': lun, 'iqn': iqn})
|
||||
|
||||
def __generate_iscsi_url(properties):
|
||||
"""Returns iscsi url."""
|
||||
iqn = __get_property(properties, 'target_iqn')
|
||||
lun = __get_property(properties, 'target_lun')
|
||||
if 'target_portals' in properties:
|
||||
portals = properties.get('target_portals')
|
||||
formatted_portals = []
|
||||
for portal in portals:
|
||||
formatted_portals.append(__format_portal(portal, iqn, lun))
|
||||
return ' '.join(formatted_portals)
|
||||
else:
|
||||
portal = __get_property(properties, 'target_portal')
|
||||
return __format_portal(portal, iqn, lun)
|
||||
|
||||
pxe_options = {}
|
||||
node = task.node
|
||||
boot_volume = node.driver_internal_info.get('boot_from_volume')
|
||||
|
@ -103,6 +103,17 @@ class TestPXEUtils(db_base.DbTestCase):
|
||||
'password': 'fake_password',
|
||||
})
|
||||
|
||||
self.ipxe_options_boot_from_volume_multipath = \
|
||||
self.ipxe_options.copy()
|
||||
self.ipxe_options_boot_from_volume_multipath.update({
|
||||
'boot_from_volume': True,
|
||||
'iscsi_boot_url': 'iscsi:fake_host::3260:0:fake_iqn '
|
||||
'iscsi:faker_host::3260:0:fake_iqn',
|
||||
'iscsi_initiator_iqn': 'fake_iqn',
|
||||
'username': 'fake_username',
|
||||
'password': 'fake_password',
|
||||
})
|
||||
|
||||
self.ipxe_options_boot_from_volume_no_extra_volume.pop(
|
||||
'initrd_filename', None)
|
||||
self.ipxe_options_boot_from_volume_extra_volume.pop(
|
||||
@ -183,6 +194,25 @@ class TestPXEUtils(db_base.DbTestCase):
|
||||
|
||||
self.assertEqual(str(expected_template), rendered_template)
|
||||
|
||||
def test_default_ipxe_boot_from_volume_config_multipath(self):
|
||||
self.config(
|
||||
pxe_config_template='ironic/drivers/modules/ipxe_config.template',
|
||||
group='pxe'
|
||||
)
|
||||
self.config(http_url='http://1.2.3.4:1234', group='deploy')
|
||||
rendered_template = utils.render_template(
|
||||
CONF.pxe.pxe_config_template,
|
||||
{'pxe_options': self.ipxe_options_boot_from_volume_multipath,
|
||||
'ROOT': '{{ ROOT }}',
|
||||
'DISK_IDENTIFIER': '{{ DISK_IDENTIFIER }}'})
|
||||
|
||||
templ_file = 'ironic/tests/unit/drivers/' \
|
||||
'ipxe_config_boot_from_volume_multipath.template'
|
||||
with open(templ_file) as f:
|
||||
expected_template = f.read().rstrip()
|
||||
|
||||
self.assertEqual(str(expected_template), rendered_template)
|
||||
|
||||
def test_default_ipxe_boot_from_volume_config(self):
|
||||
self.config(
|
||||
pxe_config_template='ironic/drivers/modules/ipxe_config.template',
|
||||
@ -1492,7 +1522,8 @@ class iPXEBuildConfigOptionsTestCase(db_base.DbTestCase):
|
||||
debug=False,
|
||||
boot_from_volume=False,
|
||||
mode='deploy',
|
||||
iso_boot=False):
|
||||
iso_boot=False,
|
||||
multipath=False):
|
||||
self.config(debug=debug)
|
||||
self.config(pxe_append_params='test_param', group='pxe')
|
||||
self.config(ipxe_timeout=ipxe_timeout, group='pxe')
|
||||
@ -1587,7 +1618,6 @@ class iPXEBuildConfigOptionsTestCase(db_base.DbTestCase):
|
||||
if boot_from_volume:
|
||||
expected_options.update({
|
||||
'boot_from_volume': True,
|
||||
'iscsi_boot_url': 'iscsi:fake_host::3260:0:fake_iqn',
|
||||
'iscsi_initiator_iqn': 'fake_iqn_initiator',
|
||||
'iscsi_volumes': [{'url': 'iscsi:fake_host::3260:1:fake_iqn',
|
||||
'username': 'fake_username_1',
|
||||
@ -1596,6 +1626,15 @@ class iPXEBuildConfigOptionsTestCase(db_base.DbTestCase):
|
||||
'username': 'fake_username',
|
||||
'password': 'fake_password'
|
||||
})
|
||||
if multipath:
|
||||
expected_options.update({
|
||||
'iscsi_boot_url': 'iscsi:fake_host::3260:0:fake_iqn '
|
||||
'iscsi:faker_host::3261:0:fake_iqn',
|
||||
})
|
||||
else:
|
||||
expected_options.update({
|
||||
'iscsi_boot_url': 'iscsi:fake_host::3260:0:fake_iqn',
|
||||
})
|
||||
expected_options.pop('deployment_aki_path')
|
||||
expected_options.pop('deployment_ari_path')
|
||||
expected_options.pop('initrd_filename')
|
||||
@ -1701,7 +1740,8 @@ class iPXEBuildConfigOptionsTestCase(db_base.DbTestCase):
|
||||
'auth_username': 'fake_username_1',
|
||||
'auth_password': 'fake_password_1'})
|
||||
self.node.driver_internal_info.update({'boot_from_volume': vol_id})
|
||||
self._test_build_pxe_config_options_ipxe(boot_from_volume=True)
|
||||
self._test_build_pxe_config_options_ipxe(boot_from_volume=True,
|
||||
multipath=True)
|
||||
|
||||
def test_get_volume_pxe_options(self):
|
||||
vol_id = uuidutils.generate_uuid()
|
||||
|
@ -0,0 +1,56 @@
|
||||
#!ipxe
|
||||
|
||||
set attempts:int32 10
|
||||
set i:int32 0
|
||||
|
||||
goto deploy
|
||||
|
||||
:deploy
|
||||
imgfree
|
||||
kernel http://1.2.3.4:1234/deploy_kernel selinux=0 troubleshoot=0 text test_param BOOTIF=${mac} initrd=deploy_ramdisk || goto retry
|
||||
|
||||
initrd http://1.2.3.4:1234/deploy_ramdisk || goto retry
|
||||
boot
|
||||
|
||||
:retry
|
||||
iseq ${i} ${attempts} && goto fail ||
|
||||
inc i
|
||||
echo No response, retrying in ${i} seconds.
|
||||
sleep ${i}
|
||||
goto deploy
|
||||
|
||||
:fail
|
||||
echo Failed to get a response after ${attempts} attempts
|
||||
echo Powering off in 30 seconds.
|
||||
sleep 30
|
||||
poweroff
|
||||
|
||||
:boot_partition
|
||||
imgfree
|
||||
kernel http://1.2.3.4:1234/kernel root={{ ROOT }} ro text test_param initrd=ramdisk || goto boot_partition
|
||||
initrd http://1.2.3.4:1234/ramdisk || goto boot_partition
|
||||
boot
|
||||
|
||||
:boot_ramdisk
|
||||
imgfree
|
||||
kernel http://1.2.3.4:1234/kernel root=/dev/ram0 text test_param ramdisk_param initrd=ramdisk || goto boot_ramdisk
|
||||
initrd http://1.2.3.4:1234/ramdisk || goto boot_ramdisk
|
||||
boot
|
||||
|
||||
:boot_iscsi
|
||||
imgfree
|
||||
set username fake_username
|
||||
set password fake_password
|
||||
set initiator-iqn fake_iqn
|
||||
sanhook --drive 0x80 iscsi:fake_host::3260:0:fake_iqn iscsi:faker_host::3260:0:fake_iqn || goto fail_iscsi_retry
|
||||
|
||||
|
||||
sanboot --no-describe || goto fail_iscsi_retry
|
||||
|
||||
:fail_iscsi_retry
|
||||
echo Failed to attach iSCSI volume(s), retrying in 10 seconds.
|
||||
sleep 10
|
||||
goto boot_iscsi
|
||||
|
||||
:boot_whole_disk
|
||||
sanboot --no-describe
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Adds support for multipath volumes. If the volume properties have
|
||||
multiple portals, then it will generate multiple iscsi urls and
|
||||
append them together for use in the generated ipxe file.
|
||||
|
Loading…
Reference in New Issue
Block a user