Files
OpenPXE/crates/http-api/src/state.rs
T
Miles WardandClaude Opus 4.8 5da05a519d v0.6.2: Mythos Validation — full-codebase polish, hot-path optimizations, dhcproto 0.15
Codebase-wide review pass: finish or remove every loose end, take the
safe performance wins on the serving hot paths, and refresh the
dependency tree for reliability. No behavior changes for working
clients; legacy clients get clearer protocol errors.

Finalize / cleanup:
- Remove mac_allowlist/subnet_allowlist config fields — parsed but never
  enforced since introduction; the operator wants line-of-sight serving,
  so the honest fix is deletion, not wiring.
- Remove dead ClientRegistry API (get, set_selected_target,
  always-None selected_target field, never-emitted DhcpRequest/
  HttpIsoAsset events).
- TFTP: reject WRQ with ERR_ILLEGAL_OP and non-octet modes with a clear
  error instead of silent timeouts (legacy-client friendliness); fold
  plan_window into cfg(test); drop the unused-constant keep-alive hack.
- rustfmt sweep over the six files with accumulated drift.

Hot-path optimizations (all behavior-preserving):
- Serve embedded iPXE binaries zero-copy (Cow over rodata) on both TFTP
  and HTTP — was a ~1 MiB heap copy per boot file request.
- Cache the composited PXE boot-menu background PNG keyed on the
  branding logo revision — was ~50-200 ms of image work per booting
  client; now one compose per logo change.
- Run bcrypt verify/hash on the blocking pool (boot password gate,
  login, setup, credential rotation) so CPU-heavy auth can't stall the
  workers streaming ISO ranges to imaging machines.
- iso_raw: reuse the already-cloned IsoMeta for path resolution instead
  of a second registry lock + deep clone per range request.
- DriverEscalation: amortize the TTL sweep (1-min interval + inline
  staleness check) instead of an O(map) retain per DHCP packet.
- format_mac: one allocation instead of four per datagram.
- Introspection haystack sized to min(scan cap, file size) — was
  guaranteed a 32 MiB realloc on every large-ISO probe.

Robustness:
- parse_range: malformed Range headers are now ignored per RFC 7233
  (200 + full body) instead of answered with a bogus 206.

Dependencies:
- dhcproto 0.12 -> 0.15: drops the deprecated/unmaintained
  trust-dns-proto from the tree (hickory-proto), three releases of DHCP
  option coverage. Compiles + passes the full suite unchanged.
- socket2 0.6 (dedupes tree), bcrypt 0.19, tower-http 0.6.11 (sheds
  iri-string), tokio 1.52.3 / hyper 1.10 lockfile refresh; dead nom
  workspace entry removed; requested versions synced to shipped reality.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-09 16:44:55 -04:00

116 lines
6.0 KiB
Rust

