fix agent-logs unit dropdown mismatch, add other hive daemons
Dashboard AGENT log tab sent unit=hive-ag3nt.service (the crate/dir name) but the actual systemd unit is hive-agent.service, so every fetch 400'd against the backend allow-list. Fixed the dropdown value and, per the same issue's request, added the other per-agent daemons (hive-mcp-http, hive-bash-daemon, hive-matrix-daemon) as selectable units, plus hive-priv.service on the SYSTEM tab's host-daemon list. Extended both backend allow-lists (post_journal / post_journal_host) to match, and fixed a stale systemd.services.hive-ag3nt doc reference in agent-hierarchy.md that had the same crate/unit-name confusion.
This commit is contained in:
parent
b87eac0a61
commit
a73216e8be
4 changed files with 21 additions and 9 deletions
|
|
@ -216,7 +216,7 @@ nspawn agent. Open questions, not yet wired:
|
||||||
|
|
||||||
One harness serve binary (`hive-agent`, with its `hive-agent-mcp` /
|
One harness serve binary (`hive-agent`, with its `hive-agent-mcp` /
|
||||||
`hive-agent-wake` siblings), one shared `nix/agent-modules/` tree, one
|
`hive-agent-wake` siblings), one shared `nix/agent-modules/` tree, one
|
||||||
service unit (`systemd.services.hive-ag3nt`) for all agents. There
|
service unit (`systemd.services.hive-agent`) for all agents. There
|
||||||
is no longer a separate manager service name or role distinction in
|
is no longer a separate manager service name or role distinction in
|
||||||
the harness — privilege differences live server-side in the broker
|
the harness — privilege differences live server-side in the broker
|
||||||
socket (which tool groups and manager-surface calls each agent
|
socket (which tool groups and manager-surface calls each agent
|
||||||
|
|
|
||||||
|
|
@ -734,7 +734,9 @@ routing is hash-based (`#agent`, `#system`, `#audit`); default is
|
||||||
|
|
||||||
**AGENT sub-tab** — per-container journald viewer. Two selects: agent
|
**AGENT sub-tab** — per-container journald viewer. Two selects: agent
|
||||||
name (populated from `GET /api/state`) and unit filter
|
name (populated from `GET /api/state`) and unit filter
|
||||||
(`hive-ag3nt.service` / `(full machine journal)`). Fetches
|
(`hive-agent.service` / `hive-mcp-http.service` /
|
||||||
|
`hive-bash-daemon.service` / `hive-matrix-daemon.service` /
|
||||||
|
`(full machine journal)`). Fetches
|
||||||
`GET /api/journal/{name}?unit=<unit>&lines=500` on selection change
|
`GET /api/journal/{name}?unit=<unit>&lines=500` on selection change
|
||||||
or `↻ refresh`. Output rendered as a `<pre>` block. A `?agent=<name>`
|
or `↻ refresh`. Output rendered as a `<pre>` block. A `?agent=<name>`
|
||||||
and/or `?unit=<svc>` URL param pre-selects the agent + unit on page
|
and/or `?unit=<svc>` URL param pre-selects the agent + unit on page
|
||||||
|
|
@ -743,9 +745,9 @@ deep-link directly to a specific agent's journal. A "fetched N ago"
|
||||||
chip appears after the `↻ refresh` button following each successful
|
chip appears after the `↻ refresh` button following each successful
|
||||||
fetch and ticks every 30 s.
|
fetch and ticks every 30 s.
|
||||||
|
|
||||||
**SYSTEM sub-tab** — host-side service logs. Unit selector (currently
|
**SYSTEM sub-tab** — host-side service logs. Unit selector
|
||||||
only `hive-c0re.service`). Fetches
|
(`hive-c0re.service` / `hive-priv.service`). Fetches
|
||||||
`GET /api/journal-host?unit=hive-c0re.service&lines=500` on activation
|
`GET /api/journal-host?unit=<unit>&lines=500` on activation
|
||||||
and on `↻ refresh`. Rendered as a `<pre>` block. A "fetched N ago"
|
and on `↻ refresh`. Rendered as a `<pre>` block. A "fetched N ago"
|
||||||
chip ticks every 30 s. Available to the operator unconditionally (not
|
chip ticks every 30 s. Available to the operator unconditionally (not
|
||||||
capability-gated — the endpoint lives on the hive-c0re dashboard,
|
capability-gated — the endpoint lives on the hive-c0re dashboard,
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,10 @@
|
||||||
<div class="logs-toolbar">
|
<div class="logs-toolbar">
|
||||||
<select id="agent-select" class="journal-unit"></select>
|
<select id="agent-select" class="journal-unit"></select>
|
||||||
<select id="agent-unit-select" class="journal-unit">
|
<select id="agent-unit-select" class="journal-unit">
|
||||||
<option value="hive-ag3nt.service">hive-ag3nt.service</option>
|
<option value="hive-agent.service">hive-agent.service</option>
|
||||||
|
<option value="hive-mcp-http.service">hive-mcp-http.service</option>
|
||||||
|
<option value="hive-bash-daemon.service">hive-bash-daemon.service</option>
|
||||||
|
<option value="hive-matrix-daemon.service">hive-matrix-daemon.service</option>
|
||||||
<option value="">(full machine journal)</option>
|
<option value="">(full machine journal)</option>
|
||||||
</select>
|
</select>
|
||||||
<button type="button" class="btn btn-restart" id="agent-refresh">↻ refresh</button>
|
<button type="button" class="btn btn-restart" id="agent-refresh">↻ refresh</button>
|
||||||
|
|
@ -61,6 +64,7 @@
|
||||||
<div class="logs-toolbar">
|
<div class="logs-toolbar">
|
||||||
<select id="system-unit-select" class="journal-unit">
|
<select id="system-unit-select" class="journal-unit">
|
||||||
<option value="hive-c0re.service">hive-c0re.service</option>
|
<option value="hive-c0re.service">hive-c0re.service</option>
|
||||||
|
<option value="hive-priv.service">hive-priv.service</option>
|
||||||
</select>
|
</select>
|
||||||
<button type="button" class="btn btn-restart" id="system-refresh">↻ refresh</button>
|
<button type="button" class="btn btn-restart" id="system-refresh">↻ refresh</button>
|
||||||
<span id="system-fetch-ts" class="meta logs-fetch-ts" hidden></span>
|
<span id="system-fetch-ts" class="meta logs-fetch-ts" hidden></span>
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,14 @@ pub(super) async fn get_journal(
|
||||||
let lines = q.lines.unwrap_or(500).min(5000);
|
let lines = q.lines.unwrap_or(500).min(5000);
|
||||||
let unit = match q.unit.as_deref().filter(|s| !s.is_empty()) {
|
let unit = match q.unit.as_deref().filter(|s| !s.is_empty()) {
|
||||||
Some(u) => {
|
Some(u) => {
|
||||||
// accept hive-agent[.service] — anything else refused.
|
// accept any of the per-container hive daemons [.service] —
|
||||||
let allowed = ["hive-agent.service"];
|
// anything else refused.
|
||||||
|
let allowed = [
|
||||||
|
"hive-agent.service",
|
||||||
|
"hive-mcp-http.service",
|
||||||
|
"hive-bash-daemon.service",
|
||||||
|
"hive-matrix-daemon.service",
|
||||||
|
];
|
||||||
let unit = if u.ends_with(".service") {
|
let unit = if u.ends_with(".service") {
|
||||||
u.to_owned()
|
u.to_owned()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -115,7 +121,7 @@ pub(super) async fn get_journal_host(
|
||||||
axum::extract::Query(q): axum::extract::Query<JournalHostQuery>,
|
axum::extract::Query(q): axum::extract::Query<JournalHostQuery>,
|
||||||
) -> Result<Response, ProblemDetails> {
|
) -> Result<Response, ProblemDetails> {
|
||||||
let lines = q.lines.unwrap_or(500).min(5000);
|
let lines = q.lines.unwrap_or(500).min(5000);
|
||||||
let allowed = ["hive-c0re.service"];
|
let allowed = ["hive-c0re.service", "hive-priv.service"];
|
||||||
let mut cmd = tokio::process::Command::new("journalctl");
|
let mut cmd = tokio::process::Command::new("journalctl");
|
||||||
cmd.args(["--no-pager", "--output=short-iso", "--lines"])
|
cmd.args(["--no-pager", "--output=short-iso", "--lines"])
|
||||||
.arg(lines.to_string());
|
.arg(lines.to_string());
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue