|
@@ -143,6 +143,27 @@ fn resolve_cluster_simple<'c>(
|
|
|
select_cluster(config, cluster_name, recipe.required_nodes, &state)
|
|
select_cluster(config, cluster_name, recipe.required_nodes, &state)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/// Dry-run cluster resolution: treat every configured node as reachable and
|
|
|
|
|
+/// free, then select. Skips all SSH probing/power/pinging so a dry-run works
|
|
|
|
|
+/// even when the cluster is off or unreachable (the whole point of a dry-run
|
|
|
|
|
+/// is to preview the generated command, not to verify hardware).
|
|
|
|
|
+///
|
|
|
|
|
+/// Like [`prepare_cluster`], returns the cluster with **all** its nodes (dry-run
|
|
|
|
|
+/// does not filter for free nodes, since none are actually inspected).
|
|
|
|
|
+pub fn prepare_cluster_dry_run(
|
|
|
|
|
+ config: &Config,
|
|
|
|
|
+ recipe: &Recipe,
|
|
|
|
|
+ cluster_name: &str,
|
|
|
|
|
+ node_name: Option<&str>,
|
|
|
|
|
+) -> Result<(Cluster, NcclConfig)> {
|
|
|
|
|
+ if let Some(nn) = node_name {
|
|
|
|
|
+ let (c, n) = resolve_solo_node(config, nn)?;
|
|
|
|
|
+ return Ok((c, n.clone()));
|
|
|
|
|
+ }
|
|
|
|
|
+ let (c, n) = resolve_cluster_simple(config, recipe, cluster_name)?;
|
|
|
|
|
+ Ok((c.clone(), n.clone()))
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/// Does the state contain any unreachable nodes?
|
|
/// Does the state contain any unreachable nodes?
|
|
|
fn state_has_unreachable(state: &ClusterState, config: &Config) -> bool {
|
|
fn state_has_unreachable(state: &ClusterState, config: &Config) -> bool {
|
|
|
for cluster in &config.clusters {
|
|
for cluster in &config.clusters {
|