Skip to main content

Make a bootable image that loads iPXE and chains to a URL you choose

Project description

boots-from mascot - a pair of boots cropped from the bty bat's lower half

boots-from - make a bootable image that loads iPXE and chains to a URL

One image, one chain URL, every boot goes through your control plane.

Build a bootable image that runs iPXE and chains to a URL you pick. iPXE fires at boot, fetches its first script from the URL you embedded, and dispatches on whatever the server returns -- chainload an installer, sanboot the local disk, drop into a menu, anything iPXE can do.

The image knows nothing about what's on the other end. It's the equivalent of "PXE-boot but without setting up DHCP / TFTP" -- your bootstrap is the image instead of the LAN.

# Build a hybrid ISO -- bootable on iKVM virtual media + USB.
# Output is always ./boots-from.iso in the current directory.
boots-from https://my-bootserver.example/boot

The output is a hybrid ISO (~6 MB) at ./boots-from.iso: bootable as a CD-ROM on JetKVM / PiKVM / Supermicro iKVM virtual media, AND as a USB stick after dd. Same artifact, two paths. Plug in or attach over BMC, the machine runs iPXE, iPXE fetches your script, your server runs the show from there.

Writing the ISO to a device is out of scope -- pipe it to dd, open it in Balena Etcher, hand it to bty flash, or attach it over BMC virtual media. One tool, one job.

No state lives on the artifact -- the chain URL is baked into the iPXE binary via EMBED= at build time. Different URL? Rebake (build time ~5-10s).

The chain URL: one argument, a lot of flexibility

The single positional you pass is whatever iPXE's chain command accepts. That's broader than just HTTP -- iPXE speaks a range of transports natively, so the same ISO can point at any of them depending on how the URL is written:

URL form Transport Typical use
http://host[:port]/path HTTP The common case. Plain text, no certs to manage.
https://host[:port]/path HTTPS Requires an iPXE build with TLS + trusted CA.
tftp://host/path TFTP Classic PXE-style script delivery.
ftp://host/path FTP Rare, but supported.
nfs://host/export/path NFS Read a script straight off an NFS export.
iscsi:host::::iqn.target iSCSI sanboot Skip the script step, boot a remote LUN.

Requirements / semantics:

  • Format: must be a single URL iPXE understands -- no shell quoting, no spaces, no shell-glob expansion (the URL goes straight into the embedded script as a literal). If your URL legitimately needs spaces or odd characters, percent-encode them.
  • Reachability: at boot time, from the target machine's network -- not from wherever you ran boots-from. The build step does NOT fetch or validate the URL. A typo only surfaces at boot.
  • DHCP: the embedded script runs dhcp before chain, so the target machine needs to be on a LAN that hands out addresses. Static-IP / DHCP-less environments are out of scope (rebake from a fork if you need them).
  • Hostnames: resolved via the DHCP-provided DNS. Using a hostname like bty-server works if the LAN's DNS (or each client's /etc/hosts) resolves it. IPs work unconditionally.
  • What the server returns: an iPXE script (text starting with #!ipxe). It can do anything iPXE can do -- chainload another binary, sanboot a disk, display a menu, prompt the operator, conditionally branch on MAC / serial / arch, etc.
  • Failure mode: if dhcp or chain fails, iPXE drops to its interactive shell with a diagnostic message rather than rebooting in a loop. Operators can debug manually from the prompt.

Why does this exist?

iPXE absolutely supports embedding a chain script in the binary (make bin-x86_64-efi/ipxe.efi EMBED=script.ipxe), but the toolchain is a multi-step "git clone, install deps, configure, make, copy binaries, write to USB the right way for hybrid BIOS+UEFI boot" affair. Most writeups online walk through it manually.

netboot.xyz ships pre-built USB ISOs but the embedded chain URL is hardcoded to boot.netboot.xyz. Brilliant for their use case, not for "I want to point at my own server".

boots-from fills the gap: one command produces a ready-to-flash hybrid ISO with your URL baked in. Server-agnostic. Pairs with anything that serves iPXE scripts (MAAS, Foreman, FOG, Cobbler, custom Flask apps, bty, netboot.xyz on a self-hosted mirror, ...).

Scope

Custom embedded scripts, CA-cert bundles, static-IP fallback, alternate output paths, different iPXE upstream -- all rebake-from-fork territory. The source is small enough that forking and editing is a lower-cost path than maintaining flags. The project's bet is simplicity scales further than configurability.

Pre-baked release: zero-build for the common case

The GitHub release page also publishes a pre-baked boots-from-bty.iso whose embedded chain URL is http://bty-server/boot. Use it when you don't want to build locally: set up your LAN DNS (router, pihole, dnsmasq, or /etc/hosts on the operator workstation) to resolve bty-server to your bty appliance's IP, attach the ISO over BMC virtual media or write it to a USB stick, and boot. The embedded iPXE chains to http://bty-server/boot -- which is exactly the URL the bty docs already tell you to configure for PXE clients, so no extra setup is needed beyond the DNS record.

Operators who want a different default hostname rebake with boots-from <their-url> and mv boots-from.iso <whatever>.iso if they want a different filename. The build is ~5-10 seconds; the pre-baked release exists to spare the ceremony for the bty-default case, not to lock anyone in.

Companion projects

  • bty -- the flasher. Uses iPXE for its PXE control plane; takes a boots-from-made image pointed at a bty-server and gets full PXE-equivalent behaviour without configuring the LAN's DHCP for PXE.
  • nosi -- the image builder. Builds Debian / Ubuntu / Fedora sysdev images and publishes them to GHCR as ORAS artefacts; bty consumes those via oras:// refs in its catalog.

Same boots-from shape applies to any iPXE-script-serving stack (MAAS, Foreman, FOG, Cobbler, netboot.xyz on a self-hosted mirror, ...).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

boots_from-0.0.1.tar.gz (122.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

boots_from-0.0.1-py3-none-any.whl (28.8 kB view details)

Uploaded Python 3

File details

Details for the file boots_from-0.0.1.tar.gz.

File metadata

  • Download URL: boots_from-0.0.1.tar.gz
  • Upload date:
  • Size: 122.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for boots_from-0.0.1.tar.gz
Algorithm Hash digest
SHA256 cdb3f6cd5082ee8cae38bcb6e09e057546bdee6001911e246d320a62ceaa0548
MD5 64c1038d77d1e9a640cdff25e4e6e4ed
BLAKE2b-256 9ca7647a342a16b22d3fced6620f4d2d59b49556a2f66a71d53203e7c5781441

See more details on using hashes here.

Provenance

The following attestation bundles were made for boots_from-0.0.1.tar.gz:

Publisher: release.yml on safl/boots-from

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file boots_from-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: boots_from-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 28.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for boots_from-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 48e80978f0e89f579187bac4e6aa18bc139cb2da8aeabeae8ce1e13e39d722bb
MD5 a65f63fa643cc529e6a1364f0b4daa04
BLAKE2b-256 97a0fb03cd7d4d9d0f2f1c25a834f586df92aa53df3a08227c447c0c3a84001f

See more details on using hashes here.

Provenance

The following attestation bundles were made for boots_from-0.0.1-py3-none-any.whl:

Publisher: release.yml on safl/boots-from

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page