Remove elilo support

Story: #1691454
Task: #9754
Change-Id: I087c8172b67e83b36344c30cf52812645148d9e4
This commit is contained in:
Dmitry Tantsur 2018-01-12 12:01:28 +01:00 committed by Julia Kreger
parent 73845b3655
commit 0f6639d4eb
4 changed files with 26 additions and 126 deletions

View File

@ -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')

View File

@ -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 }}"

View File

@ -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)

View File

@ -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.