[zsh] Make ssh loading across platform more robust

This commit is contained in:
2026-03-03 23:37:47 -05:00
parent 48985e5b5c
commit 61565479f2
5 changed files with 209 additions and 26 deletions

View File

@ -8,11 +8,17 @@
(after! envrc
(envrc-global-mode))
;; Force systemd user ssh-agent socket for all Emacs subprocesses.
(let* ((xdg (format "/run/user/%d" (user-uid)))
(sock (expand-file-name "ssh-agent.socket" xdg)))
(setenv "XDG_RUNTIME_DIR" xdg)
(setenv "SSH_AUTH_SOCK" sock))
;; Force user ssh-agent socket for all Emacs subprocesses.
(defun my/apply-ssh-agent-env ()
"Set SSH_AUTH_SOCK in Emacs using ~/.local/bin/ssh-agent-env."
(let* ((cmd (expand-file-name "~/.local/bin/ssh-agent-env"))
(out (and (file-executable-p cmd)
(string-trim (shell-command-to-string cmd)))))
;; out looks like: export SSH_AUTH_SOCK='...'
(when (and out (string-match "SSH_AUTH_SOCK='\\([^']+\\)'" out))
(setenv "SSH_AUTH_SOCK" (match-string 1 out)))))
(my/apply-ssh-agent-env)
;; load pinentry
(when (require 'pinentry nil t)
@ -448,33 +454,22 @@ Always open the result in `eww`."
;; Bind globally to C-c l
(global-set-key (kbd "C-c l") #'life-scrobble-url)
(after! magit
(defvar my/ssh-key-injector-script (expand-file-name "~/.local/bin/load_keys"))
(defun my/systemd-ssh-auth-sock ()
(format "/run/user/%d/ssh-agent.socket" (user-uid)))
(defun my/ssh-add-status ()
"ssh-add -l exit code: 0=has keys, 1=no keys, 2=no agent."
(call-process "ssh-add" nil nil nil "-l"))
(defun my/run-ssh-key-injector ()
(my/apply-ssh-agent-env)
(let* ((buf (get-buffer-create "*ssh-key-injector*"))
(sock (my/systemd-ssh-auth-sock))
(process-connection-type t) ;; PTY for pinentry-curses
(process-connection-type t)
(process-environment (copy-sequence process-environment)))
(setenv "SSH_AUTH_SOCK" sock)
(setenv "XDG_RUNTIME_DIR" (format "/run/user/%d" (user-uid)))
(unless (file-executable-p my/ssh-key-injector-script)
(user-error "SSH injector script not executable: %s" my/ssh-key-injector-script))
(with-current-buffer buf
(erase-buffer)
(insert (format "Emacs SSH_AUTH_SOCK=%s\n" (getenv "SSH_AUTH_SOCK")))
(insert (format "Emacs XDG_RUNTIME_DIR=%s\n\n" (getenv "XDG_RUNTIME_DIR"))))
(insert (format "Emacs SSH_AUTH_SOCK=%s\n\n" (or (getenv "SSH_AUTH_SOCK") "<unset>"))))
(let ((proc (make-process
:name "ssh-key-injector"
:buffer buf
@ -483,16 +478,15 @@ Always open the result in `eww`."
:noquery t)))
(while (process-live-p proc)
(accept-process-output proc 0.05))
(let ((exit (process-exit-status proc)))
(unless (eq exit 0)
(display-buffer buf)
(user-error "SSH key injection failed (exit %d). See *ssh-key-injector*." exit))))))
(unless (eq (process-exit-status proc) 0)
(display-buffer buf)
(user-error "SSH key injection failed. See *ssh-key-injector*.")))))
(defun my/ensure-ssh-keys-loaded (&rest _ignore)
(pcase (my/ssh-add-status)
(0 nil) ;; already has identities
(1 (my/run-ssh-key-injector)) ;; agent reachable but empty
(2 (user-error "No reachable ssh-agent. SSH_AUTH_SOCK=%s"
(0 nil)
(1 (my/run-ssh-key-injector))
(2 (user-error "No reachable ssh-agent (SSH_AUTH_SOCK=%s)"
(or (getenv "SSH_AUTH_SOCK") "<unset>")))
(_ (my/run-ssh-key-injector))))