diff --git a/ironic/common/pxe_utils.py b/ironic/common/pxe_utils.py index 901d81d912..76cb371390 100644 --- a/ironic/common/pxe_utils.py +++ b/ironic/common/pxe_utils.py @@ -120,12 +120,10 @@ def _link_mac_pxe_configs(task, ipxe_enabled=False): 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. :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 is in use by the caller. :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.") % task.node.uuid) for port_ip_address in ip_addrs: - ip_address_path = _get_pxe_ip_address_path(port_ip_address, - hex_form) + ip_address_path = _get_pxe_ip_address_path(port_ip_address) ironic_utils.unlink_without_raise(ip_address_path) relative_source_path = os.path.relpath( 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) -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. :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. """ - # 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. return os.path.join( 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 directory, so regardless of which port boots first they'll get the 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 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) is_uefi_boot_mode = (boot_mode_utils.get_boot_mode(task.node) == 'uefi') + uefi_with_grub = is_uefi_boot_mode and not ipxe_enabled # grub bootloader panics with '{}' around any of its tags in its # config file. To overcome that 'ROOT' and 'DISK_IDENTIFIER' are enclosed # with '(' and ')' in uefi boot mode. - # These changes do not have any impact on elilo bootloader. - hex_form = True - if is_uefi_boot_mode and utils.is_regex_string_in_file(template, - '^menuentry'): - hex_form = False + if uefi_with_grub: pxe_config_root_tag = '(( ROOT ))' 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: # 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 @@ -312,14 +292,13 @@ def create_pxe_config(task, pxe_options, template=None, ipxe_enabled=False): # Always write the mac addresses _link_mac_pxe_configs(task, ipxe_enabled=ipxe_enabled) - if is_uefi_boot_mode and not ipxe_enabled: + if uefi_with_grub: 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 # dhcp_provider interface is set to none. This will result # in the MAC addresses and DHCP files being written, and - # we can remove IP address creation for the grub use - # case, considering that will ease removal of elilo support. + # we can remove IP address creation for the grub use. except exception.FailedToGetIPaddressesOnPort as e: if CONF.dhcp.dhcp_provider != 'none': 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: try: # Get xx.xx.xx.xx based grub config file - 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) + ip_address_path = _get_pxe_ip_address_path(port_ip_address) except exception.InvalidIPv4Address: continue except exception.FailedToGetIPAddressOnPort: continue # Cleaning up config files created for grub2. 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: 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_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('ari_path', 'no_ramdisk') diff --git a/ironic/drivers/modules/elilo_efi_pxe_config.template b/ironic/drivers/modules/elilo_efi_pxe_config.template deleted file mode 100644 index 615605228c..0000000000 --- a/ironic/drivers/modules/elilo_efi_pxe_config.template +++ /dev/null @@ -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 }}" diff --git a/ironic/tests/unit/common/test_pxe_utils.py b/ironic/tests/unit/common/test_pxe_utils.py index 6f1372ee01..04762d71c1 100644 --- a/ironic/tests/unit/common/test_pxe_utils.py +++ b/ironic/tests/unit/common/test_pxe_utils.py @@ -219,28 +219,6 @@ class TestPXEUtils(db_base.DbTestCase): expected_template = f.read().rstrip() 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): pxe_opts = self.pxe_options pxe_opts['boot_mode'] = 'uefi' @@ -467,44 +445,6 @@ class TestPXEUtils(db_base.DbTestCase): write_mock.assert_called_with(pxe_cfg_file_path, 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('ironic.common.pxe_utils._link_ip_address_pxe_configs', autospec=True) @@ -531,7 +471,7 @@ class TestPXEUtils(db_base.DbTestCase): {'pxe_options': self.pxe_options, 'ROOT': '(( ROOT ))', '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) write_mock.assert_called_with(pxe_cfg_file_path, @@ -572,7 +512,7 @@ class TestPXEUtils(db_base.DbTestCase): 'DISK_IDENTIFIER': '(( DISK_IDENTIFIER ))'}) link_mac_pxe_configs_mock.assert_called_once_with( 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) 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): ipaddress = '10.10.0.1' 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): expected_dir = '/tftproot' @@ -939,7 +879,8 @@ class TestPXEUtils(db_base.DbTestCase): unlink_calls = [ 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) rmtree_mock.assert_called_once_with( @@ -965,9 +906,9 @@ class TestPXEUtils(db_base.DbTestCase): unlink_calls = [ mock.call('/tftpboot/10.10.0.1.conf'), - mock.call('/tftpboot/0A0A0001.conf'), mock.call('/tftpboot/pxelinux.cfg/01-%s' % - address.replace(':', '-')) + address.replace(':', '-')), + mock.call('/tftpboot/' + address + '.conf') ] unlink_mock.assert_has_calls(unlink_calls) @@ -994,7 +935,8 @@ class TestPXEUtils(db_base.DbTestCase): unlink_calls = [ 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) 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) expected_options = { + 'aki_path': 'no_kernel', + 'ari_path': 'no_ramdisk', 'deployment_aki_path': 'path-to-deploy_kernel', 'deployment_ari_path': 'path-to-deploy_ramdisk', 'pxe_append_params': pxe_params, 'tftp_server': 'my-tftp-server', - 'aki_path': 'no_kernel', - 'ari_path': 'no_ramdisk', 'ipxe_timeout': 0} self.assertEqual(expected_options, options) diff --git a/releasenotes/notes/remove-elilo-support-7fc1227f66e59084.yaml b/releasenotes/notes/remove-elilo-support-7fc1227f66e59084.yaml new file mode 100644 index 0000000000..fd4551e65b --- /dev/null +++ b/releasenotes/notes/remove-elilo-support-7fc1227f66e59084.yaml @@ -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.