v0.4.62: ship the v0.4.61 cache fix as a buildable image
v0.4.61 source landed in main with the cache fix and the PXE-logo compositor, plus an aspirational Dockerfile stage that rebuilds iPXE from source with IMAGE_PNG enabled. The Dockerfile stage hits intermittent `cc1: internal compiler error: Segmentation fault` when cross-emulating x86_64 gcc under QEMU on arm64 build hosts, which is what the build host I was using does. No v0.4.61 image was ever published as a result. v0.4.62 walks back the iPXE-from-source change and ships a working image with the same cache fix and the same compositor code in place. The iPXE rebuild is queued for a follow-up release, to be built and validated on the actual x86_64 Unraid hardware where the QEMU instability doesn't apply. What's in v0.4.62 vs v0.4.6: - Asset URL versioning: index.html now appends `?v=<openpxe-version>` to every asset URL (app.css, app.js, logo.svg). Combined with `Cache-Control: no-cache, must-revalidate` on the asset handlers, upgrades land in operators' browsers without a hard refresh. This is the fix for "I pulled v0.4.6 but the UI still looks like v0.4.5". - New PXE-logo compositor in iso-store::pxe_logo: decodes any raster the operator uploads, scales-to-fit into a 600×200 bounding box, pastes it centered at the top of a 1024×768 PNG canvas, and serves the result at GET /branding/pxe-logo. Wired into render_menu's `console --picture` directive; takes effect when the shipped iPXE binaries grow PNG support. - ASCII OpenPXE wordmark in render_menu retained for v0.4.62 — works on the boot.ipxe.org pre-builds we currently ship. Quality: - 142 tests passing. - cargo clippy --workspace --all-targets clean. - No image dependency change since v0.4.61 (the `image = "0.25"` dep added in v0.4.61 stays — it backs the compositor). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
1419309a2d
commit
d729a7ae2f
Generated
+8
-8
@@ -1140,7 +1140,7 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||
|
||||
[[package]]
|
||||
name = "openpxe"
|
||||
version = "0.4.61"
|
||||
version = "0.4.62"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
@@ -1162,7 +1162,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openpxe-core"
|
||||
version = "0.4.61"
|
||||
version = "0.4.62"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bcrypt",
|
||||
@@ -1181,7 +1181,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openpxe-dhcp-proxy"
|
||||
version = "0.4.61"
|
||||
version = "0.4.62"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -1195,7 +1195,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openpxe-http-api"
|
||||
version = "0.4.61"
|
||||
version = "0.4.62"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
@@ -1226,7 +1226,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openpxe-ipxe-assets"
|
||||
version = "0.4.61"
|
||||
version = "0.4.62"
|
||||
dependencies = [
|
||||
"openpxe-core",
|
||||
"rust-embed",
|
||||
@@ -1236,7 +1236,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openpxe-iso-store"
|
||||
version = "0.4.61"
|
||||
version = "0.4.62"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bcrypt",
|
||||
@@ -1260,7 +1260,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openpxe-tftp"
|
||||
version = "0.4.61"
|
||||
version = "0.4.62"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -1274,7 +1274,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openpxe-webui"
|
||||
version = "0.4.61"
|
||||
version = "0.4.62"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.4.61"
|
||||
version = "0.4.62"
|
||||
edition = "2021"
|
||||
rust-version = "1.95"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
@@ -77,15 +77,20 @@ pub fn render_menu(isos: &[IsoMeta], settings: &Settings, base_url: &str) -> Str
|
||||
);
|
||||
let _ = writeln!(s, ":menu");
|
||||
let _ = writeln!(s, "menu OpenPXE - network boot menu");
|
||||
// v0.4.61: we used to draw an ASCII OpenPXE wordmark here. Now
|
||||
// that the bundled iPXE is built with `IMAGE_PNG`, the
|
||||
// `console --picture` line at the top of this script paints the
|
||||
// operator's actual logo (composed server-side into a 1024×768
|
||||
// canvas with the logo centered at the top) — the ASCII banner
|
||||
// became visual noise *on top* of the real image. Old iPXE
|
||||
// builds without PNG fall through the `|| console` clause and
|
||||
// simply show the menu without a logo, which is the correct
|
||||
// graceful-degradation outcome.
|
||||
// ASCII OpenPXE wordmark. Works on every iPXE build, including
|
||||
// the boot.ipxe.org pre-builds we ship (which omit `IMAGE_PNG`,
|
||||
// so `console --picture` paints nothing). When the queued iPXE
|
||||
// source-build lands and the operator's uploaded raster actually
|
||||
// paints via `console --picture`, this banner can be retired in
|
||||
// favour of the real image. The compositor at
|
||||
// /branding/pxe-logo is already wired and waiting.
|
||||
let _ = writeln!(s, "item --gap");
|
||||
let _ = writeln!(s, "item --gap -- ___ ___ __ __ ___");
|
||||
let _ = writeln!(s, "item --gap -- / _ \\ _ __ ___ _ _ | _ \\ \\/ / | __|");
|
||||
let _ = writeln!(s, "item --gap -- | (_) | '_ \\/ -_) ' \\ | _/ \\ / | _|");
|
||||
let _ = writeln!(s, "item --gap -- \\___/| .__/\\___|_||_| |_| /_/\\_\\ |___|");
|
||||
let _ = writeln!(s, "item --gap -- |_|");
|
||||
let _ = writeln!(s, "item --gap");
|
||||
let _ = writeln!(
|
||||
s,
|
||||
"item --gap -- ------------------------- Default -------------------------"
|
||||
@@ -626,12 +631,13 @@ mod password_tests {
|
||||
|
||||
#[test]
|
||||
fn top_menu_has_polished_branding_and_arch_footer() {
|
||||
// v0.4.6 polish + v0.4.61 image upgrade: the menu emits a
|
||||
// `console --picture` line that the bundled iPXE (built with
|
||||
// `IMAGE_PNG`) honours, plus an arch-resolved footer carrying
|
||||
// the current OpenPXE version. The ASCII wordmark that used
|
||||
// to live here was dropped in v0.4.61 — it duplicated the now-
|
||||
// working image.
|
||||
// v0.4.6 polish + v0.4.62 stability fixes: the menu emits a
|
||||
// `console --picture` line that PNG-capable iPXE builds will
|
||||
// honour (queued for a follow-up release once we can rebuild
|
||||
// iPXE from source on native x86_64 hardware), an ASCII
|
||||
// OpenPXE wordmark that works on every iPXE build (including
|
||||
// the boot.ipxe.org pre-builds we currently ship), and a
|
||||
// single-line footer carrying the OpenPXE version + arch.
|
||||
let settings = Settings::default();
|
||||
let s = render_menu(&[], &settings, "http://10.0.0.5");
|
||||
assert!(
|
||||
@@ -641,11 +647,11 @@ mod password_tests {
|
||||
// Picture-or-text-console must be a single statement so older
|
||||
// iPXE parsers don't choke on the chain.
|
||||
assert!(s.contains("|| console"), "missing graceful fallback:\n{s}");
|
||||
// No ASCII wordmark — once the real PNG paints, the ASCII
|
||||
// banner would duplicate the operator's logo visually.
|
||||
// ASCII wordmark — paints on every iPXE build regardless of
|
||||
// PNG support.
|
||||
assert!(
|
||||
!s.contains("___ ___ __ __ ___"),
|
||||
"ASCII banner shouldn't be emitted in v0.4.61+:\n{s}"
|
||||
s.contains("___ ___ __ __ ___"),
|
||||
"ASCII banner missing first row:\n{s}"
|
||||
);
|
||||
// Footer with version + arch interpolation. The version comes
|
||||
// from CARGO_PKG_VERSION at compile time.
|
||||
|
||||
+12
-74
@@ -16,79 +16,21 @@
|
||||
|
||||
ARG RUST_VERSION=1.95
|
||||
|
||||
########## fetch wimboot (and a sanity-check fetch of upstream iPXE) ##########
|
||||
# v0.4.61: we no longer ship the boot.ipxe.org iPXE binaries directly;
|
||||
# instead we build iPXE from source with IMAGE_PNG enabled (see the
|
||||
# ipxe-build stage below). The fetch stage still pulls wimboot (a
|
||||
# pre-signed binary from ipxe/wimboot's GitHub release) since that's
|
||||
# unrelated to the PNG concern.
|
||||
########## fetch iPXE binaries + wimboot ##########
|
||||
# v0.4.62: kept on the boot.ipxe.org pre-builds for the moment. We
|
||||
# want PNG support (so `console --picture` paints the operator's logo
|
||||
# on the PXE menu) but the obvious path — adding a new `ipxe-build`
|
||||
# stage that compiles iPXE from source with `IMAGE_PNG` enabled —
|
||||
# runs into a QEMU/gcc instability when cross-emulating x86_64 on
|
||||
# arm64 build hosts (intermittent `cc1` segfaults). The compositor
|
||||
# at /branding/pxe-logo is already wired so when the iPXE rebuild
|
||||
# lands (on native x86_64 hardware), no other code change is needed.
|
||||
FROM debian:12-slim AS fetch
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
WORKDIR /src
|
||||
RUN mkdir -p assets/ipxe && \
|
||||
curl --fail --silent --show-error --location \
|
||||
-o assets/ipxe/wimboot \
|
||||
https://github.com/ipxe/wimboot/releases/latest/download/wimboot \
|
||||
|| echo "wimboot fetch failed; Windows toggle will stay disabled"
|
||||
|
||||
########## build iPXE from source with IMAGE_PNG enabled ##########
|
||||
# This stage replaces the old "grab pre-built binaries from
|
||||
# boot.ipxe.org" path. The shipped binaries there are built with the
|
||||
# default config which omits `IMAGE_PNG`, so the `console --picture`
|
||||
# call in render_menu silently no-ops — operator logos never paint.
|
||||
# Building from source lets us flip the one flag we need.
|
||||
#
|
||||
# Cross-compilation: x86_64 + i386 use the native toolchain that ships
|
||||
# in the rust:bookworm base; arm64 uses gcc-aarch64-linux-gnu. The four
|
||||
# output binaries match the names openpxe-ipxe-assets expects in
|
||||
# assets/ipxe/.
|
||||
FROM rust:${RUST_VERSION}-bookworm AS ipxe-build
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
git build-essential liblzma-dev mtools genisoimage syslinux \
|
||||
gcc-aarch64-linux-gnu \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
WORKDIR /build
|
||||
# Pin to a recent iPXE master tip via shallow clone. iPXE doesn't tag
|
||||
# releases; pinning the SHA in source would be a periodic chore. The
|
||||
# tradeoff is that "rebuild the container" silently picks up upstream
|
||||
# patches — for a boot loader this is the right side of the
|
||||
# pin-vs-fresh tradeoff (we want CVE fixes ASAP and the PXE chain is
|
||||
# the trusted base).
|
||||
RUN git clone --depth=1 https://github.com/ipxe/ipxe.git ipxe
|
||||
WORKDIR /build/ipxe/src
|
||||
# Feature flags landed via the `config/local/` override files iPXE's
|
||||
# config system reads after `config/general.h`. We enable just the
|
||||
# image format + framebuffer console plumbing — everything else stays
|
||||
# at the upstream default. `keep-debug` is off; `parserrors` is off; we
|
||||
# pin a small set of useful tweaks.
|
||||
RUN mkdir -p config/local \
|
||||
&& printf '%s\n' \
|
||||
'#define IMAGE_PNG' \
|
||||
'#define CONSOLE_FRAMEBUFFER' \
|
||||
'#define CONSOLE_VESAFB' \
|
||||
'#define DOWNLOAD_PROTO_HTTPS' \
|
||||
'#define NSLOOKUP_CMD' \
|
||||
'#define NTP_CMD' \
|
||||
> config/local/general.h
|
||||
# Each arch builds to its own `bin-*` directory. We copy the four
|
||||
# output binaries into /out/ with the names openpxe-ipxe-assets
|
||||
# expects. Stripping the binaries saves ~30% — they go into the rust
|
||||
# binary via include_bytes! so the savings ripple through the final
|
||||
# image.
|
||||
RUN mkdir -p /out && \
|
||||
make -j"$(nproc)" bin/undionly.kpxe && \
|
||||
cp bin/undionly.kpxe /out/undionly.kpxe && \
|
||||
make -j"$(nproc)" bin-x86_64-efi/snponly.efi && \
|
||||
cp bin-x86_64-efi/snponly.efi /out/snponly.efi && \
|
||||
make -j"$(nproc)" bin-x86_64-efi/ipxe.efi && \
|
||||
cp bin-x86_64-efi/ipxe.efi /out/ipxe.efi && \
|
||||
make -j"$(nproc)" bin-i386-efi/snponly.efi && \
|
||||
cp bin-i386-efi/snponly.efi /out/snponly-i386.efi && \
|
||||
make -j"$(nproc)" CROSS_COMPILE=aarch64-linux-gnu- bin-arm64-efi/snponly.efi && \
|
||||
cp bin-arm64-efi/snponly.efi /out/snponly-arm64.efi && \
|
||||
ls -lh /out/
|
||||
COPY scripts/fetch-ipxe.sh scripts/fetch-ipxe.sh
|
||||
RUN mkdir -p assets/ipxe && bash scripts/fetch-ipxe.sh
|
||||
|
||||
########## build openpxe ##########
|
||||
FROM rust:${RUST_VERSION}-bookworm AS build
|
||||
@@ -122,11 +64,7 @@ RUN apt-get update \
|
||||
# `cargo build`, which is slow and can exhaust small Colima/CI disks.
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY crates/ crates/
|
||||
# v0.4.61: iPXE binaries come from our own source-built stage with
|
||||
# IMAGE_PNG enabled. wimboot still comes from the fetch stage (it's
|
||||
# from ipxe/wimboot's GitHub release, separately signed).
|
||||
COPY --from=ipxe-build /out/ /src/assets/ipxe/
|
||||
COPY --from=fetch /src/assets/ipxe/wimboot /src/assets/ipxe/wimboot
|
||||
COPY --from=fetch /src/assets/ipxe /src/assets/ipxe
|
||||
|
||||
# Cache cargo registry + target across builds. The mtime touch is
|
||||
# belt-and-suspenders: cargo occasionally misses mtime-only changes on
|
||||
|
||||
Reference in New Issue
Block a user