fix(install): find uv for the .venv owner (root shells and sudo lack ~/.local/bin)
Run as root, SUDO_USER is unset and uv is not on root's PATH, so the training environment was not synced. Now the sync runs as the owner of .venv, with uv from PATH, that user's ~/.local/bin or ~/.cargo/bin, /usr/local/bin, or UV=/path/to/uv.
This commit is contained in:
1 parent
24998b033c
commit
7f29b1831e
1 file changed
+28
-10
+28
-10
@@ -20,9 +20,11 @@
|
||||
# built beforehand as a normal user:
|
||||
# cargo build --release --locked --manifest-path rust/Cargo.toml
|
||||
# (Rust >= 1.88 from rustup, plus pkg-config and libssl-dev)
|
||||
# 4. the Python training environment (.venv, `uv sync --frozen`): in place
|
||||
# as the user running sudo (who pulled and built), otherwise as root;
|
||||
# SKIP_UV=1 skips it
|
||||
# 4. the Python training environment (.venv, `uv sync --frozen`), as the
|
||||
# owner of .venv (in place; else the user running sudo) or as root for a
|
||||
# copy. uv is looked up on PATH and in that user's ~/.local/bin and
|
||||
# ~/.cargo/bin (sudo and root shells often lack them); UV=/path/to/uv
|
||||
# overrides, SKIP_UV=1 skips the step
|
||||
# 5. .env: created from .env.example on a fresh install (edit, then re-run);
|
||||
# WEB_LISTEN and FORECAST_IN_COLLECTOR default to the production values
|
||||
# when absent
|
||||
@@ -104,16 +106,32 @@ log "Installing $BIN -> ${APP_DIR}/bin/ping-collector ($("$BIN" --version))"
|
||||
install -D -m 0755 -o root -g root "$BIN" "${APP_DIR}/bin/ping-collector"
|
||||
|
||||
# 4. Python training environment ------------------------------------------------
|
||||
find_uv() { # user -> path of a uv binary that user can run
|
||||
local home c
|
||||
home="$(getent passwd "$1" | cut -d: -f6)"
|
||||
for c in "${UV:-}" "$(command -v uv 2>/dev/null || true)" "${home}/.local/bin/uv" \
|
||||
"${home}/.cargo/bin/uv" /root/.local/bin/uv /usr/local/bin/uv /usr/bin/uv; do
|
||||
[ -n "$c" ] && [ -x "$c" ] && runuser -u "$1" -- test -x "$c" && {
|
||||
echo "$c"
|
||||
return 0
|
||||
}
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
if [ "${SKIP_UV:-0}" != 1 ]; then
|
||||
uv_user=root # copy mode: handed to the service user below
|
||||
[ "$in_place" = 1 ] && uv_user="${SUDO_USER:-root}"
|
||||
log "Syncing the Python training environment (${APP_DIR}/.venv) as $uv_user"
|
||||
if [ "$uv_user" = root ]; then
|
||||
(cd "$APP_DIR" && uv sync --python 3.11 --frozen) ||
|
||||
warn "uv sync failed: the monthly retrain needs ${APP_DIR}/.venv (uv sync --python 3.11 --frozen)"
|
||||
if [ "$in_place" = 1 ]; then
|
||||
uv_user="${SUDO_USER:-root}"
|
||||
[ -d "${APP_DIR}/.venv" ] && uv_user="$(stat -c %U "${APP_DIR}/.venv")"
|
||||
fi
|
||||
if uv_bin="$(find_uv "$uv_user")"; then
|
||||
log "Syncing the Python training environment (${APP_DIR}/.venv) as $uv_user with $uv_bin"
|
||||
(cd "$APP_DIR" && runuser -u "$uv_user" -- env HOME="$(getent passwd "$uv_user" | cut -d: -f6)" \
|
||||
"$uv_bin" sync --python 3.11 --frozen) ||
|
||||
warn "uv sync failed: the monthly retrain needs ${APP_DIR}/.venv (uv sync --python 3.11 --frozen as $uv_user)"
|
||||
else
|
||||
runuser -u "$uv_user" -- bash -lc "cd '$APP_DIR' && uv sync --python 3.11 --frozen" ||
|
||||
warn "uv sync as $uv_user failed: run 'uv sync --python 3.11 --frozen' in $APP_DIR as the owner of .venv"
|
||||
warn "uv not found for $uv_user (pass UV=/path/to/uv): ${APP_DIR}/.venv not synced"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
Reference in new issue
Block a user