docs(bastion): document multi-arch PXE and the vendor-OS classification
Records the two things that are easy to get wrong and expensive to rediscover: the DHCP option 93 value table (19 is arm64 UEFI HTTP boot, 20 is PC/AT BIOS), and that arm64 needs iPXE with LoadFile2 or the kernel panics with unknown-block(0,0) and looks like a disk fault. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015nRFZXpKwUVE4SRSHw6GjF
This commit is contained in:
@@ -191,12 +191,20 @@ async function startHarness(vmName: string, httpPort: number, pubKey: string): P
|
||||
});
|
||||
|
||||
// iPXE binaries. The arm64 one is the whole point: dnsmasq hands it out on DHCP
|
||||
// option 93 = 11, and x86_64 is staged too so the config renders as it does in
|
||||
// production.
|
||||
// option 93 -- 11 for UEFI PXE (TFTP) and 19 for UEFI HTTP Boot.
|
||||
//
|
||||
// They go in BOTH directories, exactly as main.ts stages them. AAVMF prefers HTTP
|
||||
// Boot, so it is served an http:// URL and fetches from httpDir; a firmware that
|
||||
// takes the TFTP path reads the same file from tftpDir. Staging only tftpDir gives a
|
||||
// 404 and "No bootable option or device was found" on the console.
|
||||
log("Staging iPXE binaries...");
|
||||
copyFileSync(IPXE_ARM64, join(config.tftpDir, "ipxe-arm64.efi"));
|
||||
const ipxeX86 = "/usr/share/ipxe/ipxe-snponly-x86_64.efi";
|
||||
if (existsSync(ipxeX86)) copyFileSync(ipxeX86, join(config.tftpDir, "ipxe.efi"));
|
||||
copyFileSync(IPXE_ARM64, join(config.tftpDir, "ipxe-arm64.efi"));
|
||||
copyFileSync(IPXE_ARM64, join(config.httpDir, "ipxe-arm64.efi"));
|
||||
if (existsSync(ipxeX86)) {
|
||||
copyFileSync(ipxeX86, join(config.tftpDir, "ipxe.efi"));
|
||||
copyFileSync(ipxeX86, join(config.httpDir, "ipxe.efi"));
|
||||
}
|
||||
|
||||
// Fedora kernel + initrd for both architectures, cached across runs.
|
||||
const cacheDir = "/var/lib/libvirt/images/lab-pxe-cache";
|
||||
|
||||
Reference in New Issue
Block a user