//! `local-view` staging block executor. //! //! Some checkpoints stream a large side table at every token (the DSV4.1 //! Engram tables read ~1 MB of rows per token). Serving those rows from the //! shared NAS costs an order of magnitude more than from local NVMe, while the //! bulk of the weights belongs on shared storage. A `local-view` block //! materializes, per launch node, a directory holding **real copies** of the //! files matching `local` and symlinks (into the shared cache's container //! path) for everything else; `serve` mounts it and points `model` at it. //! //! The node-side work is `scripts/local_view.py`; this module only builds the //! command lines, decides the container mount and computes the bytes a node //! must have free (used by the pre-start free-space check). use crate::config::{Config, Node, Staging, expand_tilde}; use crate::ssh::{run_ssh_long_running, upload_script}; use anyhow::{Result, bail}; use std::path::Path; use tracing::info; pub const SCRIPT_BODY: &str = include_str!("scripts/local_view.py"); /// Container-side path the view is mounted at (the model references it). pub const CONTAINER_ROOT: &str = "/root/.cache/hf-view"; fn script_path(id: &str) -> String { format!("/tmp/sm121-local-view-{id}.py") } /// The repo a block views: explicit `repo`, else the recipe's model. pub fn repo_for(block: &Staging, model: &str) -> String { block.repo.clone().unwrap_or_else(|| model.to_string()) } /// Node-side view directory (tilde-expanded). pub fn dst_for(block: &Staging, id: &str, ssh_user: &str) -> String { block .dst .as_deref() .map(|d| expand_tilde(d, ssh_user)) .unwrap_or_else(|| format!("~/.cache/hf-view/{id}")) } /// `measure` (bytes a node needs) or `apply` (build the view). pub struct ViewSpec<'a> { pub repo: &'a str, pub local: &'a [String], pub verify: &'a str, pub min_free: Option<&'a str>, pub force: bool, } /// Command line for `python3