Skip to content

Commit

Permalink
Merge pull request #2076 from ogayot/nbft-installer
Browse files Browse the repository at this point in the history
In the presence of a NBFT, assume the firmware supports NVMe/TCP booting
  • Loading branch information
ogayot authored Sep 10, 2024
2 parents a8bb999 + 4ed0602 commit eb6a54e
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 28 deletions.
34 changes: 22 additions & 12 deletions subiquity/server/controllers/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,6 @@ def __init__(self, app):
# If needed, this can be moved outside of the storage/filesystem stuff.
self._probe_firmware_task = SingleInstanceTask(self._probe_firmware)

self.firmware_supports_nvme_tcp_booting: Optional[bool] = None

def is_core_boot_classic(self):
return self._info.is_core_boot_classic()

Expand Down Expand Up @@ -1476,23 +1474,35 @@ async def _probe(self, *, context=None):
self.start_monitor()
break

async def _probe_firmware(self) -> None:
fw = await self.app.prober.get_firmware()

log.debug("detected firmware information: %s", fw)

def firmware_supports_nvmeotcp_boot(self, fw: dict[str, str]) -> bool:
"""Tell whether the system supports NVMe/TCP booting. This is solely
determined by checking for:
* the presence of a NBFT ; or
* the presence of a known-good firmware model/version."""
edk2_timberland_sig = {
"bios-vendor": "EFI Development Kit II / OVMF",
"bios-version": "0.0.0",
"bios-release-date": "02/06/2015",
}

if set(edk2_timberland_sig.items()).issubset(set(fw.items())):
log.debug("firmware seems to support booting with NVMe/TCP")
assume_supported = True
if pathlib.Path("/sys/firmware/acpi/tables/NBFT").exists():
log.debug("firmware seems to support booting with NVMe/TCP (NBFT found)")
return True
elif set(edk2_timberland_sig.items()).issubset(set(fw.items())):
log.debug(
"firmware seems to support booting with NVMe/TCP"
" (EDK II from Timberland SIG found)"
)
return True
else:
log.debug("firmware does not seem to support booting with NVMe/TCP")
assume_supported = False
return False

async def _probe_firmware(self) -> None:
fw = await self.app.prober.get_firmware()

log.debug("detected firmware information: %s", fw)

assume_supported = self.firmware_supports_nvmeotcp_boot(fw)

if self.model.opt_supports_nvme_tcp_booting not in (None, assume_supported):
log.debug("but CLI argument states otherwise, so ignoring")
Expand Down
48 changes: 32 additions & 16 deletions subiquity/server/controllers/tests/test_filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,30 +149,46 @@ async def test_probe_once_fs_configured(self):

@parameterized.expand(
(
(fw_lenovo, True, False, True),
(fw_lenovo, False, False, False),
(fw_lenovo, None, False, False),
(fw_edk2_timberland, True, True, False),
(fw_edk2_timberland, False, True, True),
(fw_edk2_timberland, None, True, False),
(False, fw_lenovo, False),
(False, fw_edk2_timberland, True),
(True, fw_lenovo, True),
(True, fw_edk2_timberland, True),
)
)
async def test_firmware_supports_nvmeotcp_boot(
self, nbft_exists: bool, firmware: dict[str, str], expected: bool
):
with mock.patch("pathlib.Path.exists", return_value=nbft_exists):
self.assertEqual(
expected, self.fsc.firmware_supports_nvmeotcp_boot(firmware)
)

@parameterized.expand(
(
(False, True, True),
(False, False, False),
(False, None, False),
(True, True, False),
(True, False, True),
(True, None, False),
)
)
async def test__probe_firmware(
self,
fw,
fw_supports: bool,
opt_supports: bool | None,
expect_detected_supports: bool,
expect_log: bool,
):
self.fsc.model.opt_supports_nvme_tcp_booting = opt_supports
with mock.patch.object(self.app.prober, "get_firmware", return_value=fw):
with self.assertLogs(
"subiquity.server.controllers.filesystem", level="DEBUG"
) as debug:
await self.fsc._probe_firmware()
self.assertEqual(
expect_detected_supports, self.fsc.model.detected_supports_nvme_tcp_booting
)
with mock.patch.object(self.app.prober, "get_firmware", return_value=None):
with mock.patch.object(
self.fsc, "firmware_supports_nvmeotcp_boot", return_value=fw_supports
):
with self.assertLogs(
"subiquity.server.controllers.filesystem", level="DEBUG"
) as debug:
await self.fsc._probe_firmware()
self.assertEqual(fw_supports, self.fsc.model.detected_supports_nvme_tcp_booting)
found_log = "but CLI argument states otherwise, so ignoring" in [
record.msg for record in debug.records
]
Expand Down

0 comments on commit eb6a54e

Please sign in to comment.