|
@@ -42,9 +42,16 @@ pub async fn doctor(
|
|
|
dry_run: bool,
|
|
dry_run: bool,
|
|
|
) -> Result<()> {
|
|
) -> Result<()> {
|
|
|
let recipe = load_recipe(recipe_name).await?;
|
|
let recipe = load_recipe(recipe_name).await?;
|
|
|
|
|
+ let dn = recipe.name.clone();
|
|
|
|
|
+ let de = recipe.engine.clone();
|
|
|
|
|
+ let db = recipe.distributed_backend.clone();
|
|
|
println!(
|
|
println!(
|
|
|
- "\n🩺 Doctor: {} ({}) [backend: {}]",
|
|
|
|
|
- recipe.name, recipe.engine, recipe.distributed_backend
|
|
|
|
|
|
|
+ "{}",
|
|
|
|
|
+ fluent_i18n::t!("doctor-header", {
|
|
|
|
|
+ "name" => dn,
|
|
|
|
|
+ "engine" => de,
|
|
|
|
|
+ "backend" => db,
|
|
|
|
|
+ })
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
let (cluster, _nccl) = resolve_cluster(config, &recipe, cluster_name)?;
|
|
let (cluster, _nccl) = resolve_cluster(config, &recipe, cluster_name)?;
|
|
@@ -72,7 +79,10 @@ pub async fn doctor(
|
|
|
// Print results
|
|
// Print results
|
|
|
let mut has_failures = false;
|
|
let mut has_failures = false;
|
|
|
for result in &all_results {
|
|
for result in &all_results {
|
|
|
- println!("\n--- {} ---", result.node_name);
|
|
|
|
|
|
|
+ println!(
|
|
|
|
|
+ "{}",
|
|
|
|
|
+ fluent_i18n::t!("doctor-node-section", { "name" => &result.node_name })
|
|
|
|
|
+ );
|
|
|
for check in &result.checks {
|
|
for check in &result.checks {
|
|
|
println!(" {} {} {}", check.status, check.name, check.detail);
|
|
println!(" {} {} {}", check.status, check.name, check.detail);
|
|
|
if check.status == DoctorStatus::Fail {
|
|
if check.status == DoctorStatus::Fail {
|
|
@@ -83,15 +93,18 @@ pub async fn doctor(
|
|
|
|
|
|
|
|
if has_failures {
|
|
if has_failures {
|
|
|
if repair {
|
|
if repair {
|
|
|
- println!("\n🔧 Repairing image...");
|
|
|
|
|
|
|
+ println!("{}", fluent_i18n::t!("doctor-repairing"));
|
|
|
let repaired = run_cluster_repair(config, &cluster, &recipe, dry_run).await?;
|
|
let repaired = run_cluster_repair(config, &cluster, &recipe, dry_run).await?;
|
|
|
- println!("✅ Repaired image: {}", repaired);
|
|
|
|
|
|
|
+ println!(
|
|
|
|
|
+ "{}",
|
|
|
|
|
+ fluent_i18n::t!("doctor-repaired", { "tag" => &repaired })
|
|
|
|
|
+ );
|
|
|
} else {
|
|
} else {
|
|
|
- println!("\n⚠ Some checks failed. Run with --repair to auto-fix.");
|
|
|
|
|
|
|
+ println!("{}", fluent_i18n::t!("doctor-checks-failed"));
|
|
|
std::process::exit(1);
|
|
std::process::exit(1);
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- println!("\n✅ All checks passed!");
|
|
|
|
|
|
|
+ println!("{}", fluent_i18n::t!("doctor-all-passed"));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
@@ -249,9 +262,14 @@ async fn run_cluster_repair(
|
|
|
.context("Failed to build repaired image")?;
|
|
.context("Failed to build repaired image")?;
|
|
|
println!("Build output: {}", output.lines().last().unwrap_or(&output));
|
|
println!("Build output: {}", output.lines().last().unwrap_or(&output));
|
|
|
} else {
|
|
} else {
|
|
|
|
|
+ let dtag = repaired_tag.clone();
|
|
|
|
|
+ let dnode = head_node.name.clone();
|
|
|
println!(
|
|
println!(
|
|
|
- " (dry-run) Would build {} on {}",
|
|
|
|
|
- repaired_tag, head_node.name
|
|
|
|
|
|
|
+ "{}",
|
|
|
|
|
+ fluent_i18n::t!("doctor-dry-build", {
|
|
|
|
|
+ "tag" => dtag,
|
|
|
|
|
+ "node" => dnode,
|
|
|
|
|
+ })
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
|
|
|