fix(#1004,#1006): get_host_journal - JournalPriority enum, grep/since/until, default 30/max 100, verbatim container, fix doc comment

This commit is contained in:
damocles 2026-06-01 20:48:02 +02:00 committed by mara
commit b9ecacaafe
6 changed files with 96 additions and 30 deletions

View file

@ -310,8 +310,8 @@ async fn dispatch(req: &AgentRequest, agent: &str, coord: &Arc<Coordinator>) ->
message: format!("{e:#}"),
},
},
AgentRequest::GetHostJournal { unit, container, lines, priority } => {
dispatch_host_journal(agent, unit, container, lines, priority).await
AgentRequest::GetHostJournal { unit, container, lines, priority, grep, since, until } => {
dispatch_host_journal(agent, unit, container, lines, priority, grep, since, until).await
}
// Manager-only variants are not valid on the agent socket.
_ => AgentResponse::Err {
@ -320,28 +320,29 @@ async fn dispatch(req: &AgentRequest, agent: &str, coord: &Arc<Coordinator>) ->
}
}
/// Handle `GetHostJournal` from the agent socket. Capability-gated:
/// the calling agent must hold `read_host_journal` in
/// Handle `GetHostJournal` from both the agent and manager sockets.
/// Capability-gated: the calling agent must hold `read_host_journal` in
/// `meta/capabilities.json`. Runs `journalctl` host-side and returns
/// the output as a `HostJournal` response.
///
/// Also called from `manager_server` so the manager can use the same
/// tool without duplicating the journalctl invocation. The manager
/// is exempt from the capability check (it holds all capabilities
/// implicitly until the capability system enforcement is complete).
/// The manager is not exempt - grant `read_host_journal` in
/// `meta/capabilities.json` to enable it for any agent including the manager.
pub async fn dispatch_host_journal(
agent: &str,
unit: &Option<String>,
container: &Option<String>,
lines: &Option<u32>,
priority: &Option<String>,
priority: &Option<hive_sh4re::JournalPriority>,
grep: &Option<String>,
since: &Option<String>,
until: &Option<String>,
) -> AgentResponse {
if !crate::capabilities::has_cap(agent, hive_sh4re::Capability::ReadHostJournal) {
return AgentResponse::Err {
message: "agent does not have the read_host_journal capability".to_owned(),
};
}
let n = lines.unwrap_or(100).min(500);
let n = lines.unwrap_or(30).min(100);
let mut args: Vec<String> = vec![
"--no-pager".to_owned(),
"--output=short".to_owned(),
@ -353,13 +354,21 @@ pub async fn dispatch_host_journal(
args.push(u.clone());
}
if let Some(c) = container {
let machine = crate::lifecycle::container_name(c);
args.push("-M".to_owned());
args.push(machine);
args.push(c.clone());
}
if let Some(p) = priority {
args.push("-p".to_owned());
args.push(p.clone());
args.push(p.as_str().to_owned());
}
if let Some(g) = grep {
args.push(format!("--grep={g}"));
}
if let Some(s) = since {
args.push(format!("--since={s}"));
}
if let Some(u) = until {
args.push(format!("--until={u}"));
}
tracing::info!(%agent, ?args, "get_host_journal");
match tokio::process::Command::new("journalctl")

View file

@ -582,9 +582,9 @@ async fn dispatch(req: &ManagerRequest, coord: &Arc<Coordinator>) -> ManagerResp
// GetHostJournal is an agent-socket-only capability-gated variant.
// The manager can use the existing GetLogs tool for per-container
// logs. Route to the agent_server handler for consistency.
ManagerRequest::GetHostJournal { unit, container, lines, priority } => {
ManagerRequest::GetHostJournal { unit, container, lines, priority, grep, since, until } => {
crate::agent_server::dispatch_host_journal(
MANAGER_AGENT, unit, container, lines, priority,
MANAGER_AGENT, unit, container, lines, priority, grep, since, until,
)
.await
}