Storage: - Filter inputs for the Available images table (matches filename, detected family, category, source) and the Unattended files list (name, kind). Pure client-side; shown when there's more than one entry. Forty-image libraries are now navigable. Hosts — one form, one mental model: - The separate Boot rules card is gone. The Pin form gains 'Architecture (optional)' next to Label (plus the v0.7.1 boot-binary pin): a full MAC with no architecture saves a per-host pin exactly as before; a MAC prefix and/or architecture saves a first-match-wins group rule. Saved rules render as a compact read-only 'Group rules' card with remove buttons. - The boot-decision webhook keeps working via /api/boot-rules but no longer has a UI knob (operator feedback: not needed in the UI). - Per-machine auto-deploy fields are rejected on group rules with a clear message (they're per-host values). Network: - New 'Link' row under NIC name: operstate · speed · duplex · port MAC, read from sysfs at startup (detect_link_info). Empty-degrades on non-Linux dev builds and virtual NICs. Confirms WHICH physical port answers PXE in multi-NIC/trunked environments. About: - Hero copy rewritten: positioning lead, three-pillar feature grid (Boot anything / Adapt to every machine / Run it in production), and the privacy + no-test-cert principles restated crisply. Spacing: - label.field:has(+ button) collapse fixes the doubled 30px gap above Queue 'Launch for all waiting' and Network 'Save' (now the same 16px as every other card action). Validation: clippy clean, fmt clean, 299 workspace tests green, webui syntax-checked. No protocol or boot-path changes in this release. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
128 lines
6.8 KiB
Rust
128 lines
6.8 KiB
Rust
use crate::auth::SessionStore;
|
|
use crate::saml_routes::SamlRuntime;
|
|
use crate::uploads::UploadSessions;
|
|
use openpxe_core::{
|
|
AdminStore, BootLog, BootRulesStore, BootTokens, 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,
|
|
/// v0.7.0: ordered label-based boot rules (MAC prefix / arch →
|
|
/// target) plus the optional boot-decision webhook. Consulted by the
|
|
/// top-level boot script after exact host bindings, before the menu.
|
|
pub boot_rules: BootRulesStore,
|
|
/// v0.7.0: short-lived access tokens for unattended answer files.
|
|
/// Minted into every generated answer-file URL; the serving endpoint
|
|
/// requires one (or an operator session) once an admin exists.
|
|
pub boot_tokens: BootTokens,
|
|
/// 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,
|
|
/// v0.7.2: physical link summary for that NIC (operstate, speed,
|
|
/// duplex, port MAC) — read from sysfs at startup; empty where
|
|
/// unavailable. Helps confirm which port answers PXE.
|
|
pub nic_link: String,
|
|
/// Subnet mask of the public interface in dotted-quad form.
|
|
pub subnet_mask: String,
|
|
/// Default gateway IPv4 address.
|
|
pub gateway: String,
|
|
}
|