diff --git a/.spacemacs b/.spacemacs index df9aab8..6552fc8 100644 --- a/.spacemacs +++ b/.spacemacs @@ -665,20 +665,24 @@ before packages are loaded." (spacemacs/set-leader-keys "ot" 'toggle-proxy) ;; idea from chatgpt - (defun set-dotfiles-environment () + (defun jp/set-dotfiles-environment () "Set environment variables for the dotfiles repository." (interactive) (setenv "GIT_DIR" (expand-file-name "~/.cfg/")) (setenv "GIT_WORK_TREE" (expand-file-name "~")) (message "Dotfiles environment set.")) - (defun unset-dotfiles-environment () + (defun jp/unset-dotfiles-environment () "Unset environment variables for the dotfiles repository." (interactive) (setenv "GIT_DIR" nil) (setenv "GIT_WORK_TREE" nil) (message "Dotfiles environment unset.")) + (global-set-key (kbd " s") 'jp/set-dotfiles-environment) + (global-set-key (kbd " u") 'jp/unset-dotfiles-environment) + + (defun magit-status-dotfiles () "Open Magit with the dotfiles Git configuration." (interactive) diff --git a/bin/lib/common.sh b/bin/lib/common.sh index b16f051..4969d5c 100644 --- a/bin/lib/common.sh +++ b/bin/lib/common.sh @@ -15,16 +15,26 @@ w3m_safe() { # Returns: -# 0 = server reachable & command ran +# 0 = server reachable & remote command ran # 1 = network/host-not-up-yet -# 2 = SSH auth failure (likely passphrase/key issue) -> caller should abort +# 2 = SSH auth failure (key needs passphrase / wrong key / agent locked) -> caller should abort +# 3 = host not found is_server_up() { + local host err st err_lc host=$1 - # Capture only stderr (order of redirs matters: 2>&1 >/dev/null) - err=$(/usr/bin/ssh \ + # return 3 if the host does not exist + host "$host" 2>&1 > /dev/null || return 3 + + # Capture only stderr; do NOT use -q (it suppresses diagnostics we need to classify). + # Force English messages for stable matching. + err=$(LC_ALL=C /usr/bin/ssh \ -o BatchMode=yes \ -o PreferredAuthentications=publickey \ + -o PubkeyAuthentication=yes \ + -o PasswordAuthentication=no \ + -o KbdInteractiveAuthentication=no \ + -o NumberOfPasswordPrompts=0 \ -o ConnectTimeout=10 \ -o ServerAliveInterval=20 \ -o ServerAliveCountMax=3 \ @@ -32,44 +42,60 @@ is_server_up() { -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ -o LogLevel=ERROR \ - -n -q "$host" 'uname -n || hostname' 2>&1 >/dev/null) + -n "$host" 'uname -n || hostname' 2>&1 >/dev/null) st=$? + # Success [ $st -eq 0 ] && return 0 - # Normalize to lowercase for robust matching + # ssh uses 255 for any error; distinguish by stderr text err_lc=$(printf '%s' "$err" | tr '[:upper:]' '[:lower:]') case $err_lc in + # Common auth/passphrase/agent problems *"permission denied"*|\ *"no supported authentication methods available"*|\ + *"publickey authentication failed"*|\ *"too many authentication failures"*|\ + *"sign_and_send_pubkey: signing failed"*|\ + *"agent refused operation"*|\ *"agent admitted failure"*|\ - *"publickey authentication failed"*) + *"bad permissions"*|\ + *"enter passphrase"*) printf 'FATAL: SSH authentication failed for "%s": %s\n' "$host" "$err" >&2 return 2 ;; esac - # Anything else (timeout, connection refused, kex read/reset, etc.) + # Everything else looks like "not up yet" (timeout, DNS, connection refused/reset, kex read, etc.) return 1 } wait_for_server_to_boot_up() { + local server rc server=$1 while :; do - if is_server_up "$server"; then - printf '"%s" is up and running.\n' "$server" - return 0 - fi + is_server_up "$server" rc=$? - if [ $rc -eq 2 ]; then - printf 'Aborting: SSH authentication failed for "%s" (likely passphrase needed or wrong key).\n' "$server" >&2 - exit 2 - fi - printf 'Server "%s" is not up\n' "$server" - sleep 10 + case $rc in + 0) + printf '"%s" is up and running.\n' "$server" + return 0 + ;; + 2) + printf 'Aborting: SSH authentication failed for "%s" (key needs passphrase / wrong key / agent locked).\n' "$server" >&2 + return 2 + ;; + 3) + printf 'Aborting: Host not found.\n' "$server" >&2 + return 3 + ;; + *) + printf 'Server "%s" is not up\n' "$server" + sleep 10 + ;; + esac done } -# vim: set ts=4 sw=4 tw=0 noet ft=bash: +# vim: set ts=4 sw=4 tw=0 noet ft=sh: