Skip to content

[scanner] fix: enable PXE DDI downloads - #27

Open
kubestellar-hive[bot] wants to merge 1 commit into
mainfrom
scanner/fix-pxe-ddi-download
Open

kubestellar-hive[bot] wants to merge 1 commit into
mainfrom
scanner/fix-pxe-ddi-download

Conversation

@kubestellar-hive

Copy link
Copy Markdown
Contributor

Fix

Enable opt-in PXE installation using inst.ddi_url, with optional SHA256 verification and explicit target disk selection. Downloaded DDIs use temporary systemd-repart overrides; embedded installer-media behavior remains the default. Add curl, zstd, checksum tooling, and document the network flow.

Fixes #14


Filed by scanner agent (ACMM L5 — hold-gated mode). Hold-gated: human review required.

— hive: agent=scanner backend=copilot model=gpt-5.6-luna

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Architecturally the best-positioned of four overlapping PXE PRs in this repo (#22/#25/#26/#27): correctly rebased on current main, doesn't redundantly re-add the PXE-export lines already merged there, and adds only the missing inst.ddi_url/inst.target_disk piece. But CI fails with the identical real bug as #26: freedesktop-sdk.bst:components/coreutils.bst doesn't exist upstream, breaking bst show.

PXE overlap summary: these are four independent, competing bot attempts at the same feature, not a sequential build-up. Main has already absorbed the "export standalone kernel+initrd" half from a source outside this batch; only the "opt-in network DDI fetch" half remains open. #25 was the most complete/human-approved version but is now stale against main. This one (#27) is the only one correctly rebased on what's already merged, but shares #26's fatal phantom-dependency mistake. Recommend closing #22 and #26 as superseded/duplicate, and fixing the coreutils.bst reference here (or rebasing #25) as the path forward.


Generated by Claude Code

@castrojo

castrojo commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

Deferring PXE network DDI pull for 26.08.0 release. Standalone PXE boot artifacts already shipped in #23.

Enable opt-in PXE installation using inst.ddi_url, with optional SHA256
verification and explicit target disk selection. Downloaded DDIs use
temporary systemd-repart overrides; embedded installer-media behavior
remains the default. Add curl, sed, zstd tooling to installer stack,
and document the network flow.

Fixes #14

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@castrojo
castrojo force-pushed the scanner/fix-pxe-ddi-download branch from a229967 to fab2a5d Compare September 10, 2026 00:11
@castrojo

Copy link
Copy Markdown
Collaborator

Rebased cleanly onto latest main:

  • Resolved merge conflict in elements/oci/bluefin-server-installer.bst (retained both NVMe discovery and removable media fallback staging alongside PXE command-line overrides).
  • Corrected elements/installer/installer-stack.bst by removing the non-existent freedesktop-sdk.bst:components/coreutils.bst reference (coreutils tooling is provided by bluefin-server/uutils-coreutils.bst).
  • Fixed bash built-in cmdline reading syntax to satisfy installer unit tests.
  • Re-tested with just validate and pytest tests/unit (all passing).

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integrity is opt-in on the most destructive path in the repo

Before anything else: a maintainer already deferred this scope, and the hold label is still on.

@castrojo, 2026-09-06: Deferring PXE network DDI pull for 26.08.0 release. Standalone PXE boot artifacts already shipped in #23.

If that still stands, this should stay out of the 26.08.0 set regardless of the below. The rebase on 2026-09-10 makes the intent ambiguous, so worth an explicit call.

On the code itself:

1. inst.ddi_sha256 is optional — so an unverified network blob can be written straight to disk

curl --fail --silent --show-error --location --retry 3 \
  --output /run/installer/bluefin-server-ddi.raw.zst "${DDI_URL}"
if [ -n "${DDI_SHA256}" ]; then
  printf '%s  %s\n' "${DDI_SHA256}" ... | sha256sum --check --status || { ... exit 1; }
fi

If inst.ddi_sha256 is absent, there is no check at all, and the downloaded image becomes the machine's root filesystem. Every input here is attacker-reachable in the threat model PXE actually has: the kernel command line arrives over DHCP/TFTP, both unauthenticated. --location follows redirects to any host, and nothing constrains the scheme — --proto/--proto-redir are not set, so inst.ddi_url=http://… is accepted and so is an http:// redirect target.

This should fail closed: when DDI_URL is set and DDI_SHA256 is empty, abort. Plus --proto '=https' --proto-redir '=https' on the curl invocation. A destructive whole-disk write is exactly where opt-in integrity is the wrong default — and it sits oddly beside #81, #90 and #91, which are all tightening supply-chain posture in this same repo.

2. The docs promise HTTPS the code does not enforce

-The installer is offline, self-contained, and systemd-native.
+The installer is systemd-native and offline by default. ... while PXE users may
+opt into downloading it over HTTPS.

and

inst.ddi_url=<https-url> downloads zstd-compressed DDI instead of using embedded installer partition.

Nothing in the shell restricts the scheme. Either enforce it (item 1) or drop the HTTPS claim. Same for:

Network or checksum failures abort before partitioning.

True for a failed checksum; silent for an absent one, which is the case that matters.

3. mkdir -p /usr/lib/repart.sysinstall.d writes to /usr at install time

mkdir -p /run/installer /usr/lib/repart.sysinstall.d
...
cp /usr/lib/repart.d/10-esp.conf /usr/lib/repart.sysinstall.d/

The wrapper runs under set -euo pipefail (line 183), so if /usr is read-only in the booted installer — which is the normal shape for a UKI/DDI-backed systemd-native initrd — the very first mkdir aborts the whole install with a bare EROFS. Nothing in this diff remounts it or establishes that /usr is writable there, and I can't settle it from the tree alone since the build produces the image but never boots it.

/run/installer is already created in the staged rootfs (mkdir -p /layer/run/installer, step 1a) and is unambiguously writable. If systemd-sysinstall accepts a definitions directory under /run, putting the overrides there removes the question entirely. If it must be /usr/lib, please confirm the mount is writable and say so in a comment — this is the sort of thing that only shows up on real PXE hardware.

4. ~50 lines of new shell on the destructive path, with no test

tests/unit/test_installer_contract.py already greps this exact element for behavioural contracts — test_installer_wrapper_reads_kernel_command_line_without_cat, test_installer_loads_nvme_and_settles_udev, and so on. None of the new PXE branch is covered: not the cmdline parsing, not the fail-closed paths, not the repart override rewrite. #86 just set a good bar for this (it mutation-tests the flash-installer guards); the same approach applies cleanly here, and at minimum a contract test asserting "DDI_URL set and DDI_SHA256 empty ⇒ exit non-zero" would pin item 1 permanently.

5. Minor

  • --retry 3 without --retry-all-errors won't retry the non-transient-looking failures that dominate PXE environments.
  • The doc example names bluefin-server-pxe-vmlinuz / bluefin-server-pxe-initrd.cpio.gz, but just export-pxe emits versioned filenames (bluefin-server-pxe-vmlinuz-*, bluefin-server-pxe-initrd-*.cpio.gz). More importantly, export-pxe is not called anywhere in .github/workflows/build.yml — the build job runs export-ddi, export-installer and export-sysext only, and the release step uploads installer-*.raw.zst, *.efi, ddi/* and sysext/*. So the PXE artifacts this documentation tells operators to boot are never published to a release. Worth resolving as part of making the PXE story real.

Status

mergeable_state: clean, and I confirmed it locally:

$ git checkout -B testmerge 7f376fa && git merge --no-gpg-sign --no-edit pr27
CLEAN

CI on fab2a5d is green (build success, docs success; no unit job, correctly, since no path in the unit-tests.yml filter is touched). Local gates on the merged tree: 201 passed, 1 xfailed, 41/41 bats, all three checkers exit 0 — identical to the main baseline at 7f376fa. So nothing here is broken; the concerns are about behaviour CI does not and cannot exercise.


Generated by Claude Code

@castrojo

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

The branch could not be refreshed onto current main automatically because elements/oci/bluefin-server-installer.bst conflicts. Please rebase and resolve that file. Current main includes #149, so the refreshed branch will use the shared Project Bluefin QEMU installer gate. The existing hold decision remains unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hold Work is intentionally paused.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: PXE/netboot install support (standalone PXE artifacts + network DDI pull)

2 participants