Remove elilo support
Story: #1691454 Task: #9754 Change-Id: I087c8172b67e83b36344c30cf52812645148d9e4
This commit is contained in:
parent
73845b3655
commit
0f6639d4eb
@ -120,12 +120,10 @@ def _link_mac_pxe_configs(task, ipxe_enabled=False):
|
|||||||
create_link(_get_pxe_grub_mac_path(port.address))
|
create_link(_get_pxe_grub_mac_path(port.address))
|
||||||
|
|
||||||
|
|
||||||
def _link_ip_address_pxe_configs(task, hex_form, ipxe_enabled=False):
|
def _link_ip_address_pxe_configs(task, ipxe_enabled=False):
|
||||||
"""Link each IP address with the PXE configuration file.
|
"""Link each IP address with the PXE configuration file.
|
||||||
|
|
||||||
:param task: A TaskManager instance.
|
:param task: A TaskManager instance.
|
||||||
:param hex_form: Boolean value indicating if the conf file name should be
|
|
||||||
hexadecimal equivalent of supplied ipv4 address.
|
|
||||||
:param ipxe_enabled: Default false boolean to indicate if ipxe
|
:param ipxe_enabled: Default false boolean to indicate if ipxe
|
||||||
is in use by the caller.
|
is in use by the caller.
|
||||||
:raises: FailedToGetIPAddressOnPort
|
:raises: FailedToGetIPAddressOnPort
|
||||||
@ -143,8 +141,7 @@ def _link_ip_address_pxe_configs(task, hex_form, ipxe_enabled=False):
|
|||||||
"Failed to get IP address for any port on node %s.") %
|
"Failed to get IP address for any port on node %s.") %
|
||||||
task.node.uuid)
|
task.node.uuid)
|
||||||
for port_ip_address in ip_addrs:
|
for port_ip_address in ip_addrs:
|
||||||
ip_address_path = _get_pxe_ip_address_path(port_ip_address,
|
ip_address_path = _get_pxe_ip_address_path(port_ip_address)
|
||||||
hex_form)
|
|
||||||
ironic_utils.unlink_without_raise(ip_address_path)
|
ironic_utils.unlink_without_raise(ip_address_path)
|
||||||
relative_source_path = os.path.relpath(
|
relative_source_path = os.path.relpath(
|
||||||
pxe_config_file_path, os.path.dirname(ip_address_path))
|
pxe_config_file_path, os.path.dirname(ip_address_path))
|
||||||
@ -181,22 +178,13 @@ def _get_pxe_mac_path(mac, delimiter='-', client_id=None,
|
|||||||
mac_file_name)
|
mac_file_name)
|
||||||
|
|
||||||
|
|
||||||
def _get_pxe_ip_address_path(ip_address, hex_form):
|
def _get_pxe_ip_address_path(ip_address):
|
||||||
"""Convert an ipv4 address into a PXE config file name.
|
"""Convert an ipv4 address into a PXE config file name.
|
||||||
|
|
||||||
:param ip_address: A valid IPv4 address string in the format 'n.n.n.n'.
|
:param ip_address: A valid IPv4 address string in the format 'n.n.n.n'.
|
||||||
:param hex_form: Boolean value indicating if the conf file name should be
|
|
||||||
hexadecimal equivalent of supplied ipv4 address.
|
|
||||||
:returns: the path to the config file.
|
:returns: the path to the config file.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# NOTE(TheJulia): Remove elilo support after the deprecation
|
|
||||||
# period, in the Queens release.
|
|
||||||
# elilo bootloader needs hex based config file name.
|
|
||||||
if hex_form:
|
|
||||||
ip = ip_address.split('.')
|
|
||||||
ip_address = '{0:02X}{1:02X}{2:02X}{3:02X}'.format(*map(int, ip))
|
|
||||||
|
|
||||||
# grub2 bootloader needs ip based config file name.
|
# grub2 bootloader needs ip based config file name.
|
||||||
return os.path.join(
|
return os.path.join(
|
||||||
CONF.pxe.tftp_root, ip_address + ".conf"
|
CONF.pxe.tftp_root, ip_address + ".conf"
|
||||||
@ -259,8 +247,6 @@ def create_pxe_config(task, pxe_options, template=None, ipxe_enabled=False):
|
|||||||
the configuration file will be created under the PXE configuration
|
the configuration file will be created under the PXE configuration
|
||||||
directory, so regardless of which port boots first they'll get the
|
directory, so regardless of which port boots first they'll get the
|
||||||
same PXE configuration.
|
same PXE configuration.
|
||||||
If elilo is the bootloader in use, then its configuration file will
|
|
||||||
be created based on hex form of DHCP IP address.
|
|
||||||
If grub2 bootloader is in use, then its configuration will be created
|
If grub2 bootloader is in use, then its configuration will be created
|
||||||
based on DHCP IP address in the form nn.nn.nn.nn.
|
based on DHCP IP address in the form nn.nn.nn.nn.
|
||||||
|
|
||||||
@ -282,20 +268,14 @@ def create_pxe_config(task, pxe_options, template=None, ipxe_enabled=False):
|
|||||||
ipxe_enabled=ipxe_enabled)
|
ipxe_enabled=ipxe_enabled)
|
||||||
is_uefi_boot_mode = (boot_mode_utils.get_boot_mode(task.node)
|
is_uefi_boot_mode = (boot_mode_utils.get_boot_mode(task.node)
|
||||||
== 'uefi')
|
== 'uefi')
|
||||||
|
uefi_with_grub = is_uefi_boot_mode and not ipxe_enabled
|
||||||
|
|
||||||
# grub bootloader panics with '{}' around any of its tags in its
|
# grub bootloader panics with '{}' around any of its tags in its
|
||||||
# config file. To overcome that 'ROOT' and 'DISK_IDENTIFIER' are enclosed
|
# config file. To overcome that 'ROOT' and 'DISK_IDENTIFIER' are enclosed
|
||||||
# with '(' and ')' in uefi boot mode.
|
# with '(' and ')' in uefi boot mode.
|
||||||
# These changes do not have any impact on elilo bootloader.
|
if uefi_with_grub:
|
||||||
hex_form = True
|
|
||||||
if is_uefi_boot_mode and utils.is_regex_string_in_file(template,
|
|
||||||
'^menuentry'):
|
|
||||||
hex_form = False
|
|
||||||
pxe_config_root_tag = '(( ROOT ))'
|
pxe_config_root_tag = '(( ROOT ))'
|
||||||
pxe_config_disk_ident = '(( DISK_IDENTIFIER ))'
|
pxe_config_disk_ident = '(( DISK_IDENTIFIER ))'
|
||||||
LOG.warning("The requested config appears to support elilo. "
|
|
||||||
"Support for elilo has been deprecated and will be "
|
|
||||||
"removed in the Queens release of OpenStack.")
|
|
||||||
else:
|
else:
|
||||||
# TODO(stendulker): We should use '(' ')' as the delimiters for all our
|
# TODO(stendulker): We should use '(' ')' as the delimiters for all our
|
||||||
# config files so that we do not need special handling for each of the
|
# config files so that we do not need special handling for each of the
|
||||||
@ -312,14 +292,13 @@ def create_pxe_config(task, pxe_options, template=None, ipxe_enabled=False):
|
|||||||
|
|
||||||
# Always write the mac addresses
|
# Always write the mac addresses
|
||||||
_link_mac_pxe_configs(task, ipxe_enabled=ipxe_enabled)
|
_link_mac_pxe_configs(task, ipxe_enabled=ipxe_enabled)
|
||||||
if is_uefi_boot_mode and not ipxe_enabled:
|
if uefi_with_grub:
|
||||||
try:
|
try:
|
||||||
_link_ip_address_pxe_configs(task, hex_form, ipxe_enabled)
|
_link_ip_address_pxe_configs(task, ipxe_enabled)
|
||||||
# NOTE(TheJulia): The IP address support will fail if the
|
# NOTE(TheJulia): The IP address support will fail if the
|
||||||
# dhcp_provider interface is set to none. This will result
|
# dhcp_provider interface is set to none. This will result
|
||||||
# in the MAC addresses and DHCP files being written, and
|
# in the MAC addresses and DHCP files being written, and
|
||||||
# we can remove IP address creation for the grub use
|
# we can remove IP address creation for the grub use.
|
||||||
# case, considering that will ease removal of elilo support.
|
|
||||||
except exception.FailedToGetIPaddressesOnPort as e:
|
except exception.FailedToGetIPaddressesOnPort as e:
|
||||||
if CONF.dhcp.dhcp_provider != 'none':
|
if CONF.dhcp.dhcp_provider != 'none':
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
@ -363,21 +342,13 @@ def clean_up_pxe_config(task, ipxe_enabled=False):
|
|||||||
for port_ip_address in ip_addresses:
|
for port_ip_address in ip_addresses:
|
||||||
try:
|
try:
|
||||||
# Get xx.xx.xx.xx based grub config file
|
# Get xx.xx.xx.xx based grub config file
|
||||||
ip_address_path = _get_pxe_ip_address_path(port_ip_address,
|
ip_address_path = _get_pxe_ip_address_path(port_ip_address)
|
||||||
False)
|
|
||||||
# NOTE(TheJulia): Remove elilo support after the deprecation
|
|
||||||
# period, in the Queens release.
|
|
||||||
# Get 0AOAOAOA based elilo config file
|
|
||||||
hex_ip_path = _get_pxe_ip_address_path(port_ip_address,
|
|
||||||
True)
|
|
||||||
except exception.InvalidIPv4Address:
|
except exception.InvalidIPv4Address:
|
||||||
continue
|
continue
|
||||||
except exception.FailedToGetIPAddressOnPort:
|
except exception.FailedToGetIPAddressOnPort:
|
||||||
continue
|
continue
|
||||||
# Cleaning up config files created for grub2.
|
# Cleaning up config files created for grub2.
|
||||||
ironic_utils.unlink_without_raise(ip_address_path)
|
ironic_utils.unlink_without_raise(ip_address_path)
|
||||||
# Cleaning up config files created for elilo.
|
|
||||||
ironic_utils.unlink_without_raise(hex_ip_path)
|
|
||||||
|
|
||||||
for port in task.ports:
|
for port in task.ports:
|
||||||
client_id = port.extra.get('client-id')
|
client_id = port.extra.get('client-id')
|
||||||
@ -720,8 +691,6 @@ def build_instance_pxe_options(task, pxe_info, ipxe_enabled=False):
|
|||||||
pxe_opts[option] = get_path_relative_to_tftp_root(
|
pxe_opts[option] = get_path_relative_to_tftp_root(
|
||||||
pxe_info[label][1])
|
pxe_info[label][1])
|
||||||
|
|
||||||
# These are dummy values to satisfy elilo.
|
|
||||||
# image and initrd fields in elilo config cannot be blank.
|
|
||||||
pxe_opts.setdefault('aki_path', 'no_kernel')
|
pxe_opts.setdefault('aki_path', 'no_kernel')
|
||||||
pxe_opts.setdefault('ari_path', 'no_ramdisk')
|
pxe_opts.setdefault('ari_path', 'no_ramdisk')
|
||||||
|
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
{#- NOTE(TheJulia): Remove elilo support after the deprecation period, in the Queens release. -#}
|
|
||||||
default=deploy
|
|
||||||
|
|
||||||
image={{pxe_options.deployment_aki_path}}
|
|
||||||
label=deploy
|
|
||||||
initrd={{pxe_options.deployment_ari_path}}
|
|
||||||
append="selinux=0 troubleshoot=0 text {{ pxe_options.pxe_append_params|default("", true) }} ip=%I:{{pxe_options.tftp_server}}:%G:%M:%H::on ipa-api-url={{ pxe_options['ipa-api-url'] }} coreos.configdrive=0"
|
|
||||||
|
|
||||||
|
|
||||||
image={{pxe_options.aki_path}}
|
|
||||||
label=boot_partition
|
|
||||||
initrd={{pxe_options.ari_path}}
|
|
||||||
append="root={{ ROOT }} ro text {{ pxe_options.pxe_append_params|default("", true) }} ip=%I:{{pxe_options.tftp_server}}:%G:%M:%H::on"
|
|
||||||
|
|
||||||
image=chain.c32
|
|
||||||
label=boot_whole_disk
|
|
||||||
append="mbr:{{ DISK_IDENTIFIER }}"
|
|
@ -219,28 +219,6 @@ class TestPXEUtils(db_base.DbTestCase):
|
|||||||
expected_template = f.read().rstrip()
|
expected_template = f.read().rstrip()
|
||||||
self.assertEqual(six.text_type(expected_template), rendered_template)
|
self.assertEqual(six.text_type(expected_template), rendered_template)
|
||||||
|
|
||||||
# NOTE(TheJulia): Remove elilo support after the deprecation period,
|
|
||||||
# in the Queens release.
|
|
||||||
def test_default_elilo_config(self):
|
|
||||||
pxe_opts = self.pxe_options
|
|
||||||
pxe_opts['boot_mode'] = 'uefi'
|
|
||||||
self.config(
|
|
||||||
uefi_pxe_config_template=('ironic/drivers/modules/'
|
|
||||||
'elilo_efi_pxe_config.template'),
|
|
||||||
group='pxe'
|
|
||||||
)
|
|
||||||
rendered_template = utils.render_template(
|
|
||||||
CONF.pxe.uefi_pxe_config_template,
|
|
||||||
{'pxe_options': pxe_opts,
|
|
||||||
'ROOT': '{{ ROOT }}',
|
|
||||||
'DISK_IDENTIFIER': '{{ DISK_IDENTIFIER }}'})
|
|
||||||
|
|
||||||
templ_file = 'ironic/tests/unit/drivers/elilo_efi_pxe_config.template'
|
|
||||||
with open(templ_file) as f:
|
|
||||||
expected_template = f.read().rstrip()
|
|
||||||
|
|
||||||
self.assertEqual(six.text_type(expected_template), rendered_template)
|
|
||||||
|
|
||||||
def test_default_grub_config(self):
|
def test_default_grub_config(self):
|
||||||
pxe_opts = self.pxe_options
|
pxe_opts = self.pxe_options
|
||||||
pxe_opts['boot_mode'] = 'uefi'
|
pxe_opts['boot_mode'] = 'uefi'
|
||||||
@ -467,44 +445,6 @@ class TestPXEUtils(db_base.DbTestCase):
|
|||||||
write_mock.assert_called_with(pxe_cfg_file_path,
|
write_mock.assert_called_with(pxe_cfg_file_path,
|
||||||
render_mock.return_value)
|
render_mock.return_value)
|
||||||
|
|
||||||
# NOTE(TheJulia): Remove elilo support after the deprecation period,
|
|
||||||
# in the Queens release.
|
|
||||||
@mock.patch.object(os, 'chmod', autospec=True)
|
|
||||||
@mock.patch('ironic.common.pxe_utils._link_ip_address_pxe_configs',
|
|
||||||
autospec=True)
|
|
||||||
@mock.patch('ironic.common.utils.write_to_file', autospec=True)
|
|
||||||
@mock.patch('ironic.common.utils.render_template', autospec=True)
|
|
||||||
@mock.patch('oslo_utils.fileutils.ensure_tree', autospec=True)
|
|
||||||
def test_create_pxe_config_uefi_elilo(self, ensure_tree_mock, render_mock,
|
|
||||||
write_mock, link_ip_configs_mock,
|
|
||||||
chmod_mock):
|
|
||||||
self.config(
|
|
||||||
uefi_pxe_config_template=('ironic/drivers/modules/'
|
|
||||||
'elilo_efi_pxe_config.template'),
|
|
||||||
group='pxe'
|
|
||||||
)
|
|
||||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
|
||||||
task.node.properties['capabilities'] = 'boot_mode:uefi'
|
|
||||||
pxe_utils.create_pxe_config(task, self.pxe_options,
|
|
||||||
CONF.pxe.uefi_pxe_config_template)
|
|
||||||
|
|
||||||
ensure_calls = [
|
|
||||||
mock.call(os.path.join(CONF.pxe.tftp_root, self.node.uuid)),
|
|
||||||
mock.call(os.path.join(CONF.pxe.tftp_root, 'pxelinux.cfg')),
|
|
||||||
]
|
|
||||||
ensure_tree_mock.assert_has_calls(ensure_calls)
|
|
||||||
chmod_mock.assert_not_called()
|
|
||||||
render_mock.assert_called_with(
|
|
||||||
CONF.pxe.uefi_pxe_config_template,
|
|
||||||
{'pxe_options': self.pxe_options,
|
|
||||||
'ROOT': '{{ ROOT }}',
|
|
||||||
'DISK_IDENTIFIER': '{{ DISK_IDENTIFIER }}'})
|
|
||||||
link_ip_configs_mock.assert_called_once_with(task, True, False)
|
|
||||||
|
|
||||||
pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
|
|
||||||
write_mock.assert_called_with(pxe_cfg_file_path,
|
|
||||||
render_mock.return_value)
|
|
||||||
|
|
||||||
@mock.patch.object(os, 'chmod', autospec=True)
|
@mock.patch.object(os, 'chmod', autospec=True)
|
||||||
@mock.patch('ironic.common.pxe_utils._link_ip_address_pxe_configs',
|
@mock.patch('ironic.common.pxe_utils._link_ip_address_pxe_configs',
|
||||||
autospec=True)
|
autospec=True)
|
||||||
@ -531,7 +471,7 @@ class TestPXEUtils(db_base.DbTestCase):
|
|||||||
{'pxe_options': self.pxe_options,
|
{'pxe_options': self.pxe_options,
|
||||||
'ROOT': '(( ROOT ))',
|
'ROOT': '(( ROOT ))',
|
||||||
'DISK_IDENTIFIER': '(( DISK_IDENTIFIER ))'})
|
'DISK_IDENTIFIER': '(( DISK_IDENTIFIER ))'})
|
||||||
link_ip_configs_mock.assert_called_once_with(task, False, False)
|
link_ip_configs_mock.assert_called_once_with(task, False)
|
||||||
|
|
||||||
pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
|
pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
|
||||||
write_mock.assert_called_with(pxe_cfg_file_path,
|
write_mock.assert_called_with(pxe_cfg_file_path,
|
||||||
@ -572,7 +512,7 @@ class TestPXEUtils(db_base.DbTestCase):
|
|||||||
'DISK_IDENTIFIER': '(( DISK_IDENTIFIER ))'})
|
'DISK_IDENTIFIER': '(( DISK_IDENTIFIER ))'})
|
||||||
link_mac_pxe_configs_mock.assert_called_once_with(
|
link_mac_pxe_configs_mock.assert_called_once_with(
|
||||||
task, ipxe_enabled=False)
|
task, ipxe_enabled=False)
|
||||||
link_ip_configs_mock.assert_called_once_with(task, False, False)
|
link_ip_configs_mock.assert_called_once_with(task, False)
|
||||||
|
|
||||||
pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
|
pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
|
||||||
write_mock.assert_called_with(pxe_cfg_file_path,
|
write_mock.assert_called_with(pxe_cfg_file_path,
|
||||||
@ -694,7 +634,7 @@ class TestPXEUtils(db_base.DbTestCase):
|
|||||||
def test__get_pxe_ip_address_path(self):
|
def test__get_pxe_ip_address_path(self):
|
||||||
ipaddress = '10.10.0.1'
|
ipaddress = '10.10.0.1'
|
||||||
self.assertEqual('/tftpboot/10.10.0.1.conf',
|
self.assertEqual('/tftpboot/10.10.0.1.conf',
|
||||||
pxe_utils._get_pxe_ip_address_path(ipaddress, False))
|
pxe_utils._get_pxe_ip_address_path(ipaddress))
|
||||||
|
|
||||||
def test_get_root_dir(self):
|
def test_get_root_dir(self):
|
||||||
expected_dir = '/tftproot'
|
expected_dir = '/tftproot'
|
||||||
@ -939,7 +879,8 @@ class TestPXEUtils(db_base.DbTestCase):
|
|||||||
|
|
||||||
unlink_calls = [
|
unlink_calls = [
|
||||||
mock.call('/tftpboot/10.10.0.1.conf'),
|
mock.call('/tftpboot/10.10.0.1.conf'),
|
||||||
mock.call('/tftpboot/0A0A0001.conf')
|
mock.call('/tftpboot/pxelinux.cfg/01-aa-aa-aa-aa-aa-aa'),
|
||||||
|
mock.call('/tftpboot/' + address + '.conf')
|
||||||
]
|
]
|
||||||
unlink_mock.assert_has_calls(unlink_calls)
|
unlink_mock.assert_has_calls(unlink_calls)
|
||||||
rmtree_mock.assert_called_once_with(
|
rmtree_mock.assert_called_once_with(
|
||||||
@ -965,9 +906,9 @@ class TestPXEUtils(db_base.DbTestCase):
|
|||||||
|
|
||||||
unlink_calls = [
|
unlink_calls = [
|
||||||
mock.call('/tftpboot/10.10.0.1.conf'),
|
mock.call('/tftpboot/10.10.0.1.conf'),
|
||||||
mock.call('/tftpboot/0A0A0001.conf'),
|
|
||||||
mock.call('/tftpboot/pxelinux.cfg/01-%s' %
|
mock.call('/tftpboot/pxelinux.cfg/01-%s' %
|
||||||
address.replace(':', '-'))
|
address.replace(':', '-')),
|
||||||
|
mock.call('/tftpboot/' + address + '.conf')
|
||||||
]
|
]
|
||||||
|
|
||||||
unlink_mock.assert_has_calls(unlink_calls)
|
unlink_mock.assert_has_calls(unlink_calls)
|
||||||
@ -994,7 +935,8 @@ class TestPXEUtils(db_base.DbTestCase):
|
|||||||
|
|
||||||
unlink_calls = [
|
unlink_calls = [
|
||||||
mock.call('/tftpboot/10.10.0.1.conf'),
|
mock.call('/tftpboot/10.10.0.1.conf'),
|
||||||
mock.call('/tftpboot/0A0A0001.conf')
|
mock.call('/tftpboot/pxelinux.cfg/01-aa-aa-aa-aa-aa-aa'),
|
||||||
|
mock.call('/tftpboot/' + address + ".conf")
|
||||||
]
|
]
|
||||||
unlink_mock.assert_has_calls(unlink_calls)
|
unlink_mock.assert_has_calls(unlink_calls)
|
||||||
rmtree_mock.assert_called_once_with(
|
rmtree_mock.assert_called_once_with(
|
||||||
@ -1328,12 +1270,12 @@ class PXEInterfacesTestCase(db_base.DbTestCase):
|
|||||||
options = pxe_utils.build_pxe_config_options(task, image_info)
|
options = pxe_utils.build_pxe_config_options(task, image_info)
|
||||||
|
|
||||||
expected_options = {
|
expected_options = {
|
||||||
|
'aki_path': 'no_kernel',
|
||||||
|
'ari_path': 'no_ramdisk',
|
||||||
'deployment_aki_path': 'path-to-deploy_kernel',
|
'deployment_aki_path': 'path-to-deploy_kernel',
|
||||||
'deployment_ari_path': 'path-to-deploy_ramdisk',
|
'deployment_ari_path': 'path-to-deploy_ramdisk',
|
||||||
'pxe_append_params': pxe_params,
|
'pxe_append_params': pxe_params,
|
||||||
'tftp_server': 'my-tftp-server',
|
'tftp_server': 'my-tftp-server',
|
||||||
'aki_path': 'no_kernel',
|
|
||||||
'ari_path': 'no_ramdisk',
|
|
||||||
'ipxe_timeout': 0}
|
'ipxe_timeout': 0}
|
||||||
self.assertEqual(expected_options, options)
|
self.assertEqual(expected_options, options)
|
||||||
|
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
Support for `elilo` has been removed as support was deprecated
|
||||||
|
and `elilo` has been dropped by most Linux distributions. Users
|
||||||
|
should migrate to another PXE loader.
|
Loading…
Reference in New Issue
Block a user