Skip to main content

life_cli/
status.rs

1//! Status checking for deployed agents.
2
3use anyhow::{Context, Result};
4use tabled::{Table, Tabled};
5
6use crate::cli::StatusArgs;
7use crate::deploy::DeploymentState;
8
9#[derive(Tabled)]
10struct ServiceRow {
11    #[tabled(rename = "Service")]
12    name: String,
13    #[tabled(rename = "Status")]
14    status: String,
15    #[tabled(rename = "URL")]
16    url: String,
17    #[tabled(rename = "Service ID")]
18    service_id: String,
19}
20
21pub async fn run(args: StatusArgs) -> Result<()> {
22    let state = DeploymentState::load(&args.agent)
23        .with_context(|| format!("no deployment found for agent '{}'", args.agent))?;
24
25    // Create backend and query live status
26    let backend = crate::deploy::create_backend(&state.target)?;
27    let live_status = backend.status(&state.project_id).await;
28
29    match &args.format[..] {
30        "json" => {
31            match &live_status {
32                Ok(services) => {
33                    let output = serde_json::json!({
34                        "agent": state.agent_name,
35                        "project_name": state.project_name,
36                        "project_id": state.project_id,
37                        "target": state.target,
38                        "template": state.template_name,
39                        "deployed_at": state.deployed_at.to_rfc3339(),
40                        "services": services,
41                    });
42                    println!("{}", serde_json::to_string_pretty(&output)?);
43                }
44                Err(e) => {
45                    // Fall back to saved state
46                    let output = serde_json::json!({
47                        "agent": state.agent_name,
48                        "project_name": state.project_name,
49                        "project_id": state.project_id,
50                        "target": state.target,
51                        "template": state.template_name,
52                        "deployed_at": state.deployed_at.to_rfc3339(),
53                        "services": state.services,
54                        "warning": format!("live status unavailable: {e}"),
55                    });
56                    println!("{}", serde_json::to_string_pretty(&output)?);
57                }
58            }
59        }
60        _ => {
61            println!("Agent: {}", state.agent_name);
62            println!("Project: {} ({})", state.project_name, state.project_id);
63            println!("Target: {}", state.target);
64            println!("Template: {}", state.template_name);
65            println!(
66                "Deployed: {}",
67                state.deployed_at.format("%Y-%m-%d %H:%M:%S UTC")
68            );
69            println!();
70
71            match live_status {
72                Ok(services) => {
73                    let rows: Vec<ServiceRow> = services
74                        .iter()
75                        .map(|(name, svc)| ServiceRow {
76                            name: name.clone(),
77                            status: svc.status.clone(),
78                            url: svc.url.clone().unwrap_or_else(|| "(internal)".to_string()),
79                            service_id: svc.service_id.clone(),
80                        })
81                        .collect();
82
83                    println!("{}", Table::new(rows));
84                }
85                Err(e) => {
86                    eprintln!("Warning: could not fetch live status: {e}");
87                    eprintln!("Showing last known state:");
88                    println!();
89
90                    let rows: Vec<ServiceRow> = state
91                        .services
92                        .iter()
93                        .map(|(name, svc)| ServiceRow {
94                            name: name.clone(),
95                            status: svc.status.clone(),
96                            url: svc.url.clone().unwrap_or_else(|| "(internal)".to_string()),
97                            service_id: svc.service_id.clone(),
98                        })
99                        .collect();
100
101                    println!("{}", Table::new(rows));
102                }
103            }
104        }
105    }
106
107    Ok(())
108}