tell the operator they are still root, once

Neither script ever becomes the user it sets the machine up for — a process cannot
change its own uid, so both run as root and drop privileges per command instead.
Everything Officer owns ends up belonging to that user and every pm2 process runs
as them, but the session you are left holding is root's.

Two things that fixes are invisible until they bite: group membership is fixed at
LOGIN, so the `docker` group just granted is not in the current session, and the
shell configuration was written into their home and is not loaded in root's. Both
present as "the machine is broken" rather than "log in again".

Printed by whichever half runs LAST. The first attempt put it at the end of both,
which says it twice on a full install — and the first time it is wrong, because
officer-setup is about to run and still needs the root session it tells you to
leave. install.sh is the only thing that knows whether anything follows, so it
sets OFFICER_SETUP_FOLLOWS and machine-setup stays quiet.

Also drops "Pre-flight complete. The remaining sections are not built yet." from
the end of officer-setup. All 11 sections exist; that line last made sense when 6
did.

Verified: bash -n on all three, the set -e behaviour of `$RUN_OFFICER && export`
under --machine-only, and the suppression across all five ways in.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-14 06:05:57 +00:00
co-authored by Claude Opus 5
parent cbfe376a42
commit 6c13e0d8f6
3 changed files with 67 additions and 2 deletions
+10
View File
@@ -149,8 +149,18 @@ say ""
# Not `set -e`'s job: a half that exits non-zero should say which half, and stop
# before the next one starts on a machine that is not ready for it.
# ── Who says "you are still root" ──
#
# Both halves end as root and both need to say so, but only the LAST one to run
# should — otherwise a full install says it twice, once in the middle where it is
# wrong, because officer-setup is about to run and still needs the privilege.
#
# So the rule is "say it if nothing follows you", and this is the only place that
# knows whether anything does.
if $RUN_MACHINE; then
$RUN_OFFICER && export OFFICER_SETUP_FOLLOWS=1
bash "$MACHINE" || die "machine setup did not finish — fix what it reported, then run this again"
unset OFFICER_SETUP_FOLLOWS
fi
if $RUN_OFFICER; then
@@ -2522,6 +2522,34 @@ echo " Officer: $OFFICER_ROOT"
[[ -n "${TS_IP:-}" && "$TS_IP" != "unknown" ]] && echo " Tailscale: $TS_IP"
echo ""
# ── Who you are when this exits ──
#
# Root. This script never becomes ${USERNAME} — it cannot, since a process cannot
# change its own uid — so it stays root and drops privileges per command instead.
# Everything written into their home was written that way.
#
# Worth saying out loud because the two things a fresh session fixes are both
# invisible until they bite: group membership is fixed at LOGIN, so the `docker`
# group just granted does not exist in this session, and their shell configuration
# lives in their home and is not loaded in root's.
#
# Suppressed when officer-setup is about to run — install.sh sets the variable. It
# would be wrong advice in the middle of an install, because the half that follows
# still needs the root session this would tell you to leave.
if [[ "$EUID" -eq 0 && -z "${OFFICER_SETUP_FOLLOWS:-}" ]]; then
echo -e "${BOLD} You are still root.${NC}"
echo ""
echo " This machine is set up for ${USERNAME}. To carry on as them:"
echo ""
echo -e " ${BOLD}su - ${USERNAME}${NC} from this session"
echo -e " ${BOLD}ssh ${USERNAME}@<this machine>${NC} or log in fresh"
echo ""
echo " A new session is what makes their docker group membership and their"
echo " shell configuration take effect — neither applies to the session you"
echo " are in now."
echo ""
fi
# Clean up progress file on success
rm -f "$PROGRESS_FILE"
+28 -1
View File
@@ -838,8 +838,35 @@ if ! skip; then
fi
# ── Who you are when this exits ──
#
# Root, and that surprises people — reasonably, because everything this script just
# installed belongs to somebody else. The platform runs as ${USERNAME}: the checkout,
# node_modules, .env, the secret store and all six pm2 processes are theirs. Root was
# the installer's privilege, never the platform's.
#
# Saying so matters for two things that are invisible until they bite:
#
# - group membership is fixed at login. ${USERNAME} was added to `docker` during
# machine setup, and a session that started before that does not have it — so
# `docker ps` fails for a reason that has nothing to do with docker.
# - the shell config was written into THEIR home. Staying as root means none of it
# is loaded, and the machine looks unconfigured.
if [[ "$EUID" -eq 0 ]]; then
echo ""
echo -e "${BOLD} Pre-flight complete.${NC} The remaining sections are not built yet."
echo -e "${BOLD} One more thing — you are still root.${NC}"
echo ""
echo " Officer runs as ${USERNAME}, and everything it installed is theirs."
echo " Nothing here needs root any more. To carry on as them:"
echo ""
echo -e " ${BOLD}su - ${USERNAME}${NC} from this session"
echo -e " ${BOLD}ssh ${USERNAME}@<this machine>${NC} or log in fresh"
echo ""
echo " Either gives a new session, which is what makes their docker group"
echo " membership and their shell configuration take effect. Staying as root"
echo " means neither does, and the machine will look half-configured."
fi
echo ""
report_mark_complete