fix(doctor): survive a PATH entry the user can't execute
prd-number-check / require-numbered-prds (pull_request) Successful in 10s
lint / lint (push) Successful in 57s
tracker-policy-pr / check-pr (pull_request) Failing after 14m34s
test / coverage (pull_request) Blocked by required conditions
test / integration-docker (pull_request) Blocked by required conditions
test / unit (pull_request) Has started running
test / image-input-builds (pull_request) Has started running
prd-number-check / require-numbered-prds (pull_request) Successful in 10s
lint / lint (push) Successful in 57s
tracker-policy-pr / check-pr (pull_request) Failing after 14m34s
test / coverage (pull_request) Blocked by required conditions
test / integration-docker (pull_request) Blocked by required conditions
test / unit (pull_request) Has started running
test / image-input-builds (pull_request) Has started running
The install itself now works end to end on a fresh macOS account — venv built,
package installed from git, entry point linked — and `doctor` then died with an
unhandled traceback:
PermissionError: [Errno 13] Permission denied: 'ip'
netpool's probe helpers caught only FileNotFoundError. That is not the only way
a probe binary can be unavailable: when a name on PATH exists but this user
cannot execute it, exec fails with EACCES, and CPython reports that in
preference to the ENOENT from the other PATH entries. So `except
FileNotFoundError` misses it and the crash propagates all the way out of
`doctor`. Reproduced directly: a mode-000 file named `ip` on PATH yields
exactly the error above.
_run_ok's docstring already stated the intent — treat an unavailable binary as
failure rather than crashing — so this widens the catch to OSError to match
what it says. Any OSError means the probe could not run, which for a
fail-closed check is indistinguishable from "not present". The same narrow
catch is fixed in overlapping_routes and in the two docker probes
(compose ls, docker ps), which are the same shape and equally reachable.
Deliberately not touched: the FileNotFoundError catches around file I/O in
bottle_state and orchestrator/service, where the narrow exception is correct.
The harness also required `bot-bottle` on PATH before running doctor, which
could never be true: install.sh prints the PATH line rather than editing a
shell profile, by design, so on a fresh account the entry point is installed
and working but not on PATH. It now looks where the installer actually puts
it (~/.local/bin, then the venv) and notes when it's running by absolute path.
That was the harness failing a run for a reason the installer intends.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WEfZZhakx13bxTfXcZCoS5
This commit is contained in:
@@ -89,14 +89,28 @@ user_exists() { dscl . -read "/Users/$USER_NAME" >/dev/null 2>&1; }
|
||||
# Run a shell snippet as the throwaway user in a fresh login shell.
|
||||
run_as_user() { sudo -u "$USER_NAME" -i sh -c "$1"; }
|
||||
|
||||
# `bot-bottle doctor` as the throwaway user. Non-zero when the entry point
|
||||
# never made it onto that user's PATH, or when doctor itself is unhappy.
|
||||
# `bot-bottle doctor` as the throwaway user. Non-zero when no entry point was
|
||||
# installed at all, or when doctor itself is unhappy.
|
||||
#
|
||||
# Deliberately does NOT require `bot-bottle` on PATH: install.sh prints the
|
||||
# PATH line rather than editing a shell profile, so on a fresh account the
|
||||
# entry point is installed and working but not on PATH. Demanding PATH here
|
||||
# would fail every run for a reason the installer intends.
|
||||
doctor_as_user() {
|
||||
if ! run_as_user 'command -v bot-bottle >/dev/null 2>&1'; then
|
||||
echo " bot-bottle is not on PATH for $USER_NAME"
|
||||
return 1
|
||||
fi
|
||||
run_as_user 'bot-bottle doctor'
|
||||
# shellcheck disable=SC2016 # $HOME/$bb must expand in the *target* user's
|
||||
# shell, not in this one — that's the whole point of the single quotes.
|
||||
run_as_user '
|
||||
for bb in "$HOME/.local/bin/bot-bottle" "$HOME/.bot-bottle/venv/bin/bot-bottle"; do
|
||||
if [ -x "$bb" ]; then
|
||||
command -v bot-bottle >/dev/null 2>&1 \
|
||||
|| echo " (not on PATH — running $bb directly, as install.sh advises)"
|
||||
exec "$bb" doctor
|
||||
fi
|
||||
done
|
||||
command -v bot-bottle >/dev/null 2>&1 && exec bot-bottle doctor
|
||||
echo " no bot-bottle entry point found for this user" >&2
|
||||
exit 1
|
||||
'
|
||||
}
|
||||
|
||||
# --- commands --------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user