Make a bootable image that loads iPXE and chains to a URL you choose
Project description
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
dhcpbeforechain, 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-serverworks 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
dhcporchainfails, 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 aboots-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 viaoras://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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cdb3f6cd5082ee8cae38bcb6e09e057546bdee6001911e246d320a62ceaa0548
|
|
| MD5 |
64c1038d77d1e9a640cdff25e4e6e4ed
|
|
| BLAKE2b-256 |
9ca7647a342a16b22d3fced6620f4d2d59b49556a2f66a71d53203e7c5781441
|
Provenance
The following attestation bundles were made for boots_from-0.0.1.tar.gz:
Publisher:
release.yml on safl/boots-from
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
boots_from-0.0.1.tar.gz -
Subject digest:
cdb3f6cd5082ee8cae38bcb6e09e057546bdee6001911e246d320a62ceaa0548 - Sigstore transparency entry: 1572407764
- Sigstore integration time:
-
Permalink:
safl/boots-from@171dd0b0229d33b4ba164b42705dd8c02d667040 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/safl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@171dd0b0229d33b4ba164b42705dd8c02d667040 -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48e80978f0e89f579187bac4e6aa18bc139cb2da8aeabeae8ce1e13e39d722bb
|
|
| MD5 |
a65f63fa643cc529e6a1364f0b4daa04
|
|
| BLAKE2b-256 |
97a0fb03cd7d4d9d0f2f1c25a834f586df92aa53df3a08227c447c0c3a84001f
|
Provenance
The following attestation bundles were made for boots_from-0.0.1-py3-none-any.whl:
Publisher:
release.yml on safl/boots-from
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
boots_from-0.0.1-py3-none-any.whl -
Subject digest:
48e80978f0e89f579187bac4e6aa18bc139cb2da8aeabeae8ce1e13e39d722bb - Sigstore transparency entry: 1572407780
- Sigstore integration time:
-
Permalink:
safl/boots-from@171dd0b0229d33b4ba164b42705dd8c02d667040 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/safl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@171dd0b0229d33b4ba164b42705dd8c02d667040 -
Trigger Event:
push
-
Statement type: