-
released this
2026-05-26 00:02:25 -04:00 | 41 commits to main since this releaseOpenPXE v0.4.6
UI polish + iVentoy-inspired PXE-menu chrome. No backend behaviour
changes other than the newidp_logo_urlSSO field; existing
deployments upgrade in place.PXE boot menu (iVentoy-style)
The top-level iPXE menu now opens with a polished centered "OpenPXE"
wordmark and closes with a single-line footer carrying the version +
the booting client's arch. Concretely:------------------------- Default ------------------------- Boot from Local HDD ----------------------- Installers ----------------------- Linux Installers > Windows Installers > -------------------------- Tools -------------------------- Tools > --------------------- Queued Deployment --------------------- Queued Deployment (join queue) OpenPXE v0.4.6 - x86_64 UEFI- ASCII wordmark lives in
item --gaplines so every iPXE build
paints it, even the minimalsnponly/undionlyvariants without
a graphics console. Always visible regardless of firmware capability. - Best-effort PNG overlay. A
console --picture <base>/branding/pxe-logo || consoleline at the top of the script lets iPXE builds with
PNG support paint the operator's uploaded raster logo as the
background. The|| consoleresets to plain text on any iPXE that
doesn't speak PNGs, so the menu always renders cleanly. - New endpoint:
GET /branding/pxe-logoserves the operator's
raster logo (PNG / JPEG / WebP / GIF) as-is. SVG uploads return 404
— iPXE can't rasterize SVG. Endpoint stays public after admin setup
because iPXE clients have no way to send a session cookie. - Footer line
OpenPXE v0.4.6 - <arch>mapped from iPXE's
${buildarch}×${platform}to a friendly form:
x86 BIOS(i386 + pcbios),x86_64 UEFI(x86_64 + efi),arm64 UEFI(arm64 + efi). No website URL per the design brief.
To get your custom logo painted in the PXE environment: upload a PNG
(or JPEG / WebP / GIF) on Settings → Branding. SVG continues to drive
the WebUI's top-left logo as before; the ASCII wordmark stands in on
the PXE side.Top-right user menu
The "signed in as X / Sign out" row moved out of the sidebar footer
and into a small person-icon button next to the theme toggle.
Click opens a popover with three rows:- Name — the operator's display username (read-only).
- Edit account — jumps to Settings, which has the Account card at
the top. - Sign out — revokes the session and bounces to the login screen.
Esc + click-outside close it. The sidebar footer is back to the clean
"Service status / Advertised PXE URL / OpenPXE v0.4.6" trio.Settings touchups
- Account card form chrome is now consistent across all four
inputs (Current password / New username / New password / Confirm).
The previous CSS selector only styledtype=textandtype=number
inputs, leaving password fields with default browser chrome —
visually misaligned next to the styled username input. The new
rule covers every input type we use, normalizes Safari's password-
field metrics, and adds a 1-pixel teal focus ring that works in
both light and dark mode. - SSO card header is now a single 3-column row: IdP display
name, IdP logo URL (new field, FleetDM-style), Metadata
source. All three controls baseline-align because the select
inherits the same chrome as the text inputs. Below the row, the
active source field (Metadata URL or pasted XML) spans full width. SsoConfig.idp_logo_urlpersisted tosso.jsonalongside the
existing fields. Length-capped at 2048 chars, must behttp://or
https://. Used by the future SAML sign-in flow to brand the
"Sign in with X" button. Empty/missing falls back to a generic
badge.
Container image
gitea.milesward.dev/mward4/openpxe:0.4.6gitea.milesward.dev/mward4/openpxe:latest
linux/amd64; static-musl binary; Debian 12-slim runtime (unchanged
from v0.4.5). Non-root UID 10001 withsetcap NET_BIND_SERVICE.Quality
- 138 tests passing (was 132 in v0.4.5). Net +6: +1 IdP-logo-URL
validation in the SSO config unit tests, +1 regression guard for the
PXE-menu polish (assertsconsole --picture, the ASCII banner, the
footer interpolation, and the three arch labels), +4 integration
tests for/branding/pxe-logocovering the missing-config / SVG-
fallback / raster-serve / post-auth-public-allowlist cases. cargo clippy --workspace --all-targetsclean.
Compatibility
- Existing
sso.jsonfiles keep working — the newidp_logo_url
field defaults to the empty string when missing. - Existing deployments upgrade in place; the WebUI bumps from v0.4.5
to v0.4.6 on next launch, picks up the new menu chrome, and the
user menu's reposition is purely cosmetic.
Downloads
- ASCII wordmark lives in
-
released this
2026-05-25 22:37:25 -04:00 | 42 commits to main since this releaseOpenPXE v0.4.5
Maintenance / hardening release. Three meaningful changes:
a Casper-cmdline fix that makes Ubuntu / Mint / Pop!_OS / elementary
ISOs reliably PXE-boot under VMware UEFI; a fully static musl binary
that removes the glibc dependency; and a complete Sonarr/Radarr-style
Forms admin auth layer with FleetDM-shaped SSO configuration on the
side.VMware UEFI fix
Borrowed from Bootimus v0.1.67.
The Debian/Ubuntu kernel command line now readsboot=casper initrd=initrd ds=nocloud ip=dhcp iso-url=…instead of the legacy
boot=casper netboot=url url=… ip=dhcp ---.
Two material changes:iso-url=is the canonical Casper option. Subiquity (the
live-server installer) consumes it directly; the oldernetboot=url url=…syntax was a Debian-installer-era artifact that subiquity
doesn't always honour.ds=nocloudshort-circuits cloud-init's metadata probe. On
VMware-UEFI guests the vmxnet3 driver comes up late enough that
cloud-init's autoprobe stalls indefinitely;ds=nocloudtells it
there's no datasource and it should move on.
Effect: Ubuntu Desktop, Ubuntu Live-Server, Mint, Pop!_OS, and
elementary OS now boot consistently under ESXi / vSphere / Workstation
UEFI guests. Bare-metal UEFI was unaffected and continues to work.A unit test (
casper_cmdline_vmware_uefi_safe) pins the new form so
this doesn't regress.Static musl binary
The container build stage now compiles against
x86_64-unknown-linux-musl. The resulting/openpxebinary has zero
glibc dependency:$ ldd /usr/local/bin/openpxe statically linkedThis matches what Bootimus shipped in v0.1.70 and gives us:
- No more "
GLIBC_2.39 not found" surprises on older RHEL / Rocky
hosts whose libc trails Debian 12's. - A future scratch / distroless variant is now a one-line swap (the
binary is its own world); v0.4.5 still ships Debian slim runtime so
we keep the existingsamba/wimtools/nfs-commonshellouts
working without behavioural changes. - Slightly smaller attack surface — no dynamic-loader, no glibc
symbol-version skew.
The choice of Rust pays off here: the entire workspace compiles
warning-free against musl without touching any code (rustls-via-reqwest,
tokio, axum, bcrypt all "just work" on the musl target).Forms-style admin auth (Sonarr / Radarr layout)
A complete first-run-bootstrap → login → change-credentials flow,
deliberately modelled on Sonarr / Radarr. From a fresh install:- The WebUI's
/api/mereturnssetup_required: trueand the SPA
renders a centered "First-run setup" card. The operator picks a
username + password. - The bootstrap call (
POST /api/setup) creates the admin record
in<work_dir>/auth.json(bcrypt-hashed, cost 10) and sets a
24-houropenpxe_sessionHttpOnly cookie. - From that moment on,
/api/*requests require the cookie; PXE
endpoints (/boot.ipxe,/iso/*,/ipxe/*, the iPXE long-poll
paths) stay public so booting clients don't get gated. - The Settings tab gains an "Administrator account" card for
rotating username / password. The current password is required
to make any change; on success every other browser session is
revoked.
Endpoints:
POST /api/setup,POST /api/login,POST /api/logout,
GET /api/me,PUT /api/me/credentials.Sidebar footer carries a
signed in as Xchip +Sign outbutton.
Forgot-password recovery is the same as Sonarr's: SSH to the host and
delete<work_dir>/auth.json— the next launch re-enters setup mode.SSO config (storage-only this release)
A FleetDM-shaped SAML configuration surface. Operators teach OpenPXE
about their IdP today; the actual SAML-response-validation flow lands
in a future release. Per the brief, the operator-visible fields are
just:- Enable SSO (toggle)
- IdP display name ("Sign in with X" label)
- Metadata source — radio between Metadata URL (HTTPS) and
pasted Metadata XML
No Entity ID field — that defaults to the advertised public base URL
internally when the SAML wiring lands, which is what every common IdP
expects.Validation: enabling SSO without either metadata source returns 400;
metadata XML is capped at 1 MiB; URLs must behttp://orhttps://
and ≤2048 chars. Endpoints:GET /api/sso,PUT /api/sso.The login screen surfaces a non-functional "Sign in with X" button
when SSO is configured but the runtime flow isn't live yet — so once
v0.4.6+ lights it up, no operator config re-entry is needed.Container image
gitea.milesward.dev/mward4/openpxe:0.4.5gitea.milesward.dev/mward4/openpxe:latest
linux/amd64; ~97 MB compressed; static-musl binary, Debian 12-slim
runtime for the shellouts. Non-root UID 10001 with
setcap NET_BIND_SERVICE.Quality
- 132 tests passing (was 106 in v0.4.4). +5 auth unit tests, +5
SSO unit tests, +7 auth integration tests, +1 SSO integration test,
+1 Casper-cmdline regression guard. cargo clippy --workspace --all-targetsclean.
Compatibility
- Existing installs keep working. Old
meta.jsonandhosts.json
files deserialize unchanged. There is no auth file on existing
deployments, so the first hit to the WebUI lands on the new
first-run setup page — that's the intended UX for the rollout.
Downloads
-
released this
2026-05-25 17:47:01 -04:00 | 43 commits to main since this releaseOpenPXE v0.4.4
Settings tab lands with API reference + custom branding, ISOs get an
operator-controlled menu category, and Storage now shows how much room
is left on the volume.New: Settings tab
A dedicated
Settingsnav item between Terminal and About. Three cards:- Identity & access — read-only placeholder for the LDAP, OIDC, and
user-management work coming in a future release. Today OpenPXE has no
built-in auth on the WebUI; run behind an identity-aware reverse proxy
(Authentik, Authelia, oauth2-proxy) for hardened deployments. - Branding — upload a custom WebUI logo (PNG, SVG, JPEG, WebP, or
GIF; up to 2 MB). Persisted under<work_dir>/branding/and served at
/assets/logo.svgin preference to the bundled mark. "OpenPXE v0.4.4"
pins to the sidebar footer so the backend identity stays visible even
with custom chrome (FleetDM-style). - API reference — a self-rendered, grouped list of every
/api/*
endpoint with method, path, and one-line summary. Sourced from a new
GET /api/docsso operators chasing an integration get it in-product
rather than having to fetch the OpenAPI YAML separately.
Storage
- Type column is now an OS / Tools dropdown. Defaults to
OS— the
ISO is routed by detected family into the Linux or Windows installer
submenus. Flipping it toToolsmoves the entry into the Tools submenu
next to memtest / shell / NIC info. Family detection still drives
BIOS/UEFI / kernel args; only the menu placement changes. New endpoint:
PUT /api/isos/:id/categorybody{"category":"os"|"tools"}. - Disk space card. Free / used / total for the volume hosting the
ISO directory, with an 80% / 95% colour ramp on the bar. Lives at the
top of the Storage tab so a half-full volume is visible before you
start an upload. New endpoint:GET /api/storage/disk. The
statvfscall lives iniso-storeso thehttp-apicrate stays
#![forbid(unsafe_code)].
UI polish
- Aligned brand block. The sidebar header now matches the topbar
height exactly so the dividing line runs straight across the top of
the app — no more "OpenPXE big, Dashboard small, different heights"
step. Brand badge is 26 px icon + 15 px label, matching the topbar's
h1. - Light-mode terminal.
--terminal-bgand the per-level text
colours now track the active theme. Previously the Terminal pane
stayed dark in light mode, looking like a stuck panel. - Sidebar footer version line. "OpenPXE v0.4.4" is pinned below the
advertised PXE URL so backend identity survives any operator-uploaded
logo. - About tab. Lead paragraph now spans the full content width
(previously capped at 60ch leaving the right two-thirds blank), and a
Docs row links to https://openpxe.com/.
Container image
gitea.milesward.dev/mward4/openpxe:0.4.4gitea.milesward.dev/mward4/openpxe:latest
linux/amd64 Debian 12-slim runtime + binary + iPXE binaries + wimboot,
non-root UID 10001 withsetcap NET_BIND_SERVICE.Quality
- 106 tests passing (was 89 in v0.4.1). Net +17 from new branding
unit tests, store/disk plumbing, and integration coverage for the
category / disk / docs / branding endpoints. cargo clippy --workspace --all-targetsclean.
Compatibility
- Old
meta.jsonfiles without acategoryfield deserialize asOs
(matches v0.4.1 behaviour — everything in OS Installers). No migration
needed. /api/settingsis unchanged; existing automations keep working.
Downloads
- Identity & access — read-only placeholder for the LDAP, OIDC, and
-
v0.4.1: upload reliability and beta polish Pre-Release
released this
2026-05-24 13:53:10 -04:00 | 44 commits to main since this release- Adds browser-safe chunked ISO uploads with deterministic progress and visible .partial files.\n- Keeps legacy multipart upload support for API clients.\n- Adds offset validation, abort cleanup, duplicate partial-file protection, and Docker build reproducibility via Cargo.lock.\n- Validates Host log capture, footer service status, 0.4.1 version surfaces, and near-black dark theme polish.\n- Full workspace tests and clippy pass.
Downloads
-
released this
2026-05-24 13:12:16 -04:00 | 47 commits to main since this releaseOpenPXE v0.4.0
Quality-of-life release on top of v0.3.2: upload reliability + diagnostics,
a per-host install log, and a true jet-black dark theme.New features
- Host log under the Hosts tab — every time a PXE client actually starts
imaging (i.e./boot/<entry>.ipxeis served past any password gate, or a
per-MAC host binding fires) OpenPXE records(timestamp, MAC, IP, image)
to a bounded ring (latest 500) and appends it toboot_log.jsonlunder
the work dir. The newHost logcard shows it newest-first. Reserved
console shortcuts (_local,_queue, …) are deliberately skipped so the
log stays focused on "what got installed where." - GET
/api/boot-log— JSON endpoint backing the new tab. Empty until
the first client boots. - iPXE MAC plumbing — per-entry chain URLs and password-prompt
submissions now carry?mac=${mac}so the boot log can attribute events
to a host without depending on DHCP correlation.
Reliability
- Upload truncation handled correctly. The multipart loop used
while let Ok(Some(_)) = field.chunk().await, which silently treated
mid-stream errors (reverse-proxy buffer caps like Cloudflare's 100 MB
free-tier limit, Cloudflare 524s, half-closed TCP, etc.) as clean EOF —
the server would happily finalise a partial ISO. v0.4.0 distinguishes
Ok(None)fromErr(_)and returns400 Bad Requestwith the
underlying cause and a "try the LAN IP directly" hint when the body is
truncated. - Per-stage upload tracing.
openpxe::http::uploadnow logs at
info/warn/errorfor every transition (begin → MB watermarks at
64/128/256/… → body complete → introspect → final). A stuck or rejected
upload is now debuggable from the Terminal tab. - Client-side upload telemetry. The browser drop-zone now shows
bytes/total, percent, throughput, and ETA while uploading. Common
failures (413, 502, 504, network drop, timeout) map to actionable hints.
UI
- Jet-black dark theme. Replaced the blue-tinted ramp (
#0b1018→
#1a2334) with a true-black palette (#000000→#0a0a0a→#141414
→#1c1c1c), modelled on NetBox Labs' product chrome. The teal accent
is preserved for brand continuity. Terminal toolbar/input recoloured to
match. - Service status moved to the sidebar. The top-right "● ready" chip
is gone; readiness is now part of the sidebar footer block alongside the
advertised PXE URL ("Service status: Ready / Advertised to clients /
http://…"). The advertised address was already the PXE boot IP
(auto-detected NIC) rather than the WebUI URL, but operators wanted them
grouped together. - Queue tab — card header "Forge" → "Status".
- Hosts tab — dropped the "Inspired by Tinkerbell smee" attribution
blurb. The MAC-binding mechanic is still the same; the marketing footnote
was just clutter.
Container image
gitea.milesward.dev/mward4/openpxe:0.4.0gitea.milesward.dev/mward4/openpxe:latest
linux/amd64; ~97 MB; Debian 12-slim runtime + binary + iPXE binaries
- wimboot. Non-root UID 10001 with
setcap NET_BIND_SERVICE.
Quality
- 89 tests passing (was 85 in v0.3.2). Includes 4 new integration
tests for the boot log (records correctly + skips reserved targets +
empty endpoint behaviour) and 5 new unit tests for the in-memory ring- on-disk JSONL.
cargo clippy --workspace --all-targetsclean.
Known caveats
- Uploading >100 MB ISOs through a Cloudflare reverse proxy will still
reject (Cloudflare's body cap, not OpenPXE's). The new UI/server hints
point the operator at the LAN IP for big files.
Downloads
- Host log under the Hosts tab — every time a PXE client actually starts
-
v0.3.1 — per-ISO password gate Pre-Release
released this
2026-05-06 22:35:11 -04:00 | 49 commits to main since this releasev0.3.1 — per-ISO boot password gate
Operators can now lock individual ISOs behind a password set in the WebUI. Picking a locked image at the PXE menu prompts the operator on the client console; the boot script is only released after a correct match. The plaintext never leaves the request — server stores bcrypt hashes, scripts never echo the candidate.
Pull
docker pull gitea.milesward.dev/mward4/openpxe:0.3.1How it looks
In the WebUI's Storage tab, each image row gains an Auth column (
open/protected) and a per-row "Set password" / "Password ✎" button that toggles an inline editor — checkbox + masked input + Save. A 🔒 appears next to the filename when locked.In the PXE menu, locked entries get a leading
*next to the size box:item --key 1 win11-test-winpe *[ 5234 MB] Windows 11 TestWhen a locked entry is selected, iPXE shows a "This image requires a password" banner, accepts input via
read --secret password(no echo), and chains back with?token=${password:uristring}so passwords with&,?,=, spaces, etc. survive transport. Wrong password sleeps 2s, printsWrong password., then re-prompts. Empty input bails to the main menu.API
PUT /api/isos/:id/passwordbody { "password": "..." }to set,{ "password": null }(or empty string) to clear.DELETE /api/isos/:id/passwordexplicit clear. Both 204 on success, 404 for unknown ids.
Security posture
- bcrypt cost =
DEFAULT_COST(10). One verify takes ~50ms on modern x86 — acceptable interactive latency, hostile to brute force on a leaked meta.json. - Server logs only that a wrong-password attempt happened plus the entry id. Never the candidate, never the correct value, never the bcrypt hash.
- Boot scripts never echo any password value back to the client console.
- The token rides in the query string — acceptable on a trusted boot VLAN, but if you reverse-proxy OpenPXE the token will end up in proxy access logs. Don't expose this to untrusted networks.
Tests
74 passing across the workspace (was 66 in v0.3.0):
- 3 store unit tests (bcrypt round-trip, unknown-id error, meta.json persistence across restart)
- 2 ipxe_script unit tests (prompt + auth-fail invariants:
read --secret,:uristring, no candidate echo) - 3 HTTP integration tests (full upload → set → prompt → fail → success → clear flow, null/empty bodies, 404 on unknown id)
cargo clippy --workspace --all-targetsclean.Local smoke verified end-to-end on a real release binary: upload
Win11_Test.iso→ PUT password → menu shows the lock indicator → no token returns prompt → wrong token returnsWrong password.→ correct token returns the wimboot chain → password values do not appear in the server log.Image details
- Base:
debian:12-slim - Architecture:
linux/amd64 - Size: ~97 MB
- Digest:
sha256:f3e5ee78079c25f55cb826837b8dda9428bf6b9592d9f15a2f6b413c5642fa1e - Runs as uid 10001
- Required cap:
NET_BIND_SERVICE - Optional cap:
SYS_ADMINfor NFS share mounting
Upgrade from v0.3.0
Drop-in. New
password_hashfield onIsoMetaisOption<String>and skipped during serialize when None — existing meta.json files are forward-compatible. Existing settings.json carries through.:latestnow points at0.3.1.Downloads
- bcrypt cost =
-
v0.3.0 — UI/Branding to OpenPXE Pre-Release
released this
2026-05-06 14:14:09 -04:00 | 50 commits to main since this releasev0.3.0 — UI/Branding OpenPXE
Full project rename to match openpxe.com. The product now reads as a polished open-source release rather than a personal-tool nickname. Placeholder retired; new mark is the rainbow-horizon medallion from site examples (animated SMIL gradient, no GIF, no JS).
Pull
docker pull gitea.milesward.dev/mward4/openpxe:0.3.0Naming changes
OpenPXE everywhere user-visible or developer-facing:
- 8 crate package names updated
- The bin crate dir + binary (
crates/openpxe,bin = "openpxe") - Env vars updated
- Tracing targets updated
- Prometheus metrics updated
- Container image path:
gitea.milesward.dev/mward4/openpxe - All in-tree paths:
/var/lib/openpxe/{isos,work,smb},/usr/share/openpxe/ipxe - Unraid template updated
Gated Deployment → Queued Deployment as the user-facing concept:
Settings::TimeoutAction::GatedDeployment→QueuedDeployment(with#[serde(alias = "gated_deployment")]so v0.2.0 settings.json files keep deserializing transparently)- Rust types:
Gate→QueueEntry,GateQueue→DeploymentQueue,gate.rs→queue.rs - HTTP routes:
/api/gate/*→/api/queue/*. JSON envelope key flipped from"gates"to"entries" - iPXE shortcut:
/boot/_gate.ipxe→/boot/_queue.ipxe. Top-level menu item idqueueinstead ofgate - WebUI sidebar tab: "Forge Gate" → "Queue"
Brand assets
logo.svgis a 24×24 medallion filled with therainbow-horizongradient from openpxe.com (sliding hue rotation via SMIL on the gradient stops, no JS).anvil-forge.svg→loader.svg, rebuilt as a 64×64 louder version of the same disc — used for page-load transitions and the imaging-progress widget. Adds a subtle scale pulse and a white inner-glow for depth.
The dashboard layout is unchanged — light/dark theme tokens and the sidebar/topbar carry over from v0.2.0. "Keeping the UI similar" was the brief.
Validation
cargo build --workspacecleancargo clippy --workspace --all-targetsno warningscargo test --workspace— 66 tests passing- Local smoke against the rebuilt release binary verifies:
/boot.ipxeemitsQueued Deployment+item queueand chains/boot/_queue.ipxe/api/queuereturns{count, entries}/metricsemitsopenpxe_queue_count(renamed frompxeforge_gate_count)/assets/logo.svgand/assets/loader.svgserve the new rainbow brand SVGs/api/statusreports version0.3.0
Image details
- Base:
debian:12-slim - Architecture:
linux/amd64 - Size: ~97 MB
- Digest:
sha256:c5fea580fb248d63f4d6c5bb9af229c2824673d5a1207f1c0e9d841c9fe40d36 - Runs as uid 10001 (entrypoint chowns bind mounts as root, then drops via
gosu) - Required cap:
NET_BIND_SERVICE - Optional cap:
SYS_ADMINfor NFS share mounting
For Unraid: pull
deploy/unraid/openpxe.xmland re-add the container under the new template. Move host appdata to/mnt/user/appdata/openpxe/.Downloads
-
v0.2.0 — pre-beta Pre-Release
released this
2026-04-30 02:28:10 -04:00 | 54 commits to main since this releasev0.2.0 — pre-beta
This is the bulk pre-beta cleanup pass. The protocol stack and operator UI are exercised by 66 automated tests (up from 56),
cargo clippy --workspace --all-targetsis fully clean, and the container image is 97 MB oflinux/amd64bytes.Pull
docker pull gitea.milesward.dev/mward4/openpxe:0.2.0Highlights
Per-MAC host bindings Pin a MAC to a boot target and the client skips the menu. The DHCP reply embeds
?mac=${mac}in theboot.ipxeURL; iPXE substitutes the literal MAC client-side, and the HTTP layer chains straight to the bound entry. NewHoststab and/api/hostsCRUD.Prometheus
/metrics. Counters for DHCP replies (per arch), TFTP transfers + bytes, HTTP requests (per route family). Gauges for ISO / client / gate / imaging counts, NFS active mounts, uptime, build info. Plain text exposition format. Lock-freeAtomicU64s — noprometheus/metrics-rsruntime dep.Light + dark themes. CSS-token toggle in the top-right corner (or press
T). Light palette designed against reference. Pre-paint inline script avoids the dark→light flash on every page load. Terminal pane stays dark in both themes.Windows boot workflow validation. A new integration test synthesizes a Windows-style ISO and asserts (1) introspection identifies it correctly, (2) the boot entry is the canonical 5-file wimboot chain, (3) the rendered iPXE script chains wimboot with
initrd --namefor each, and (4) no trust-store strings (bcdedit,testsigning,certutil,httpdisk,test-signed) appear. WinPEstartnet.cmdpicks up other open source utility lessons (explicitnet start Workstationbeforenet use, surfaced errors).Code cleanup pass
cargo clippy --workspace --all-targetsis now warning-free. Among the bigger fixes:format!()appended toString→std::fmt::Write::write!- manual reverse comparators →
Reverse map_or(false, …)→is_some_and- redundant closures → method references
std::io::Error::new(Other, …)→Error::other- merged identical match arms
Run on Unraid
docker pull gitea.milesward.dev/mward4/openpxe:0.2.0Same deployment as v0.1.0 — see
deploy/unraid/README.md. Dropdeploy/unraid/openpxe.xmlinto/boot/config/plugins/dockerMan/templates-user/for a one-click template. Web UI:http://<unraid-ip>/.What's next
A detailed Phase 6 punch list lives at
docs/NEXT_PHASE.md. The headline item is real-hardware validation across BIOS / UEFI x64 / UEFI ARM64 — the protocol legs are CI-tested, but no real firmware has booted OpenPXE yet.Image details
- Base:
debian:12-slim - Architecture:
linux/amd64 - Size: ~97 MB
- Digest:
sha256:d682c97f903caf16ae9e1631d547d7ec32a8da64b4db7ef93f64b12164233ea4 - Runs as uid 10001 (entrypoint chowns bind mounts as root, then drops via
gosu) - Required cap:
NET_BIND_SERVICE - Optional cap:
SYS_ADMINfor NFS share mounting
Downloads
-
v0.1.0 — MVP Pre-Release
released this
2026-04-30 00:02:29 -04:00 | 55 commits to main since this releasePhase 1-4 release: OpenPXE MVP
First public release — every protocol leg works in CI tests; needs real-hardware validation next.
What you can do with this image
- Boot Linux ISOs (Ubuntu, Debian, RHEL family, Arch, Alpine, openSUSE) via PXE on BIOS or x86_64 UEFI clients
- Boot Windows installers via vanilla Microsoft-signed WinPE + SMB share (no test certs, no testsigning toggle)
- Mount remote NFSv3 / NFSv4.1 shares as ISO sources without copying images into the PVC
- Drive Gated Deployment: many clients wait at a queue, operator picks one ISO, all launch simultaneously
- Watch the live tracing log + run whitelisted commands from the Terminal tab in the web UI
Pull
docker pull gitea.milesward.dev/mward4/openpxe:0.1.0Run on Unraid
See deploy/unraid/README.md. Drop
deploy/unraid/openpxe.xmlinto/boot/config/plugins/dockerMan/templates-user/for a one-click Docker template.Image details
- Base: debian:12-slim
- Architecture: linux/amd64
- Size: ~97 MB
- Runs as uid 10001 (entrypoint chowns bind mounts as root, then drops via gosu)
- Required cap: NET_BIND_SERVICE for ports 67/69/80
- Recommended cap (optional): SYS_ADMIN if you want NFS share mounting
Tests
56 passing across the workspace: 16 core + 1 dhcp-proxy + 8 http-api unit + 13 integration + 12 iso-store + 6 tftp.
Known gaps deferred to next phase
- Real-hardware Windows boot validation (plumbing tested only)
- Real-hardware NFS validation (mount manager tested only)
- Full ISO9660 + Joliet + Rock Ridge (current parser is plain ISO9660)
- UEFI HTTP Boot (option 60 = HTTPClient)
- Multi-replica deployment
Downloads