Install sled binary in huskies-owned dir so upgrades work without root

/opt/huskies/bin/huskies (chowned to the huskies user) with a symlink
from /usr/local/bin/huskies. Atomic replace needs write permission on
the directory for the tmp-write + rename, which root-owned
/usr/local/bin can't provide to the server process.

resolve_target_path() now prefers /opt/huskies/bin/huskies over
current_exe(), which can point at a stale location (e.g.
/workspace/target/release/huskies after a historical in-container
rebuild) that the entrypoint would never launch after a restart.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fHdm92yjvguPi2LiXfLB9
This commit is contained in:
Timmy
2026-07-15 16:06:31 +01:00
co-authored by Claude Fable 5
parent a1ae532c6e
commit 4d22171d16
2 changed files with 23 additions and 3 deletions
+15 -2
View File
@@ -94,9 +94,22 @@ pub async fn run_cli_upgrade(source_url: &str, target: &Path) -> Result<(), Stri
// ── Helpers ───────────────────────────────────────────────────────────────
/// Resolve the path to replace: `current_exe()` if accessible, else
/// `/usr/local/bin/huskies`.
/// Resolve the path to replace with the new binary.
///
/// Inside project containers the binary is installed at
/// `/opt/huskies/bin/huskies` (a huskies-owned directory, so the atomic
/// tmp-write + rename works without root) and `/usr/local/bin/huskies` is a
/// symlink to it. That path is preferred over `current_exe()` because
/// `current_exe()` can point at a stale location — e.g.
/// `/workspace/target/release/huskies` after a historical in-container
/// rebuild — which the entrypoint would never launch after a restart.
///
/// Outside containers (no `/opt/huskies`), falls back to `current_exe()`.
pub fn resolve_target_path() -> PathBuf {
let container_path = PathBuf::from("/opt/huskies/bin/huskies");
if container_path.exists() {
return container_path;
}
std::env::current_exe().unwrap_or_else(|_| PathBuf::from("/usr/local/bin/huskies"))
}