summaryrefslogtreecommitdiff
path: root/ironic/tests
diff options
context:
space:
mode:
authorDmitry Tantsur <dtantsur@protonmail.com>2021-11-15 19:40:03 +0100
committerDmitry Tantsur <dtantsur@protonmail.com>2021-11-15 20:09:20 +0100
commitdbc24610d907cb51d8b711edd1b6bd5413c85e69 (patch)
treea7a236dec81253091aadc257807dabbe9b3f8884 /ironic/tests
parent2ef65aa368842472946c7aa33749121f845ac336 (diff)
downloadironic-dbc24610d907cb51d8b711edd1b6bd5413c85e69.tar.gz
Add an option to create inspector-compatible boot.ipxe
Currently the default boot.ipxe is not suitable for ironic-inspector in a standalone configuration. This change adds a new option [pxe]ipxe_fallback_script that makes boot.ipxe fall back to the provided script. Story: #2009294 Task: #43982 Change-Id: Id5547885e75beafb4423e9e2056c79c54b286275
Diffstat (limited to 'ironic/tests')
-rw-r--r--ironic/tests/unit/common/test_pxe_utils.py36
-rw-r--r--ironic/tests/unit/drivers/boot-fallback.ipxe31
-rw-r--r--ironic/tests/unit/drivers/modules/test_ipxe.py6
3 files changed, 69 insertions, 4 deletions
diff --git a/ironic/tests/unit/common/test_pxe_utils.py b/ironic/tests/unit/common/test_pxe_utils.py
index 2c16e7eb7..4768b914a 100644
--- a/ironic/tests/unit/common/test_pxe_utils.py
+++ b/ironic/tests/unit/common/test_pxe_utils.py
@@ -154,6 +154,17 @@ class TestPXEUtils(db_base.DbTestCase):
self.assertEqual(str(expected_template), rendered_template)
+ def test_fallback_ipxe_boot_script(self):
+ rendered_template = utils.render_template(
+ CONF.pxe.ipxe_boot_script,
+ {'ipxe_for_mac_uri': 'pxelinux.cfg/',
+ 'ipxe_fallback_script': 'inspector.ipxe'})
+
+ with open('ironic/tests/unit/drivers/boot-fallback.ipxe') as f:
+ expected_template = f.read().rstrip()
+
+ self.assertEqual(str(expected_template), rendered_template)
+
def test_default_ipxe_config(self):
# NOTE(lucasagomes): iPXE is just an extension of the PXE driver,
# it doesn't have it's own configuration option for template.
@@ -714,7 +725,8 @@ class TestPXEUtils(db_base.DbTestCase):
'foo')
render_mock.assert_called_once_with(
CONF.pxe.ipxe_boot_script,
- {'ipxe_for_mac_uri': 'pxelinux.cfg/'})
+ {'ipxe_for_mac_uri': 'pxelinux.cfg/',
+ 'ipxe_fallback_script': None})
@mock.patch.object(os.path, 'isfile', lambda path: True)
@mock.patch('ironic.common.utils.file_has_content', autospec=True)
@@ -735,7 +747,27 @@ class TestPXEUtils(db_base.DbTestCase):
'foo')
render_mock.assert_called_once_with(
CONF.pxe.ipxe_boot_script,
- {'ipxe_for_mac_uri': 'pxelinux.cfg/'})
+ {'ipxe_for_mac_uri': 'pxelinux.cfg/',
+ 'ipxe_fallback_script': None})
+
+ @mock.patch.object(os.path, 'isfile', lambda path: False)
+ @mock.patch('ironic.common.utils.file_has_content', autospec=True)
+ @mock.patch('ironic.common.utils.write_to_file', autospec=True)
+ @mock.patch('ironic.common.utils.render_template', autospec=True)
+ def test_create_ipxe_boot_script_fallback(self, render_mock, write_mock,
+ file_has_content_mock):
+ self.config(ipxe_fallback_script='inspector.ipxe', group='pxe')
+ render_mock.return_value = 'foo'
+ pxe_utils.create_ipxe_boot_script()
+ self.assertFalse(file_has_content_mock.called)
+ write_mock.assert_called_once_with(
+ os.path.join(CONF.deploy.http_root,
+ os.path.basename(CONF.pxe.ipxe_boot_script)),
+ 'foo')
+ render_mock.assert_called_once_with(
+ CONF.pxe.ipxe_boot_script,
+ {'ipxe_for_mac_uri': 'pxelinux.cfg/',
+ 'ipxe_fallback_script': 'inspector.ipxe'})
@mock.patch.object(os.path, 'isfile', lambda path: True)
@mock.patch('ironic.common.utils.file_has_content', autospec=True)
diff --git a/ironic/tests/unit/drivers/boot-fallback.ipxe b/ironic/tests/unit/drivers/boot-fallback.ipxe
new file mode 100644
index 000000000..bf8ab414c
--- /dev/null
+++ b/ironic/tests/unit/drivers/boot-fallback.ipxe
@@ -0,0 +1,31 @@
+#!ipxe
+
+# NOTE(lucasagomes): Loop over all network devices and boot from
+# the first one capable of booting. For more information see:
+# https://bugs.launchpad.net/ironic/+bug/1504482
+set netid:int32 -1
+:loop
+inc netid || chain pxelinux.cfg/${mac:hexhyp} || goto old_rom
+isset ${net${netid}/mac} || goto loop_done
+echo Attempting to boot from MAC ${net${netid}/mac:hexhyp}
+chain pxelinux.cfg/${net${netid}/mac:hexhyp} || goto loop
+
+:loop_done
+chain inspector.ipxe | goto boot_failed
+
+:boot_failed
+echo PXE boot failed! No configuration found for any of the present NICs.
+echo Press any key to reboot...
+prompt --timeout 180
+reboot
+
+:old_rom
+chain inspector.ipxe | goto boot_failed_old_rom
+
+:boot_failed_old_rom
+echo PXE boot failed! No configuration found for NIC ${mac:hexhyp}.
+echo Please update your iPXE ROM and retry.
+echo Press any key to reboot...
+prompt --timeout 180
+reboot
+
diff --git a/ironic/tests/unit/drivers/modules/test_ipxe.py b/ironic/tests/unit/drivers/modules/test_ipxe.py
index 45a68eeb3..2254a2c72 100644
--- a/ironic/tests/unit/drivers/modules/test_ipxe.py
+++ b/ironic/tests/unit/drivers/modules/test_ipxe.py
@@ -395,7 +395,8 @@ class iPXEBootTestCase(db_base.DbTestCase):
'foo')
render_mock.assert_called_once_with(
CONF.pxe.ipxe_boot_script,
- {'ipxe_for_mac_uri': 'pxelinux.cfg/'})
+ {'ipxe_for_mac_uri': 'pxelinux.cfg/',
+ 'ipxe_fallback_script': None})
@mock.patch.object(os.path, 'isfile', lambda path: False)
@mock.patch('ironic.common.utils.file_has_content', autospec=True)
@@ -415,7 +416,8 @@ class iPXEBootTestCase(db_base.DbTestCase):
'foo')
render_mock.assert_called_once_with(
CONF.pxe.ipxe_boot_script,
- {'ipxe_for_mac_uri': 'pxelinux.cfg/'})
+ {'ipxe_for_mac_uri': 'pxelinux.cfg/',
+ 'ipxe_fallback_script': None})
@mock.patch.object(os.path, 'isfile', lambda path: True)
@mock.patch.object(common_utils, 'file_has_content', lambda *args: True)