Quellcode durchsuchen

cache doctor: find the tools where they actually live

A non-login shell has a bare PATH, so hfrs (~/.cargo/bin), uvx/hf (~/.local/bin)
and our FLARE head binary (~/flare-bin/flare) all looked MISSING. The probe now
prepends those dirs and prefers ~/flare-bin/flare over an apt-installed flare.

hfrs 0.0.1 is now installed on all eight nodes (built once on dgx5, copied), so
the update/prune path can run through the cluster — no NAS mount needed on the
machine that drives it (the HA add-on has none).
Alexander Korolev vor 1 Tag
Ursprung
Commit
67b088c4f9
3 geänderte Dateien mit 45 neuen und 41 gelöschten Zeilen
  1. 5 1
      src/cache.rs
  2. 39 0
      src/config/flare_cluster.rs
  3. 1 40
      src/config/types.rs

+ 5 - 1
src/cache.rs

@@ -142,7 +142,11 @@ pub async fn doctor(config: &Config, opts: &CacheOpts) -> Result<()> {
     let node = cache_node(config, opts.cluster.as_deref())?;
     let home = hf_home(config);
     let cmd = format!(
-        "for t in hfrs uvx flare hf; do printf '%s=%s\\n' \"$t\" \"$(command -v $t || echo MISSING)\"; done; \
+        // A non-login shell has a bare PATH: also look where the tools land.
+        "PATH=\"$HOME/.local/bin:$HOME/.cargo/bin:$PATH\"; \
+         for t in hfrs uvx hf; do printf '%s=%s\\n' \"$t\" \"$(command -v $t || echo MISSING)\"; done; \
+         if [ -x \"$HOME/flare-bin/flare\" ]; then echo \"flare=$HOME/flare-bin/flare\"; \
+         elif command -v flare >/dev/null; then echo \"flare=$(command -v flare)\"; else echo flare=MISSING; fi; \
          [ -d {root} ] && echo \"hf_home=ok\" || echo \"hf_home=MISSING\"; \
          touch {root}/.sm121-write-test 2>/dev/null && echo write=ok && rm -f {root}/.sm121-write-test || echo write=FAILED; \
          df -BG --output=avail {root} 2>/dev/null | tail -1 | sed 's/^/free=/'",

+ 39 - 0
src/config/flare_cluster.rs

@@ -19,3 +19,42 @@ pub struct FlareCluster {
     #[serde(default)]
     pub local_dir: Option<String>,
 }
+
+/// `[flare]` in the private config: how the launcher talks to FLARE.
+#[derive(Clone, Debug, Default, serde::Deserialize)]
+pub struct FlareSettings {
+    /// Publisher acceptance key (`--dangerously-approve-key`). A FLARE package
+    /// is signed; accepting the publisher is a trust decision, so it lives
+    /// here, never in the recipe.
+    #[serde(default)]
+    pub accept_key: Option<String>,
+    /// `--dangerously-accept-publisher` value (e.g. `local-development`).
+    #[serde(default)]
+    pub accept_publisher: Option<String>,
+    /// `flare` binary path (default: from PATH).
+    #[serde(default)]
+    pub binary: Option<String>,
+    /// The node that runs the `flare orbit` CLI (our name, e.g. `dgx5.lan`).
+    /// Defaults to the first cluster's rank-0 node, which is wrong on a
+    /// multi-cluster config (the recipes panel then sees no FLARE groups).
+    #[serde(default)]
+    pub controller_node: Option<String>,
+    /// Per-cluster FLARE settings, keyed by OUR cluster name (`dgx58-switch`,
+    /// `prod4`). This is the translation layer: the same launcher config then
+    /// serves FLARE on any cluster, with the right orbit cluster name, node
+    /// list and local package dir — instead of one flat block that only fits
+    /// the machine it was written for.
+    #[serde(default)]
+    pub clusters: std::collections::HashMap<String, super::flare_cluster::FlareCluster>,
+    /// Local package mirror dir on the controller (see `native::flare`).
+    #[serde(default)]
+    pub local_dir: Option<String>,
+    /// `[cluster.<name>]` in `~/.config/flare/orbit.toml` (default `sparks`).
+    #[serde(default)]
+    pub orbit_cluster: Option<String>,
+    /// Orbit node names in cluster rank order (our `dgx5.lan` → their
+    /// `spark1`). Empty = the cluster's own node names, which works when the
+    /// orbit cluster was paired under the same names.
+    #[serde(default)]
+    pub orbit_nodes: Vec<String>,
+}

+ 1 - 40
src/config/types.rs

@@ -80,7 +80,7 @@ pub struct Config {
     /// FLARE deploy settings (private: the publisher acceptance key must never
     /// reach the shared recipe repo).
     #[serde(default)]
-    pub flare: Option<FlareSettings>,
+    pub flare: Option<super::flare_cluster::FlareSettings>,
     #[serde(default)]
     pub global_mods_dir: Option<std::path::PathBuf>,
     /// Drop page cache before starting containers.
@@ -460,42 +460,3 @@ mod tests {
         assert!(r.is_err());
     }
 }
-
-/// `[flare]` in the private config: how the launcher talks to FLARE.
-#[derive(Clone, Debug, Default, serde::Deserialize)]
-pub struct FlareSettings {
-    /// Publisher acceptance key (`--dangerously-approve-key`). A FLARE package
-    /// is signed; accepting the publisher is a trust decision, so it lives
-    /// here, never in the recipe.
-    #[serde(default)]
-    pub accept_key: Option<String>,
-    /// `--dangerously-accept-publisher` value (e.g. `local-development`).
-    #[serde(default)]
-    pub accept_publisher: Option<String>,
-    /// `flare` binary path (default: from PATH).
-    #[serde(default)]
-    pub binary: Option<String>,
-    /// The node that runs the `flare orbit` CLI (our name, e.g. `dgx5.lan`).
-    /// Defaults to the first cluster's rank-0 node, which is wrong on a
-    /// multi-cluster config (the recipes panel then sees no FLARE groups).
-    #[serde(default)]
-    pub controller_node: Option<String>,
-    /// Per-cluster FLARE settings, keyed by OUR cluster name (`dgx58-switch`,
-    /// `prod4`). This is the translation layer: the same launcher config then
-    /// serves FLARE on any cluster, with the right orbit cluster name, node
-    /// list and local package dir — instead of one flat block that only fits
-    /// the machine it was written for.
-    #[serde(default)]
-    pub clusters: std::collections::HashMap<String, super::flare_cluster::FlareCluster>,
-    /// Local package mirror dir on the controller (see `native::flare`).
-    #[serde(default)]
-    pub local_dir: Option<String>,
-    /// `[cluster.<name>]` in `~/.config/flare/orbit.toml` (default `sparks`).
-    #[serde(default)]
-    pub orbit_cluster: Option<String>,
-    /// Orbit node names in cluster rank order (our `dgx5.lan` → their
-    /// `spark1`). Empty = the cluster's own node names, which works when the
-    /// orbit cluster was paired under the same names.
-    #[serde(default)]
-    pub orbit_nodes: Vec<String>,
-}