From d4b9b7b334a09c41d1695ab2a079ca28966f787d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Wed, 12 Aug 2026 18:02:28 +0000 Subject: [PATCH] ask where Officer should be installed, in pre-flight MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OFFICER_ROOT, defaulting to /officerdev. One directory holding the four things Officer is made of, per docs/sidecar-app-store.md — the app, its data, the item store, and any containers the app store provisions — so the whole installation can be moved, backed up or deleted as a unit. Asked at the start with the other questions rather than at the point it is first needed. It decides the shape of several later steps: where the repository is cloned, where DATA_PATH sits beside it, and which filesystem the app store's bind mounts come out of. Asking once up front also means the run can be described before it starts rather than discovered as it goes. A leading ~ is expanded explicitly. It arrives as a literal from a read or an environment variable — nothing expands it there — and would otherwise create a directory actually named "~" in whatever the working directory happened to be. Relative paths are refused with the value named, and a trailing slash is trimmed so the path composes cleanly with what gets appended to it. Nothing creates the directory yet; that belongs to officer-setup. This records the answer and reports it, including whether it already exists. Verified: Enter takes the default, ~ expands, trailing slash trims, OFFICER_ROOT in the environment skips the prompt, and a relative path fails with the value named. Co-Authored-By: Claude Opus 5 (1M context) --- scripts/setup/machine-setup/lib/base.sh | 44 ++++++++++++++++++++ scripts/setup/machine-setup/machine-setup.sh | 8 ++++ 2 files changed, 52 insertions(+) diff --git a/scripts/setup/machine-setup/lib/base.sh b/scripts/setup/machine-setup/lib/base.sh index 5308972c..5d69311b 100644 --- a/scripts/setup/machine-setup/lib/base.sh +++ b/scripts/setup/machine-setup/lib/base.sh @@ -163,6 +163,50 @@ confirm() { done } +# Where Officer will live. +# +# Asked in pre-flight with the rest of the questions rather than at the point it +# is first needed, because it decides the shape of several later steps — the +# directory the repository is cloned into, where DATA_PATH sits beside it, and +# which filesystem the app store's containers bind-mount out of. Answering it +# once at the start also means the run can be described before it begins. +# +# One directory holding four, per docs/sidecar-app-store.md: +# +# /platform/ the app +# /data/ DATA_PATH +# /dockers/ services the app store provisioned +# /capabilities/ the file-based item store +# +# OFFICER_ROOT in the environment answers it ahead of time. +ask_officer_root() { + local default="${USER_HOME}/officerdev" answer + + if [[ -n "${OFFICER_ROOT:-}" ]]; then + answer="$OFFICER_ROOT" + else + echo "" + info "Where should Officer be installed?" + echo " One directory holding the app, its data, the item store and any" + echo " containers the app store provisions — so it can be moved, backed" + echo " up or deleted as a unit." + echo "" + if ! read -rp " Path [${default}]: " answer; then + echo "" + fail "No answer. Set OFFICER_ROOT= to answer this ahead of time." + fi + answer="${answer:-$default}" + fi + + # A leading ~ arrives as a literal when it comes from a read or an environment + # variable — nothing expands it there — and would create a directory named "~". + answer="${answer/#\~/$USER_HOME}" + + [[ "$answer" == /* ]] || fail "That needs to be an absolute path, starting with / — got '${answer}'" + + OFFICER_ROOT="${answer%/}" +} + # Run a block as the created user (login shell, inherits HOME) as_user() { sudo -u "$USERNAME" -i bash -c "$1" diff --git a/scripts/setup/machine-setup/machine-setup.sh b/scripts/setup/machine-setup/machine-setup.sh index 2dab1855..c62ca90d 100755 --- a/scripts/setup/machine-setup/machine-setup.sh +++ b/scripts/setup/machine-setup/machine-setup.sh @@ -78,6 +78,13 @@ fi USER_HOME="/home/$USERNAME" +ask_officer_root +if [[ -d "$OFFICER_ROOT" ]]; then + info "Officer: ${OFFICER_ROOT} (exists already)" +else + info "Officer: ${OFFICER_ROOT}" +fi + # Always, and outside any step: everything below reads this index — core utils, # the fastfetch PPA, the Docker repo — and `step` skips a step whose name is # already in the progress file. With the refresh inside one of those, a resumed @@ -579,6 +586,7 @@ echo " System: $OS_NAME ($ARCH)" echo " Role: $MACHINE_ROLE" echo " User: $USERNAME" echo " Home: $USER_HOME" +echo " Officer: $OFFICER_ROOT" [[ -n "${TS_IP:-}" && "$TS_IP" != "unknown" ]] && echo " Tailscale: $TS_IP" echo ""