瀏覽代碼

web: flare groups fold into the controller node only (split helpers to stay under the line cap)

Alexander Korolev 13 小時之前
父節點
當前提交
5eaec401fd
共有 6 個文件被更改,包括 49 次插入 和 33 次删除
  1. 1 0
      src/config.rs
  2. 19 0
      src/config/hf_cache.rs
  3. 0 28
      src/config/types.rs
  4. 25 0
      src/web/flare_nodes.rs
  5. 1 0
      src/web/mod.rs
  6. 3 5
      src/web/probe.rs

+ 1 - 0
src/config.rs

@@ -56,6 +56,7 @@ mod staging;
 pub use staging::{Staging, StagingFormat, StagingKind, StagingVerify};
 mod types;
 pub use types::*;
+mod hf_cache;
 
 impl Node {
     /// Host IP for engine exports; falls back to `ssh_ip` when `ib_ip` unset

+ 19 - 0
src/config/hf_cache.rs

@@ -0,0 +1,19 @@
+//! Host-side HF cache resolution.
+
+use super::types::Config;
+
+impl Config {
+    /// Host-side HF cache dir (config `hf_cache_dir`, else the ssh user's
+    /// `~/.cache/huggingface`).
+    pub fn resolved_hf_cache_dir(&self) -> std::path::PathBuf {
+        if let Some(ref dir) = self.hf_cache_dir {
+            return std::path::PathBuf::from(dir);
+        }
+        let home = if self.ssh_user == "root" {
+            "/root".to_string()
+        } else {
+            format!("/home/{}", self.ssh_user)
+        };
+        std::path::PathBuf::from(format!("{home}/.cache/huggingface"))
+    }
+}

+ 0 - 28
src/config/types.rs

@@ -274,34 +274,6 @@ pub struct ComposedFile {
     pub content: String,
 }
 
-impl Config {
-    /// The node that runs `flare orbit` (the `[flare].controller_node` when
-    /// set, else the first cluster's rank-0 node).
-    pub fn flake_controller_node(&self) -> Option<&Node> {
-        let want = self.flare.as_ref().and_then(|f| f.controller_node.clone());
-        let all = self.clusters.iter().flat_map(|c| c.nodes.iter());
-        match want {
-            Some(name) => all.clone().find(|n| n.name == name),
-            None => all
-                .clone()
-                .find(|n| n.rank == 0)
-                .or_else(|| all.into_iter().next()),
-        }
-    }
-
-    pub fn resolved_hf_cache_dir(&self) -> std::path::PathBuf {
-        if let Some(ref dir) = self.hf_cache_dir {
-            return std::path::PathBuf::from(dir);
-        }
-        let home = if self.ssh_user == "root" {
-            "/root".to_string()
-        } else {
-            format!("/home/{}", self.ssh_user)
-        };
-        std::path::PathBuf::from(format!("{home}/.cache/huggingface"))
-    }
-}
-
 /// A recipe-level extra bind-mount for `docker run`.
 ///
 /// Two mutually exclusive kinds:

+ 25 - 0
src/web/flare_nodes.rs

@@ -0,0 +1,25 @@
+//! Which of our nodes runs the `flare orbit` CLI.
+//!
+//! The orbit cluster is FLARE's own naming (`gx10-dgx5`…), so the controller
+//! is configured explicitly (`[flare].controller_node = "dgx5.lan"`); without
+//! it we fall back to the first cluster's rank-0 node — right for a single
+//! cluster, wrong for a multi-cluster config, which is why the explicit field
+//! exists.
+
+use crate::config::{Config, Node};
+
+/// The node that runs `flare orbit`.
+pub fn controller_node(config: &Config) -> Option<&Node> {
+    let want = config
+        .flare
+        .as_ref()
+        .and_then(|f| f.controller_node.clone());
+    let all = config.clusters.iter().flat_map(|c| c.nodes.iter());
+    match want {
+        Some(name) => all.clone().find(|n| n.name == name),
+        None => all
+            .clone()
+            .find(|n| n.rank == 0)
+            .or_else(|| all.into_iter().next()),
+    }
+}

+ 1 - 0
src/web/mod.rs

@@ -10,6 +10,7 @@
 
 mod api;
 pub mod events;
+pub(crate) mod flare_nodes;
 pub mod jobs;
 pub mod logs;
 pub mod model_settings;

+ 3 - 5
src/web/probe.rs

@@ -177,7 +177,7 @@ pub async fn flare_groups(config: &crate::config::Config) -> Vec<(String, Option
         .orbit_cluster
         .clone()
         .unwrap_or_else(|| "sparks".to_string());
-    let Some(controller) = config.flake_controller_node() else {
+    let Some(controller) = crate::web::flare_nodes::controller_node(config) else {
         return Vec::new();
     };
     let cmd = format!("{binary} orbit status --cluster {orbit_cluster} 2>/dev/null");
@@ -288,8 +288,7 @@ pub async fn probe(config: &Config) -> Fleet {
         .clusters
         .iter()
         .find(|c| {
-            config
-                .flake_controller_node()
+            crate::web::flare_nodes::controller_node(config)
                 .is_some_and(|n| c.nodes.iter().any(|x| x.name == n.name))
         })
         .map(|c| c.name.clone())
@@ -315,8 +314,7 @@ pub async fn probe(config: &Config) -> Fleet {
                 // Only the controller node hosts the orbit groups (the fold
                 // below runs per node — without this guard every node would
                 // report the same group).
-                let is_controller = config
-                    .flake_controller_node()
+                let is_controller = crate::web::flare_nodes::controller_node(config)
                     .is_some_and(|c| c.ssh_ip == *node_ip_of(config, &name));
                 for (group, created) in flare.iter().filter(|_| is_controller) {
                     containers.push(ContainerSnap {