diff --git a/scripts/setup/machine-setup/lib/base.sh b/scripts/setup/machine-setup/lib/base.sh index e6343b5c..79c26773 100644 --- a/scripts/setup/machine-setup/lib/base.sh +++ b/scripts/setup/machine-setup/lib/base.sh @@ -163,6 +163,62 @@ confirm() { done } +# Which account this machine is being set up for. +# +# Asked at the top because two later questions default off it — where Officer is +# installed, and where the disk ballast goes — so it has to be settled before +# either is put to the user. +# +# Defaults to whoever invoked sudo. On a re-run, or on a machine that is already +# somebody's, that is the answer every time, and typing it again is a chance to +# typo it into creating a second account. +# +# SETUP_USERNAME in the environment answers it ahead of time. Deliberately not +# USERNAME: that name is set by some login environments, and a variable this +# script silently obeys should not be one that might already be in the +# environment for unrelated reasons. +ask_username() { + local default="${SUDO_USER:-}" answer + + # root invoked the script directly rather than through sudo. It is never the + # account being set up, so there is nothing to suggest. + [[ "$default" == "root" ]] && default="" + + if [[ -n "${SETUP_USERNAME:-}" ]]; then + answer="$SETUP_USERNAME" + else + echo "" + info "Which account is this machine for?" + echo " The account you log in and work as — not root. It will be created" + echo " if it does not exist." + echo "" + while [[ -z "${answer:-}" ]]; do + if ! read -rp " Username${default:+ [$default]}: " answer; then + echo "" + fail "No answer. Set SETUP_USERNAME= to answer this ahead of time." + fi + answer="${answer:-$default}" + [[ -z "$answer" ]] && warn "There is no default here — type a username." + done + fi + + # The portable shape of a Linux account name. Worth checking rather than + # letting adduser refuse it later, because by then several questions have been + # answered against a name that was never going to work. + [[ "$answer" =~ ^[a-z_][a-z0-9_-]*\$?$ && ${#answer} -le 32 ]] || + fail "'${answer}' is not a usable Linux username — lower case, starting with a letter or underscore." + [[ "$answer" == "root" ]] && fail "root is not the account to set up here." + + USERNAME="$answer" + + # Looked up, not assumed. The original built "/home/$USERNAME", which is merely + # the usual answer — an account created with a different home, or one whose home + # was moved, would have every later step writing to a directory that is not + # theirs. + USER_HOME="$(getent passwd "$USERNAME" 2>/dev/null | cut -d: -f6)" + [[ -n "$USER_HOME" ]] || USER_HOME="/home/${USERNAME}" +} + # Where Officer will live. # # Asked in pre-flight with the rest of the questions rather than at the point it diff --git a/scripts/setup/machine-setup/machine-setup.sh b/scripts/setup/machine-setup/machine-setup.sh index bbb3a0dd..89e2a362 100755 --- a/scripts/setup/machine-setup/machine-setup.sh +++ b/scripts/setup/machine-setup/machine-setup.sh @@ -73,13 +73,13 @@ if [[ "$EUID" -ne 0 ]]; then fail "Please run as root: sudo ./machine-setup.sh" fi -prompt_value USERNAME "New admin username (or existing)" "" -if [[ -z "$USERNAME" ]]; then - fail "Username cannot be empty" +ask_username +if id "$USERNAME" &>/dev/null; then + info "Account: ${USERNAME} (exists, home ${USER_HOME})" +else + info "Account: ${USERNAME} (will be created, home ${USER_HOME})" fi -USER_HOME="/home/$USERNAME" - ask_officer_root if [[ -d "$OFFICER_ROOT" ]]; then info "Officer: ${OFFICER_ROOT} (exists already)" @@ -813,19 +813,6 @@ if ! skip; then SUMMARY+=("Sudo: password required (Officer's account provisioning will not work)") fi fi - - # ── tmux config ── - # - # install_config rather than cp: the original overwrote whatever was there on - # every single run. - if [[ -f "$SCRIPT_DIR/.tmux.conf" ]] && id "$USERNAME" &>/dev/null; then - install_config "$SCRIPT_DIR/.tmux.conf" "${USER_HOME}/.tmux.conf" "$USERNAME" - case $? in - 0) ok "tmux config installed" ;; - 1) : ;; - 2) : ;; - esac - fi step_ok fi @@ -836,7 +823,7 @@ fi # Sections still to move across from scripts/setup-old/setup-ubuntu.sh, in order: # # ssh keys · ssh hardening · dns · static ip · fail2ban · unattended-upgrades · -# git config · docker · zsh + prompt · tailscale · neovim · js runtimes · +# git config · docker · zsh + prompt (incl. .tmux.conf) · tailscale · neovim · js runtimes · # dev tools · ufw · zshrc # # Each arrives as its own commit. Delete this block when the list is empty.