-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathlifecycle.rs
More file actions
97 lines (83 loc) · 3.44 KB
/
Copy pathlifecycle.rs
File metadata and controls
97 lines (83 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use anyhow::{Context, Result};
use crate::app::AppContext;
use crate::services::db::{bootstrap_db_parent, collect_db_path_health, DbSpec};
use crate::services::default_paths::agent_trace_db_path;
use crate::services::lifecycle::{
FixOutcome, FixResultRecord, HealthCategory, HealthFixability, HealthProblem,
HealthProblemKind, HealthSeverity, LifecycleProviderId, ServiceLifecycle, SetupOutcome,
};
use super::{AgentTraceDb, AgentTraceDbSpec};
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct AgentTraceDbLifecycle;
impl ServiceLifecycle for AgentTraceDbLifecycle {
fn id(&self) -> LifecycleProviderId {
LifecycleProviderId::AgentTraceDb
}
fn diagnose(&self, _ctx: &AppContext) -> Vec<HealthProblem> {
diagnose_agent_trace_db_health()
}
fn fix(&self, _ctx: &AppContext, problems: &[HealthProblem]) -> Vec<FixResultRecord> {
let should_bootstrap_parent = problems.iter().any(|problem| {
problem.category == HealthCategory::GlobalState
&& problem.fixability == HealthFixability::AutoFixable
});
if !should_bootstrap_parent {
return Vec::new();
}
match bootstrap_agent_trace_db_parent() {
Ok(parent) => vec![FixResultRecord {
category: HealthCategory::GlobalState,
outcome: FixOutcome::Fixed,
detail: format!(
"Agent trace DB parent directory bootstrapped at '{}'.",
parent.display()
),
}],
Err(error) => vec![FixResultRecord {
category: HealthCategory::GlobalState,
outcome: FixOutcome::Failed,
detail: format!(
"Automatic agent trace DB parent directory bootstrap failed: {error}"
),
}],
}
}
fn setup(&self, _ctx: &AppContext) -> Result<SetupOutcome> {
let db = AgentTraceDb::new()
.context("Agent trace DB lifecycle setup failed while initializing agent trace DB")?;
if db.is_sync_mode() {
if let Err(e) = db.pull() {
tracing::warn!("Agent trace DB initial sync pull failed (setup continues): {e}");
}
}
Ok(SetupOutcome::default())
}
}
pub fn diagnose_agent_trace_db_health() -> Vec<HealthProblem> {
let mut problems = Vec::new();
let db_path = match agent_trace_db_path() {
Ok(path) => path,
Err(error) => {
problems.push(HealthProblem {
kind: HealthProblemKind::UnableToResolveStateRoot,
category: HealthCategory::GlobalState,
severity: HealthSeverity::Error,
fixability: HealthFixability::ManualOnly,
summary: format!("Unable to resolve expected agent trace DB path: {error}"),
remediation: String::from("Verify that the current platform exposes a writable SCE state directory before rerunning 'sce doctor'."),
next_action: "manual_steps",
});
return problems;
}
};
collect_db_path_health(
<AgentTraceDbSpec as DbSpec>::db_name(),
&db_path,
&mut problems,
);
problems
}
fn bootstrap_agent_trace_db_parent() -> Result<std::path::PathBuf> {
let db_path = agent_trace_db_path().context("failed to resolve agent trace DB path")?;
bootstrap_db_parent(<AgentTraceDbSpec as DbSpec>::db_name(), &db_path)
}