deploy.sh: probe sudo with -n true, not -n -v (validate ignores NOPASSWD)

Follow-up to bb71c9f. `sudo -n -v` also fails on NOPASSWD users because
`sudo -v` demands a credential *timestamp* and NOPASSWD never produces
one (verified on Ubuntu 24.04 sudo 1.9.x: `sudo -n true` returns 0 while
`sudo -n -v` returns 1 with "a password is required").

Replace the probe with `sudo -n true`. When it fails, additionally
require a TTY for the interactive fallback -- previously we would fall
through to `sudo -v` on a TTY-less run and die with a confusing
"authentication failed" instead of a clear message about the missing
NOPASSWD entry.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
sam 2026-07-20 23:29:27 -07:00
parent bb71c9f6fd
commit 745f066dfd

View File

@ -426,18 +426,23 @@ fi
# Prime sudo early if filesystem setup will need it, so the password prompt
# happens HERE (visible, at the start) instead of blocking mid-provision.
# `sudo -v` alone ALWAYS attempts interactive validation -- it does not
# consult NOPASSWD -- so it fails without a TTY (cloud-init, ansible without
# a pty, unattended CI). Try `-n -v` first: on a NOPASSWD user it succeeds
# silently; otherwise we fall through to the interactive prompt for humans.
#
# `sudo -v` (and even `sudo -n -v`) demands a credential *timestamp*, which
# NOPASSWD entries never produce -- so both fail on cloud-init / CI even
# when the user has NOPASSWD:ALL. Probe with `sudo -n true` instead: it
# runs a real command through NOPASSWD when available and returns cleanly.
# If that fails AND there is no TTY, refuse loudly rather than hanging or
# dying with a confusing "authentication failed".
_dr_probe="$(get_env OBMP_DATA_ROOT)"; _dr_probe="${_dr_probe:-/var/openbmp}"
if [ ! -w "$(dirname "$_dr_probe")" ] || { [ -d "$_dr_probe" ] && [ ! -w "$_dr_probe" ]; }; then
if [ "$(id -u)" -ne 0 ]; then
if sudo -n -v 2>/dev/null; then
if sudo -n true 2>/dev/null; then
log "Filesystem setup under $_dr_probe needs sudo - passwordless sudo OK."
else
elif [ -t 0 ]; then
log "Filesystem setup under $_dr_probe needs sudo - authenticating now."
sudo -v || die "sudo authentication failed"
else
die "sudo required for $_dr_probe but no TTY and no NOPASSWD entry for $(id -un). Grant NOPASSWD (see docs) or run interactively."
fi
fi
fi