Use stored sessions for logs and artifacts

Source commit: 8faa1e3b54e5474bc31b53a3b308b6f8198b6310
This commit is contained in:
Michel Paulissen 2026-07-27 05:15:55 +02:00
parent 4bfb0e6ea0
commit 47f13f7598
4 changed files with 44 additions and 7 deletions

View file

@ -12,6 +12,7 @@ use crate::client::{
}; };
use crate::config::StoredCliSession; use crate::config::StoredCliSession;
use crate::errors::cli_error_summary_for_category; use crate::errors::cli_error_summary_for_category;
use crate::process::hydrate_process_scope;
use crate::process_events::{ use crate::process_events::{
artifact_download_grant_disclosures, artifact_download_session_summary, artifact_download_grant_disclosures, artifact_download_session_summary,
artifact_export_plan_summary, artifact_response_machine_error, artifact_summaries, artifact_export_plan_summary, artifact_response_machine_error, artifact_summaries,
@ -27,9 +28,10 @@ pub(crate) fn artifact_list_report(args: ArtifactListArgs) -> Result<Value> {
} }
pub(crate) fn artifact_list_report_with_session( pub(crate) fn artifact_list_report_with_session(
args: ArtifactListArgs, mut args: ArtifactListArgs,
stored_session: Option<&StoredCliSession>, stored_session: Option<&StoredCliSession>,
) -> Result<Value> { ) -> Result<Value> {
hydrate_process_scope(&mut args.scope, stored_session);
let events = list_task_events_if_available_with_session( let events = list_task_events_if_available_with_session(
args.scope.coordinator.as_deref(), args.scope.coordinator.as_deref(),
&args.scope, &args.scope,
@ -53,9 +55,10 @@ pub(crate) fn artifact_download_report(args: ArtifactDownloadArgs) -> Result<Val
} }
pub(crate) fn artifact_download_report_with_session( pub(crate) fn artifact_download_report_with_session(
args: ArtifactDownloadArgs, mut args: ArtifactDownloadArgs,
stored_session: Option<&StoredCliSession>, stored_session: Option<&StoredCliSession>,
) -> Result<Value> { ) -> Result<Value> {
hydrate_process_scope(&mut args.scope, stored_session);
if let Some(coordinator) = &args.scope.coordinator { if let Some(coordinator) = &args.scope.coordinator {
let mut session = JsonLineSession::connect(coordinator)?; let mut session = JsonLineSession::connect(coordinator)?;
let response = session.request(authenticated_or_local_trusted_request( let response = session.request(authenticated_or_local_trusted_request(
@ -143,9 +146,10 @@ pub(crate) fn artifact_export_report(args: ArtifactExportArgs) -> Result<Value>
} }
pub(crate) fn artifact_export_report_with_session( pub(crate) fn artifact_export_report_with_session(
args: ArtifactExportArgs, mut args: ArtifactExportArgs,
stored_session: Option<&StoredCliSession>, stored_session: Option<&StoredCliSession>,
) -> Result<Value> { ) -> Result<Value> {
hydrate_process_scope(&mut args.scope, stored_session);
if let Some(coordinator) = &args.scope.coordinator { if let Some(coordinator) = &args.scope.coordinator {
let mut session = JsonLineSession::connect(coordinator)?; let mut session = JsonLineSession::connect(coordinator)?;
let response = session.request(authenticated_or_local_trusted_request( let response = session.request(authenticated_or_local_trusted_request(

View file

@ -3,6 +3,7 @@ use serde_json::{json, Value};
use crate::client::list_task_events_if_available_with_session; use crate::client::list_task_events_if_available_with_session;
use crate::config::StoredCliSession; use crate::config::StoredCliSession;
use crate::process::hydrate_process_scope;
use crate::process_events::log_entries; use crate::process_events::log_entries;
use crate::LogsArgs; use crate::LogsArgs;
@ -12,9 +13,10 @@ pub(crate) fn logs_report(args: LogsArgs) -> Result<Value> {
} }
pub(crate) fn logs_report_with_session( pub(crate) fn logs_report_with_session(
args: LogsArgs, mut args: LogsArgs,
stored_session: Option<&StoredCliSession>, stored_session: Option<&StoredCliSession>,
) -> Result<Value> { ) -> Result<Value> {
hydrate_process_scope(&mut args.scope, stored_session);
let events = list_task_events_if_available_with_session( let events = list_task_events_if_available_with_session(
args.scope.coordinator.as_deref(), args.scope.coordinator.as_deref(),
&args.scope, &args.scope,

View file

@ -15,7 +15,10 @@ use crate::{
ProcessListArgs, ProcessRestartArgs, ProcessStatusArgs, ProcessListArgs, ProcessRestartArgs, ProcessStatusArgs,
}; };
fn hydrate_process_scope(scope: &mut CliScopeArgs, stored_session: Option<&StoredCliSession>) { pub(crate) fn hydrate_process_scope(
scope: &mut CliScopeArgs,
stored_session: Option<&StoredCliSession>,
) {
if scope.coordinator.is_none() { if scope.coordinator.is_none() {
scope.coordinator = stored_session scope.coordinator = stored_session
.filter(|session| session.session_secret.is_some()) .filter(|session| session.session_secret.is_some())

View file

@ -3004,6 +3004,14 @@ fn user_control_commands_use_authenticated_envelope_with_stored_cli_session() {
"restart_task", "restart_task",
br#"{"type":"task_restart","process":"vp","task":"task-a","actor":"user-session","accepted":false,"clean_boundary_available":false,"active_task":false,"completed_event_observed":false,"requires_whole_process_restart":true,"message":"restart requires checkpoint","charged_debug_read_bytes":1024,"used_debug_read_bytes":1024,"audit_event":{"tenant":"tenant-session","project":"project-session","process":"vp","task":"task-a","actor":"user-session","operation":"restart_task","allowed":true,"reason":"restart requires checkpoint","charged_debug_read_bytes":1024,"used_debug_read_bytes":1024}}"#.as_slice(), br#"{"type":"task_restart","process":"vp","task":"task-a","actor":"user-session","accepted":false,"clean_boundary_available":false,"active_task":false,"completed_event_observed":false,"requires_whole_process_restart":true,"message":"restart requires checkpoint","charged_debug_read_bytes":1024,"used_debug_read_bytes":1024,"audit_event":{"tenant":"tenant-session","project":"project-session","process":"vp","task":"task-a","actor":"user-session","operation":"restart_task","allowed":true,"reason":"restart requires checkpoint","charged_debug_read_bytes":1024,"used_debug_read_bytes":1024}}"#.as_slice(),
), ),
(
"list_task_events",
br#"{"type":"task_events","events":[{"process":"vp","task":"task-a","terminal_state":"completed","stdout_tail":"compiled\n","stderr_tail":""}]}"#.as_slice(),
),
(
"list_task_events",
br#"{"type":"task_events","events":[{"process":"vp","task":"task-a","terminal_state":"completed","artifact_path":"/vfs/artifacts/app.txt","artifact_digest":"sha256:app","artifact_size_bytes":3}]}"#.as_slice(),
),
( (
"create_artifact_download_link", "create_artifact_download_link",
br#"{"type":"artifact_download_link","link":{"artifact":"app.txt","source":{"RetainedNode":"node-a"},"url_path":"/artifacts/tenant-session/project-session/vp/app.txt","scoped_token_digest":"sha256:token","expires_at_epoch_seconds":60,"tenant":"tenant-session","project":"project-session","process":"vp","actor":{"User":"user-session"},"max_bytes":2048,"policy_context_digest":"sha256:policy"}}"#.as_slice(), br#"{"type":"artifact_download_link","link":{"artifact":"app.txt","source":{"RetainedNode":"node-a"},"url_path":"/artifacts/tenant-session/project-session/vp/app.txt","scoped_token_digest":"sha256:token","expires_at_epoch_seconds":60,"tenant":"tenant-session","project":"project-session","process":"vp","actor":{"User":"user-session"},"max_bytes":2048,"policy_context_digest":"sha256:policy"}}"#.as_slice(),
@ -3108,9 +3116,26 @@ fn user_control_commands_use_authenticated_envelope_with_stored_cli_session() {
Some(&session), Some(&session),
) )
.unwrap(); .unwrap();
artifact_download_report_with_session( let logs = logs_report_with_session(
LogsArgs {
scope: scope.clone(),
process: Some("vp".to_owned()),
task: Some("task-a".to_owned()),
},
Some(&session),
)
.unwrap();
let artifacts = artifact_list_report_with_session(
ArtifactListArgs {
scope: scope.clone(),
process: Some("vp".to_owned()),
},
Some(&session),
)
.unwrap();
let download = artifact_download_report_with_session(
ArtifactDownloadArgs { ArtifactDownloadArgs {
scope: coordinator_scope.clone(), scope,
artifact: "app.txt".to_owned(), artifact: "app.txt".to_owned(),
to: None, to: None,
max_bytes: 2048, max_bytes: 2048,
@ -3118,6 +3143,9 @@ fn user_control_commands_use_authenticated_envelope_with_stored_cli_session() {
Some(&session), Some(&session),
) )
.unwrap(); .unwrap();
assert_eq!(logs["log_entries"][0]["stdout_tail"], "compiled\n");
assert_eq!(artifacts["artifacts"][0]["artifact"], "app.txt");
assert_eq!(download["coordinator"], session.coordinator);
debug_attach_report_with_dap_and_session( debug_attach_report_with_dap_and_session(
DebugAttachArgs { DebugAttachArgs {
scope: coordinator_scope, scope: coordinator_scope,