|
@@ -19,7 +19,7 @@ use crate::home_assistant::Client as HaClient;
|
|
|
pub mod plug;
|
|
pub mod plug;
|
|
|
pub mod toggle;
|
|
pub mod toggle;
|
|
|
pub use plug::{OnAction, decide_on, stale_nodes};
|
|
pub use plug::{OnAction, decide_on, stale_nodes};
|
|
|
-use toggle::{call, extra_ids, toggle_entities, toggle_one};
|
|
|
|
|
|
|
+use toggle::{call, extra_ids, off_extras, toggle_entities, toggle_one};
|
|
|
mod mikro;
|
|
mod mikro;
|
|
|
|
|
|
|
|
/// Flow for `power off`: SSH shutdown + wait + HA `turn_off`.
|
|
/// Flow for `power off`: SSH shutdown + wait + HA `turn_off`.
|
|
@@ -31,9 +31,25 @@ pub async fn power_off(
|
|
|
) -> Result<()> {
|
|
) -> Result<()> {
|
|
|
let targets = select_targets(cluster, node_names, "power off")?;
|
|
let targets = select_targets(cluster, node_names, "power off")?;
|
|
|
|
|
|
|
|
|
|
+ // Cluster-level extras (the fabric switch, a cooling fan) are SHARED by
|
|
|
|
|
+ // every node in the cluster. Powering off a SUBSET (`--node`) must not
|
|
|
|
|
+ // take the fabric down for the nodes that stay up — that wedges live
|
|
|
|
|
+ // multi-node serves (NCCL over the switch dies). So extras are toggled
|
|
|
|
|
+ // off only for a whole-cluster power off (no `--node`).
|
|
|
|
|
+ let extras = off_extras(cluster, node_names);
|
|
|
|
|
+ if !node_names.is_empty() && !cluster.extra_entities.is_empty() {
|
|
|
|
|
+ info!(
|
|
|
|
|
+ "{}",
|
|
|
|
|
+ fluent_i18n::t!("power-off-extras-skipped", {
|
|
|
|
|
+ "nodes" => node_names.join(", "),
|
|
|
|
|
+ "extras" => extra_ids(cluster).join(", ")
|
|
|
|
|
+ })
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if dry_run {
|
|
if dry_run {
|
|
|
warn!("{}", fluent_i18n::t!("power-off-dryrun"));
|
|
warn!("{}", fluent_i18n::t!("power-off-dryrun"));
|
|
|
- mikro::dry_off(config, &targets, &extra_ids(cluster));
|
|
|
|
|
|
|
+ mikro::dry_off(config, &targets, &extras);
|
|
|
return Ok(());
|
|
return Ok(());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -92,14 +108,14 @@ pub async fn power_off(
|
|
|
"turn_off",
|
|
"turn_off",
|
|
|
config.mikrotik.as_ref(),
|
|
config.mikrotik.as_ref(),
|
|
|
&targets,
|
|
&targets,
|
|
|
- &extra_ids(cluster),
|
|
|
|
|
|
|
+ &extras,
|
|
|
"cluster",
|
|
"cluster",
|
|
|
)
|
|
)
|
|
|
.await
|
|
.await
|
|
|
} else {
|
|
} else {
|
|
|
info!("{}", fluent_i18n::t!("power-off-no-ha"));
|
|
info!("{}", fluent_i18n::t!("power-off-no-ha"));
|
|
|
// No HA at all — still shut down any mikrotik device referenced.
|
|
// No HA at all — still shut down any mikrotik device referenced.
|
|
|
- mikro::collect_off(config, &targets, &extra_ids(cluster))
|
|
|
|
|
|
|
+ mikro::collect_off(config, &targets, &extras)
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// 4) RouterOS graceful shutdown for each referenced device.
|
|
// 4) RouterOS graceful shutdown for each referenced device.
|