v0.7.5: Joliet namespace fallback, gap-tolerant El Torito walk, Unattended pagination

Follow-up to the v0.7.4 dashboard triage: VCSA/ultravnc data ISOs are
*correctly* flagged non-bootable (no boot catalog exists to find), but
two real false-negative holes could mislabel genuinely bootable
appliance ISOs — both closed here.

iso_fs:
- Joliet fallback (the big one): lookup() now tries the primary
  ISO9660 namespace first and falls back to the Joliet SVD (UCS-2
  big-endian identifiers, escape-sequence detected). Windows-oriented
  mastering tools — common for vendor/appliance ISOs — write a minimal
  or mangled primary tree and keep the real filenames only in Joliet;
  those images probed as "no installer files" and their in-ISO fetches
  404'd. Applies everywhere the walker is used: introspection probes
  (local + NFS/SFTP) and /iso/{id}/{*path} serving.
- find_descriptor(): the PVD/SVD search scans the whole descriptor
  area (LBA 16..32), skipping non-CD001 filler sectors instead of
  requiring a pristine sector 16.
- TestIsoBuilder grows a joliet_only mode (bare primary tree, real
  names only in the SVD) modeling the mastering worst case.

introspect:
- detect_el_torito() no longer aborts at the first non-CD001 sector or
  stops at a Set Terminator — sloppy mastering leaves zeroed filler
  sectors that used to hide a real boot record and flag a bootable
  image as a data ISO. All 16 descriptor sectors are examined; the
  25-byte exact signature can't false-positive on what follows the set.
- Volume-label read now uses the same tolerant descriptor scan, and
  label + El Torito + namespace probes all share one CachingReadAt, so
  remote probes spend fewer round-trips than before despite scanning
  more sectors.
- INTROSPECT_REV bumped to 3 so everything probed by the rev-2 logic
  re-probes with the Joliet fallback: local ISOs on first startup, and
  remote ISOs via the rev-gated cache self-invalidating.

webui:
- Unattended files: the same 5-per-page pager as Available images
  (Showing X–Y of N · Prev/Next), composed with the existing filter,
  page resets on input.

Validation: clippy pedantic clean, fmt clean, 319 workspace tests
green (+3: joliet fallback lookup, joliet-only classification, filler-
sector boot record), webui syntax-checked.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
Miles Ward
2026-06-12 17:04:01 -04:00
co-authored by Claude Opus 4.8
parent 6524aa4118
commit 1ded291c7b
5 changed files with 360 additions and 87 deletions
Generated
+8 -8
View File
@@ -2836,7 +2836,7 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
name = "openpxe"
version = "0.7.4"
version = "0.7.5"
dependencies = [
"anyhow",
"axum",
@@ -2858,7 +2858,7 @@ dependencies = [
[[package]]
name = "openpxe-core"
version = "0.7.4"
version = "0.7.5"
dependencies = [
"anyhow",
"base64",
@@ -2885,7 +2885,7 @@ dependencies = [
[[package]]
name = "openpxe-dhcp-proxy"
version = "0.7.4"
version = "0.7.5"
dependencies = [
"anyhow",
"bytes",
@@ -2902,7 +2902,7 @@ dependencies = [
[[package]]
name = "openpxe-http-api"
version = "0.7.4"
version = "0.7.5"
dependencies = [
"anyhow",
"axum",
@@ -2938,7 +2938,7 @@ dependencies = [
[[package]]
name = "openpxe-ipxe-assets"
version = "0.7.4"
version = "0.7.5"
dependencies = [
"openpxe-core",
"rust-embed",
@@ -2948,7 +2948,7 @@ dependencies = [
[[package]]
name = "openpxe-iso-store"
version = "0.7.4"
version = "0.7.5"
dependencies = [
"anyhow",
"bcrypt",
@@ -2977,7 +2977,7 @@ dependencies = [
[[package]]
name = "openpxe-tftp"
version = "0.7.4"
version = "0.7.5"
dependencies = [
"anyhow",
"bytes",
@@ -2991,7 +2991,7 @@ dependencies = [
[[package]]
name = "openpxe-webui"
version = "0.7.4"
version = "0.7.5"
[[package]]
name = "p256"