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:
@@ -33,7 +33,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Copy the huskies binary and entrypoint from the main image.
|
# Copy the huskies binary and entrypoint from the main image.
|
||||||
COPY --from=huskies-src /usr/local/bin/huskies /usr/local/bin/huskies
|
# The binary lives in /opt/huskies/bin (chowned to the huskies user below) so
|
||||||
|
# the in-process upgrade path (`POST /api/upgrade`) can atomically replace it
|
||||||
|
# without root: rename() needs write permission on the *directory*, not just
|
||||||
|
# the file. /usr/local/bin/huskies stays a symlink so PATH resolution and the
|
||||||
|
# entrypoint CMD are unchanged.
|
||||||
|
COPY --from=huskies-src /usr/local/bin/huskies /opt/huskies/bin/huskies
|
||||||
COPY --from=huskies-src /usr/local/bin/entrypoint.sh /usr/local/bin/entrypoint.sh
|
COPY --from=huskies-src /usr/local/bin/entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
# Non-root user — Claude Code refuses --dangerously-skip-permissions as root.
|
# Non-root user — Claude Code refuses --dangerously-skip-permissions as root.
|
||||||
@@ -44,6 +49,8 @@ RUN groupadd -r huskies \
|
|||||||
&& mkdir -p /home/huskies/.ssh \
|
&& mkdir -p /home/huskies/.ssh \
|
||||||
&& chmod 700 /home/huskies/.ssh \
|
&& chmod 700 /home/huskies/.ssh \
|
||||||
&& chown -R huskies:huskies /home/huskies \
|
&& chown -R huskies:huskies /home/huskies \
|
||||||
|
&& chown -R huskies:huskies /opt/huskies \
|
||||||
|
&& ln -s /opt/huskies/bin/huskies /usr/local/bin/huskies \
|
||||||
&& mkdir -p /workspace \
|
&& mkdir -p /workspace \
|
||||||
&& chown huskies:huskies /workspace \
|
&& chown huskies:huskies /workspace \
|
||||||
&& git config --global init.defaultBranch master \
|
&& git config --global init.defaultBranch master \
|
||||||
|
|||||||
+15
-2
@@ -94,9 +94,22 @@ pub async fn run_cli_upgrade(source_url: &str, target: &Path) -> Result<(), Stri
|
|||||||
|
|
||||||
// ── Helpers ───────────────────────────────────────────────────────────────
|
// ── Helpers ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
/// Resolve the path to replace: `current_exe()` if accessible, else
|
/// Resolve the path to replace with the new binary.
|
||||||
/// `/usr/local/bin/huskies`.
|
///
|
||||||
|
/// 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 {
|
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"))
|
std::env::current_exe().unwrap_or_else(|_| PathBuf::from("/usr/local/bin/huskies"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user