dashboard: remove the L0GS page and its journal backend
Logs live at swarm level now (VictoriaLogs, read through Grafana
Explore). The hive dashboard's own journal viewer goes, with
everything that existed only to serve it:
- frontend: /logs.html, logs.js, logs.css, the H0M3 "Logs" tile and
the per-agent menu's "journal logs ->" link. The build-log list
rules BU1LDS used from logs.css move into builds.css.
- hive-c0re: GET /api/journal/{name} and GET /api/journal-host, and
priv_client::read_container_journal.
- hive-priv / hive-priv-sock: the ReadContainerJournal request, its
JournalQuery/JournalOutput wire types and the journalctl -M executor.
- nix: hive-c0re's systemd-journal supplementary group, whose only
reader was the journal-host handler.
- docs: the L0GS section, the API entry and the security table row.
Closes #5113
Closes #3819
This commit is contained in:
parent
71e7fd8b20
commit
884fb3e08b
31 changed files with 192 additions and 1231 deletions
|
|
@ -34,7 +34,7 @@ pub const AGENT_PREFIX: &str = "h-";
|
|||
|
||||
/// Sibling service containers managed by hive-c0re. This doubles as the
|
||||
/// authoritative allowlist for the requests that name a container as a
|
||||
/// string (bind-mount edits, journal reads): only these — or a valid agent
|
||||
/// string (bind-mount edits): only these — or a valid agent
|
||||
/// name — are accepted. `hive-c0re` is deliberately absent; so is the
|
||||
/// gateway, whose nginx is a plain host unit rather than a container.
|
||||
/// hive-priv re-validates against this list root-side, so it's authoritative
|
||||
|
|
@ -44,7 +44,7 @@ pub const AGENT_PREFIX: &str = "h-";
|
|||
/// [`InfraContainer`] is what gates
|
||||
/// [`PrivRequest::ControlInfraContainer`], and it has one variant more than
|
||||
/// this list (the gateway). Keep the distinction — a name that belongs to
|
||||
/// no container has no business reaching a `-M` / `nixos-container` call.
|
||||
/// no container has no business reaching a `nixos-container` call.
|
||||
pub const SIBLING_CONTAINERS: &[&str] = &["hive-forge", "hive-matrix"];
|
||||
|
||||
/// Lifecycle verb for [`PrivRequest::ControlInfraContainer`]. Maps directly
|
||||
|
|
@ -95,11 +95,10 @@ pub enum InfraContainer {
|
|||
/// other variant is a container.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum InfraTarget {
|
||||
/// An nspawn container, controlled via `container@<name>.service` and
|
||||
/// readable with `journalctl -M <name>`.
|
||||
/// An nspawn container, controlled via `container@<name>.service`.
|
||||
Container(&'static str),
|
||||
/// A plain host unit. There is no machine to enter: no `-M` journal,
|
||||
/// no `nixos-container` verb.
|
||||
/// A plain host unit. There is no machine to enter: no
|
||||
/// `nixos-container` verb.
|
||||
HostUnit(&'static str),
|
||||
}
|
||||
|
||||
|
|
@ -187,64 +186,6 @@ pub const AGENT_RUNTIME_ROOT: &str = "/run/hyperhive/agents";
|
|||
/// layout cares about. Root-owned; hive-priv creates it on first use.
|
||||
pub const MIGRATE_STAGING_ROOT: &str = "/var/lib/hyperhive/migrate-staging";
|
||||
|
||||
/// Output format for `ReadContainerJournal`. Maps to journalctl
|
||||
/// `--output=<...>`. Restricted to the two formats hive callers use so
|
||||
/// the wire type can't smuggle an arbitrary `--output` value.
|
||||
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum JournalOutput {
|
||||
/// `short` — the journalctl default (syslog-style timestamps).
|
||||
#[default]
|
||||
Short,
|
||||
/// `short-iso` — ISO 8601 timestamps.
|
||||
ShortIso,
|
||||
}
|
||||
|
||||
impl JournalOutput {
|
||||
/// The string journalctl expects after `--output=`.
|
||||
#[must_use]
|
||||
pub fn as_journalctl(self) -> &'static str {
|
||||
match self {
|
||||
JournalOutput::Short => "short",
|
||||
JournalOutput::ShortIso => "short-iso",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// journalctl knobs for `ReadContainerJournal`. Grouped into one value so
|
||||
/// the read-journal call chain (`priv_client::read_container_journal` →
|
||||
/// hive-priv's executor) and its several hive-c0re callers pass a single
|
||||
/// struct instead of eight positional args that travelled together 1:1.
|
||||
/// `Default` is the common case (last N lines, short format, no filters);
|
||||
/// callers fill `lines` and override only the knobs they need via
|
||||
/// `..Default::default()`.
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct JournalQuery {
|
||||
/// `-n <lines>`.
|
||||
pub lines: u32,
|
||||
/// `-b` — restrict to the current boot.
|
||||
#[serde(default)]
|
||||
pub boot: bool,
|
||||
/// `--output=<...>`.
|
||||
#[serde(default)]
|
||||
pub output: JournalOutput,
|
||||
/// `-u <unit>`.
|
||||
#[serde(default)]
|
||||
pub unit: Option<String>,
|
||||
/// `-p <priority>`.
|
||||
#[serde(default)]
|
||||
pub priority: Option<String>,
|
||||
/// `--grep=<regex>`.
|
||||
#[serde(default)]
|
||||
pub grep: Option<String>,
|
||||
/// `--since=<ts>`.
|
||||
#[serde(default)]
|
||||
pub since: Option<String>,
|
||||
/// `--until=<ts>`.
|
||||
#[serde(default)]
|
||||
pub until: Option<String>,
|
||||
}
|
||||
|
||||
/// One bind-mount entry for `WriteNspawnFlags`.
|
||||
/// hive-priv constructs `--bind=<host_path>:<container_path>` (or `--bind-ro=`)
|
||||
/// and validates both paths before writing the conf file.
|
||||
|
|
@ -342,24 +283,6 @@ pub enum PrivRequest {
|
|||
/// `nixos-container list`
|
||||
ListContainers,
|
||||
|
||||
// --- Container journal reads ---
|
||||
/// Read a container's journal via `journalctl -M <container>`.
|
||||
/// Requires root: the machine-bus transport enters the container's
|
||||
/// namespace, so this can't run from the unprivileged hive-c0re
|
||||
/// process. hive-priv validates `container` against the managed-
|
||||
/// container allowlist, then runs journalctl and returns its output.
|
||||
///
|
||||
/// The filters (`unit` / `priority` / `grep` / `since` / `until`)
|
||||
/// are applied within the already-authorized machine and passed to
|
||||
/// journalctl as plain argument values; they can't widen access
|
||||
/// beyond the validated `container`.
|
||||
ReadContainerJournal {
|
||||
/// System container name (`h-<agent>` or a sibling service).
|
||||
container: String,
|
||||
/// journalctl knobs (see [`JournalQuery`]).
|
||||
query: JournalQuery,
|
||||
},
|
||||
|
||||
// --- Config file writes ---
|
||||
/// Update `/etc/nixos-containers/<container>.conf`: strip old network-isolation
|
||||
/// vars, write `PRIVATE_NETWORK` + bridge settings, and set `EXTRA_NSPAWN_FLAGS`
|
||||
|
|
@ -777,9 +700,8 @@ mod tests {
|
|||
fn infra_container_enum_matches_sibling_containers() {
|
||||
// The two lists are the same set *minus the things that aren't
|
||||
// containers*: every `Container` variant must appear in
|
||||
// SIBLING_CONTAINERS and vice versa, so a `-M` journal read or a
|
||||
// `nixos-container` verb can never be pointed at a name that has no
|
||||
// machine behind it.
|
||||
// SIBLING_CONTAINERS and vice versa, so a `nixos-container` verb can
|
||||
// never be pointed at a name that has no machine behind it.
|
||||
let mut from_enum: Vec<&str> = InfraContainer::ALL
|
||||
.iter()
|
||||
.filter_map(|c| match c.target() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue