Harden scripts for non-interactive provisioning

- config/scripts/bw-load-ssh.sh: add ssh-agent retry loop (graphical
  session may not be ready when systemd fires); use process substitution
  instead of pipe to avoid subshell + set -e issues with LOADED counter
- stages/05-git.sh: remove interactive SSH key generation prompt (keys
  come from Bitwarden); pre-accept GitHub host key via ssh-keyscan
  to avoid first-connect prompt during git clone
- stages/04-shell.sh: add sudo chsh fallback (chsh may fail in
  non-interactive provisioning without PAM auth)
This commit is contained in:
2026-06-07 14:34:25 +10:00
parent c7845fd04d
commit f0e18fda45
3 changed files with 41 additions and 35 deletions

24
config/scripts/bw-load-ssh.sh Normal file → Executable file
View File

@@ -24,9 +24,22 @@ if [ ! -f "$SESSION_FILE" ]; then
exit 1
fi
# Check ssh-agent is running
if ! ssh-add -l >/dev/null 2>&1; then
echo "ERROR: ssh-agent is not running."
# Check ssh-agent is running (retry in case graphical session hasn't fully started)
# ssh-add -l exits 2 if agent not running, 1 if no identities (which is fine)
_ssh_retries=5
_ssh_waited=0
while [ $_ssh_waited -lt $_ssh_retries ]; do
_ssh_exit=0
ssh-add -l >/dev/null 2>&1 || _ssh_exit=$?
if [ $_ssh_exit -eq 2 ]; then
sleep 2
_ssh_waited=$((_ssh_waited + 1))
else
break
fi
done
if [ $_ssh_exit -eq 2 ]; then
echo "ERROR: ssh-agent is not running after ${_ssh_retries} attempts."
echo "Start it with: eval \$(ssh-agent)"
exit 1
fi
@@ -53,7 +66,8 @@ fi
LOADED=0
SKIPPED=0
echo "$ITEMS" | while IFS= read -r item; do
# Use process substitution instead of pipe to avoid subshell and set -e issues
while IFS= read -r item; do
NAME=$(echo "$item" | jq -r '.name')
PUBLIC_KEY=$(echo "$item" | jq -r '.sshKey.publicKey // ""')
PRIVATE_KEY=$(echo "$item" | jq -r '.sshKey.privateKey // ""')
@@ -80,6 +94,6 @@ echo "$ITEMS" | while IFS= read -r item; do
else
echo " FAIL '$NAME'"
fi
done
done <<< "$ITEMS"
echo "Done. Loaded: $LOADED, Skipped (already loaded): $SKIPPED"