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:
24
config/scripts/bw-load-ssh.sh
Normal file → Executable file
24
config/scripts/bw-load-ssh.sh
Normal file → Executable file
@@ -24,9 +24,22 @@ if [ ! -f "$SESSION_FILE" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check ssh-agent is running
|
# Check ssh-agent is running (retry in case graphical session hasn't fully started)
|
||||||
if ! ssh-add -l >/dev/null 2>&1; then
|
# ssh-add -l exits 2 if agent not running, 1 if no identities (which is fine)
|
||||||
echo "ERROR: ssh-agent is not running."
|
_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)"
|
echo "Start it with: eval \$(ssh-agent)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -53,7 +66,8 @@ fi
|
|||||||
LOADED=0
|
LOADED=0
|
||||||
SKIPPED=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')
|
NAME=$(echo "$item" | jq -r '.name')
|
||||||
PUBLIC_KEY=$(echo "$item" | jq -r '.sshKey.publicKey // ""')
|
PUBLIC_KEY=$(echo "$item" | jq -r '.sshKey.publicKey // ""')
|
||||||
PRIVATE_KEY=$(echo "$item" | jq -r '.sshKey.privateKey // ""')
|
PRIVATE_KEY=$(echo "$item" | jq -r '.sshKey.privateKey // ""')
|
||||||
@@ -80,6 +94,6 @@ echo "$ITEMS" | while IFS= read -r item; do
|
|||||||
else
|
else
|
||||||
echo " FAIL '$NAME'"
|
echo " FAIL '$NAME'"
|
||||||
fi
|
fi
|
||||||
done
|
done <<< "$ITEMS"
|
||||||
|
|
||||||
echo "Done. Loaded: $LOADED, Skipped (already loaded): $SKIPPED"
|
echo "Done. Loaded: $LOADED, Skipped (already loaded): $SKIPPED"
|
||||||
|
|||||||
10
stages/04-shell.sh
Normal file → Executable file
10
stages/04-shell.sh
Normal file → Executable file
@@ -92,8 +92,14 @@ fi
|
|||||||
# ---- Change default shell to zsh ----
|
# ---- Change default shell to zsh ----
|
||||||
info "Setting zsh as default shell..."
|
info "Setting zsh as default shell..."
|
||||||
if [ "$SHELL" != "$(which zsh)" ]; then
|
if [ "$SHELL" != "$(which zsh)" ]; then
|
||||||
chsh -s "$(which zsh)" 2>/dev/null || warn "Could not change shell (chsh)."
|
# Try chsh directly first, fallback to sudo chsh (for non-interactive provisioning)
|
||||||
ok "Default shell set to zsh. Log out and back in to activate."
|
if chsh -s "$(which zsh)" 2>/dev/null; then
|
||||||
|
ok "Default shell set to zsh. Log out and back in to activate."
|
||||||
|
elif sudo chsh -s "$(which zsh)" "$USER" 2>/dev/null; then
|
||||||
|
ok "Default shell set to zsh via sudo. Log out and back in to activate."
|
||||||
|
else
|
||||||
|
warn "Could not change shell (chsh). Run manually: chsh -s \"$(which zsh)\""
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
ok "zsh is already the default shell."
|
ok "zsh is already the default shell."
|
||||||
fi
|
fi
|
||||||
|
|||||||
42
stages/05-git.sh
Normal file → Executable file
42
stages/05-git.sh
Normal file → Executable file
@@ -67,35 +67,21 @@ EOF
|
|||||||
ok "Global .gitignore deployed."
|
ok "Global .gitignore deployed."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ---- Git SSH key ----
|
# ---- SSH keys ----
|
||||||
# The Pop machine has a single SSH key: id_ed25519_github
|
# All SSH keys are stored in Bitwarden and loaded via bw-load-ssh.sh (stage 06).
|
||||||
# Loading is handled by bw-load-ssh.sh (stage 07) from Bitwarden.
|
# No local keys are generated.
|
||||||
# This stage can generate a new key if one doesn't exist.
|
info "SSH keys: loaded from Bitwarden via stage 06 (bw-load-ssh.sh)."
|
||||||
info "Checking SSH keys..."
|
|
||||||
if [ ! -f "$HOME/.ssh/id_ed25519" ]; then
|
# ---- Pre-accept GitHub host key ----
|
||||||
warn "No SSH key found."
|
# Avoids interactive prompt on first SSH connection to GitHub
|
||||||
warn "Options:"
|
if [ ! -f "$HOME/.ssh/known_hosts" ] || ! ssh-keygen -F github.com &>/dev/null; then
|
||||||
warn " 1. Generate a new key (recommended for new machine):"
|
info "Adding github.com SSH host key to known_hosts..."
|
||||||
warn " ssh-keygen -t ed25519 -C 'hi@julianprester.com'"
|
mkdir -p "$HOME/.ssh"
|
||||||
warn " 2. Restore from backup/Bitwarden (see TODO.md)"
|
ssh-keyscan github.com >> "$HOME/.ssh/known_hosts" 2>/dev/null && \
|
||||||
warn " 3. Skip for now (run bw-load-ssh.sh later to load from Bitwarden)"
|
chmod 644 "$HOME/.ssh/known_hosts" && \
|
||||||
echo ""
|
ok "GitHub host key added." || warn "Could not fetch GitHub host key."
|
||||||
read -r -p "Generate a new SSH key now? [y/N] " response
|
|
||||||
if [[ "$response" =~ ^[Yy]$ ]]; then
|
|
||||||
ssh-keygen -t ed25519 -C "hi@julianprester.com" -f "$HOME/.ssh/id_ed25519" -N "" 2>/dev/null || {
|
|
||||||
warn "Key generation skipped or failed."
|
|
||||||
}
|
|
||||||
ok "SSH key generated: ~/.ssh/id_ed25519.pub"
|
|
||||||
cat "$HOME/.ssh/id_ed25519.pub"
|
|
||||||
warn "Add this key to GitHub: https://github.com/settings/keys"
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
ok "SSH key already exists."
|
ok "GitHub host key already known."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ensure proper SSH permissions
|
|
||||||
chmod 700 "$HOME/.ssh" 2>/dev/null || true
|
|
||||||
find "$HOME/.ssh" -type f -name "id_*" -exec chmod 600 {} \; 2>/dev/null || true
|
|
||||||
find "$HOME/.ssh" -type f -name "*.pub" -exec chmod 644 {} \; 2>/dev/null || true
|
|
||||||
|
|
||||||
ok "Stage 05 complete: Git configured."
|
ok "Stage 05 complete: Git configured."
|
||||||
|
|||||||
Reference in New Issue
Block a user