Full Rust implementation of the warpgate NAS cache proxy: - CLI: clap-based with subcommands (run, setup, status, cache, warmup, bwlimit, speed-test, config-init, log) - Config: TOML-based with env var override, preset templates - rclone: VFS mount args builder, config generator, RC API client - Services: Samba config gen, NFS exports, WebDAV serve args, systemd units - Deploy: dependency checker, filesystem validation, one-click setup - Supervisor: single-process tree managing rclone mount + smbd + WebDAV as child processes — no systemd dependency for protocol management Supervisor hardening: - ProtocolChildren Drop impl prevents orphaned processes on startup failure - Early rclone exit detection in mount wait loop (fail fast, not 30s timeout) - Graceful SIGTERM → 3s grace → SIGKILL (prevents orphaned smbd workers) - RestartTracker with 5-min stability reset and linear backoff (2s/4s/6s) - Shutdown signal checked during mount wait and before protocol start Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
46 lines
1.3 KiB
Rust
46 lines
1.3 KiB
Rust
//! `warpgate warmup` — pre-cache a remote directory to local SSD.
|
|
|
|
use std::process::Command;
|
|
|
|
use anyhow::{Context, Result};
|
|
|
|
use crate::config::Config;
|
|
use crate::rclone::config as rclone_config;
|
|
|
|
pub fn run(config: &Config, path: &str, newer_than: Option<&str>) -> Result<()> {
|
|
let remote_src = format!("nas:{}/{}", config.connection.remote_path, path);
|
|
let local_dest = std::env::temp_dir().join("warpgate-warmup");
|
|
|
|
println!("Warming up: {}", remote_src);
|
|
|
|
// Create temp destination for downloaded files
|
|
std::fs::create_dir_all(&local_dest)
|
|
.context("Failed to create temp directory for warmup")?;
|
|
|
|
let mut cmd = Command::new("rclone");
|
|
cmd.arg("copy")
|
|
.arg("--config")
|
|
.arg(rclone_config::RCLONE_CONF_PATH)
|
|
.arg(&remote_src)
|
|
.arg(&local_dest)
|
|
.arg("--no-traverse")
|
|
.arg("--progress");
|
|
|
|
if let Some(age) = newer_than {
|
|
cmd.arg("--max-age").arg(age);
|
|
}
|
|
|
|
println!("Downloading from remote NAS...");
|
|
let status = cmd.status().context("Failed to run rclone copy")?;
|
|
|
|
// Clean up temp directory
|
|
let _ = std::fs::remove_dir_all(&local_dest);
|
|
|
|
if status.success() {
|
|
println!("Warmup complete.");
|
|
Ok(())
|
|
} else {
|
|
anyhow::bail!("rclone copy exited with status {}", status);
|
|
}
|
|
}
|