Enable PXE for systems using petitboot
Petitboot systems do not use the pxelinux.0 loader. Instead, petitboot itself handles pxelinux functionality. A side effect of this is that petitboot requires DHCP option 210 (tftp path-prefix) as this information is normally derived from the boot file name. This patch uses the value of tftp_root as a path prefix and makes the PXE module honor that prefix. Change-Id: Ib9e954feea2cec38dd8328ada35005c0311c2a1b Closes-Bug: #1639187 Co-Authored-By: Michael Turek <mjturek@linux.vnet.ibm.com>
This commit is contained in:
parent
9eb148ad37
commit
f13959c031
@ -319,6 +319,12 @@ def dhcp_options_for_instance(task):
|
||||
else:
|
||||
dhcp_opts.append({'opt_name': 'bootfile-name',
|
||||
'opt_value': boot_file})
|
||||
# 210 == tftp server path-prefix or tftp root, will be used to find
|
||||
# pxelinux.cfg directory. The pxelinux.0 loader infers this information
|
||||
# from it's own path, but Petitboot needs it to be specified by this
|
||||
# option since it doesn't use pxelinux.0 loader.
|
||||
dhcp_opts.append({'opt_name': '210',
|
||||
'opt_value': get_tftp_path_prefix()})
|
||||
|
||||
dhcp_opts.append({'opt_name': 'server-ip-address',
|
||||
'opt_value': CONF.pxe.tftp_server})
|
||||
@ -330,3 +336,20 @@ def dhcp_options_for_instance(task):
|
||||
opt.update({'ip_version': int(CONF.pxe.ip_version)})
|
||||
|
||||
return dhcp_opts
|
||||
|
||||
|
||||
def get_tftp_path_prefix():
|
||||
"""Adds trailing slash (if needed) necessary for path-prefix
|
||||
|
||||
:return: CONF.pxe.tftp_root ensured to have a trailing slash
|
||||
"""
|
||||
return os.path.join(CONF.pxe.tftp_root, '')
|
||||
|
||||
|
||||
def get_path_relative_to_tftp_root(file_path):
|
||||
"""Return file relative path to CONF.pxe.tftp_root
|
||||
|
||||
:param file_path: full file path to be made relative path.
|
||||
:returns: The path relative to CONF.pxe.tftp_root
|
||||
"""
|
||||
return os.path.relpath(file_path, get_tftp_path_prefix())
|
||||
|
@ -132,16 +132,21 @@ def _get_deploy_image_info(node):
|
||||
|
||||
def _get_pxe_kernel_ramdisk(pxe_info):
|
||||
pxe_opts = {}
|
||||
pxe_opts['deployment_aki_path'] = pxe_info['deploy_kernel'][1]
|
||||
pxe_opts['deployment_ari_path'] = pxe_info['deploy_ramdisk'][1]
|
||||
pxe_opts['deployment_aki_path'] = pxe_utils.get_path_relative_to_tftp_root(
|
||||
pxe_info['deploy_kernel'][1])
|
||||
pxe_opts['deployment_ari_path'] = pxe_utils.get_path_relative_to_tftp_root(
|
||||
pxe_info['deploy_ramdisk'][1])
|
||||
# It is possible that we don't have kernel/ramdisk or even
|
||||
# image_source to determine if it's a whole disk image or not.
|
||||
# For example, when transitioning to 'available' state for first
|
||||
# time from 'manage' state.
|
||||
if 'kernel' in pxe_info:
|
||||
pxe_opts['aki_path'] = pxe_info['kernel'][1]
|
||||
pxe_opts['aki_path'] = pxe_utils.get_path_relative_to_tftp_root(
|
||||
pxe_info['kernel'][1])
|
||||
if 'ramdisk' in pxe_info:
|
||||
pxe_opts['ari_path'] = pxe_info['ramdisk'][1]
|
||||
pxe_opts['ari_path'] = pxe_utils.get_path_relative_to_tftp_root(
|
||||
pxe_info['ramdisk'][1])
|
||||
|
||||
return pxe_opts
|
||||
|
||||
|
||||
|
@ -424,9 +424,13 @@ class TestPXEUtils(db_base.DbTestCase):
|
||||
self.config(ip_version=ip_version, group='pxe')
|
||||
self.config(tftp_server='192.0.2.1', group='pxe')
|
||||
self.config(pxe_bootfile_name='fake-bootfile', group='pxe')
|
||||
self.config(tftp_root='/tftp-path/', group='pxe')
|
||||
expected_info = [{'opt_name': 'bootfile-name',
|
||||
'opt_value': 'fake-bootfile',
|
||||
'ip_version': ip_version},
|
||||
{'opt_name': '210',
|
||||
'opt_value': '/tftp-path/',
|
||||
'ip_version': ip_version},
|
||||
{'opt_name': 'server-ip-address',
|
||||
'opt_value': '192.0.2.1',
|
||||
'ip_version': ip_version},
|
||||
@ -603,3 +607,25 @@ class TestPXEUtils(db_base.DbTestCase):
|
||||
'/httpboot/pxelinux.cfg/aa-aa-aa-aa-aa-aa')
|
||||
rmtree_mock.assert_called_once_with(
|
||||
os.path.join(CONF.deploy.http_root, self.node.uuid))
|
||||
|
||||
def test_get_tftp_path_prefix_with_trailing_slash(self):
|
||||
self.config(tftp_root='/tftpboot-path/', group='pxe')
|
||||
path_prefix = pxe_utils.get_tftp_path_prefix()
|
||||
self.assertEqual(path_prefix, '/tftpboot-path/')
|
||||
|
||||
def test_get_tftp_path_prefix_without_trailing_slash(self):
|
||||
self.config(tftp_root='/tftpboot-path', group='pxe')
|
||||
path_prefix = pxe_utils.get_tftp_path_prefix()
|
||||
self.assertEqual(path_prefix, '/tftpboot-path/')
|
||||
|
||||
def test_get_path_relative_to_tftp_root_with_trailing_slash(self):
|
||||
self.config(tftp_root='/tftpboot-path/', group='pxe')
|
||||
test_file_path = '/tftpboot-path/pxelinux.cfg/test'
|
||||
relpath = pxe_utils.get_path_relative_to_tftp_root(test_file_path)
|
||||
self.assertEqual(relpath, 'pxelinux.cfg/test')
|
||||
|
||||
def test_get_path_relative_to_tftp_root_without_trailing_slash(self):
|
||||
self.config(tftp_root='/tftpboot-path', group='pxe')
|
||||
test_file_path = '/tftpboot-path/pxelinux.cfg/test'
|
||||
relpath = pxe_utils.get_path_relative_to_tftp_root(test_file_path)
|
||||
self.assertEqual(relpath, 'pxelinux.cfg/test')
|
||||
|
@ -178,14 +178,10 @@ class PXEPrivateMethodsTestCase(db_base.DbTestCase):
|
||||
|
||||
tftp_server = CONF.pxe.tftp_server
|
||||
|
||||
deploy_kernel = os.path.join(CONF.pxe.tftp_root, self.node.uuid,
|
||||
'deploy_kernel')
|
||||
deploy_ramdisk = os.path.join(CONF.pxe.tftp_root, self.node.uuid,
|
||||
'deploy_ramdisk')
|
||||
kernel = os.path.join(CONF.pxe.tftp_root, self.node.uuid,
|
||||
'kernel')
|
||||
ramdisk = os.path.join(CONF.pxe.tftp_root, self.node.uuid,
|
||||
'ramdisk')
|
||||
deploy_kernel = os.path.join(self.node.uuid, 'deploy_kernel')
|
||||
deploy_ramdisk = os.path.join(self.node.uuid, 'deploy_ramdisk')
|
||||
kernel = os.path.join(self.node.uuid, 'kernel')
|
||||
ramdisk = os.path.join(self.node.uuid, 'ramdisk')
|
||||
root_dir = CONF.pxe.tftp_root
|
||||
|
||||
image_info = {
|
||||
@ -251,11 +247,14 @@ class PXEPrivateMethodsTestCase(db_base.DbTestCase):
|
||||
self.node.save()
|
||||
self.config(group='pxe', tftp_server='my-tftp-server')
|
||||
self.config(group='pxe', pxe_append_params='my-pxe-append-params')
|
||||
self.config(group='pxe', tftp_root='/tftp-path/')
|
||||
image_info = {
|
||||
'deploy_kernel': ('deploy_kernel',
|
||||
'path-to-deploy_kernel'),
|
||||
os.path.join(CONF.pxe.tftp_root,
|
||||
'path-to-deploy_kernel')),
|
||||
'deploy_ramdisk': ('deploy_ramdisk',
|
||||
'path-to-deploy_ramdisk')}
|
||||
os.path.join(CONF.pxe.tftp_root,
|
||||
'path-to-deploy_ramdisk'))}
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=True) as task:
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- Adds the use of DHCP option 210 (tftp-path-prefix). This
|
||||
enables PXE for systems using petitboot, which cannot
|
||||
infer their tftp-path-prefix from the boot file location
|
||||
as petitboot does not use a boot file.
|
Loading…
Reference in New Issue
Block a user