use crate::auth::SessionStore;
use crate::saml_routes::SamlRuntime;
use crate::uploads::UploadSessions;
use openpxe_core::{
AdminStore, BootLog, BrandingStore, ClientRegistry, DeploymentQueue, HostBindings, LogBus,
Metrics, NotifyStore, SettingsStore, SsoStore,
};
use openpxe_iso_store::{
IsoStore, NfsShareManager, SftpShareManager, SmbManager, SmbShareManager, UnattendedStore,
};
use std::sync::Arc;
use time::OffsetDateTime;
/// Cached composited PXE boot-menu background: `(logo_rev, encoded PNG)`.
/// See `AppState::pxe_bg_cache`.
pub type PxeBgCache = Arc<parking_lot::Mutex<Option<(u64, bytes::Bytes)>>>;
#[derive(Clone)]
pub struct AppState {
pub iso_store: IsoStore,
pub clients: Arc<ClientRegistry>,
pub settings: Arc<SettingsStore>,
pub queue: Arc<DeploymentQueue>,
/// Per-MAC iPXE script overrides. When a client matching one of
/// these MACs requests `/boot.ipxe`, we chain straight to the
/// configured target instead of rendering the menu.
pub hosts: HostBindings,
/// Persistent boot-event log surfaced under the Hosts tab. Records
/// every `/boot/<entry>.ipxe` chain that goes on to serve a script
/// (i.e. an image actually starting to install on a machine).
pub boot_log: BootLog,
/// Operator-controlled UI overrides (custom logo). When the
/// operator hasn't uploaded anything, the WebUI serves the bundled
/// rainbow-horizon mark.
pub branding: BrandingStore,
/// v0.6.2: cache of the composited PXE boot-menu background PNG,
/// keyed on the branding logo revision. Composing costs ~50-200 ms
/// of image decode/encode and **every** booting client fetches it
/// for `console --picture` — caching makes that one compose per
/// logo change instead of one per boot.
pub pxe_bg_cache: PxeBgCache,
/// Forms-auth admin record + first-run bootstrap state. When
/// `admin.is_configured() == false`, the auth middleware passes
/// every request through and `/api/me` reports `setup_required`.
pub admin: AdminStore,
/// In-memory session table for active operator logins. Cleared on
/// process restart (sessions are tied to UI state, not persisted —
/// matches Sonarr/Radarr behaviour).
pub sessions: SessionStore,
/// SAML SSO configuration (persisted IdP metadata, Entity ID, toggles).
pub sso: SsoStore,
/// v0.5.1: in-memory SAML runtime state — outstanding AuthnRequest IDs
/// (for InResponseTo correlation), consumed-assertion replay guard, and
/// a cache of fetched IdP metadata. Tied to process lifetime, like
/// `sessions`; a restart simply invalidates any in-flight SSO login.
pub saml: SamlRuntime,
/// v0.5.0: webhook / email notification config (Slack/Teams/Discord/
/// SMTP). Drives the fire-and-forget pings on boot events and powers
/// the Advanced tab's config + "Send test" button.
pub notify: NotifyStore,
/// Lock-free metrics counters surfaced at `/metrics` in Prometheus
/// text format. Cheap to clone (handles to atomics).
pub metrics: Metrics,
/// Optional SMB manager. Present when the binary was given a writable
/// `smb_dir` at startup; `None` in pure-Linux-only deployments where
/// Windows support is not wired in. Settings toggle drives start/stop.
pub smb: Option<Arc<SmbManager>>,
/// v0.4.65: SMB share manager — userspace consumer of remote SMB
/// shares via Samba's `smbclient` CLI. Replaces the kernel-mount
/// NFS path that v0.4.64 shipped; that path didn't work on hosts
/// (Unraid, etc.) whose kernel ships without the nfs/cifs client
/// modules, and no container-side configuration could fix it.
/// `smbclient` does the SMB protocol over a plain TCP socket in
/// userspace — works in any container, no special caps required.
pub smb_shares: SmbShareManager,
/// v0.4.67: NFSv3 share manager — pure-Rust userspace consumer
/// via the `nfs3_client` crate. Ships alongside the SMB manager
/// so operators pick whichever protocol their NAS prefers.
/// In-process (no subprocess); supports HTTP Range requests on
/// NFS-sourced ISOs because NFSv3 READ3 takes an explicit offset.
pub nfs_shares: NfsShareManager,
/// v0.5.5: SFTP-over-SSH share manager — pure-Rust userspace
/// consumer via `russh` + `russh-sftp` (ring backend, no OpenSSL).
/// Ships alongside SMB/NFS as the third remote-library protocol.
/// In-process (no subprocess, no kernel mount); supports HTTP Range
/// requests because SFTP opens a seekable file handle. Authenticates
/// the server's SSH host key on a trust-on-first-use basis.
pub sftp_shares: SftpShareManager,
/// v0.5.2: uploaded unattended-install answer files (Kickstart /
/// Preseed / Autoinstall / Windows answer files). Served on demand to
/// booting clients with per-host hostname/IP/MAC templating; lives in
/// its own directory, never the ISO listing or PXE menu.
pub unattended: UnattendedStore,
/// Browser chunked upload state. Multipart uploads still go straight
/// through `IsoStore`, but the UI uses sessions so large ISO transfers
/// can show deterministic progress and leave visible partial files.
pub uploads: UploadSessions,
/// Live log bus consumed by the Terminal tab via SSE. Operator-issued
/// terminal commands also push synthetic lines onto it so the tail
/// shows them inline.
pub log_bus: Arc<LogBus>,
/// Wall-clock instant the server bound — used for the uptime chip.
pub started_at: OffsetDateTime,
/// Base URL advertised to PXE clients (e.g. `http://10.0.0.5`). Used when
/// rendering iPXE scripts so every URL resolves offline.
pub public_base_url: String,
/// Name of the network interface auto-detected at startup (e.g.
/// `enp1s0`). Surfaced read-only on the Network tab. Empty if the
/// interface couldn't be identified.
pub nic_name: String,
/// Subnet mask of the public interface in dotted-quad form.
pub subnet_mask: String,
/// Default gateway IPv4 address.
pub gateway: String,
}