Skip to content

fix: start GnuPG launchd jobs left pending by bootstrap - #29

Merged
liby merged 2 commits into
mainfrom
bugfix/28-kickstart-gnupg-launchd-jobs
Sep 3, 2026
Merged

fix: start GnuPG launchd jobs left pending by bootstrap#29
liby merged 2 commits into
mainfrom
bugfix/28-kickstart-gnupg-launchd-jobs

Conversation

@liby

@liby liby commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Closes #28.

On a machine whose gui launchd domain is in on-demand-only mode, launchctl bootstrap registers the gpg-agent and keyboxd jobs but leaves their RunAtLoad spawn pending as speculative, so the bootstrap script's socket wait failed. Apple's DTS describes that mode in LaunchAgent priority: while login app restore or Setup Assistant is still running, the gui domain accepts only on-demand starts and pends every other spawn until that phase ends, so a chezmoi init run in that window hits it. The script now kickstarts each job unless launchctl print already reports a run, and appends conf options on their own line even when a hand-edited file lacks a trailing newline.

The --no-detach plus KeepAlive form suggested in the issue is not adopted: in GnuPG 2.5.22 --no-detach only keeps the console and the launched process still forks, so KeepAlive would respawn a parent that exits 2 on the held socket. gpgconf --kill returns after the daemon exited, so no extra wait was added.

Because the script contents changed, the next chezmoi apply on every existing machine reruns it: gpg-agent and keyboxd restart and the YubiKey must be present.

The on-demand-only mode could not be reproduced locally. The kickstart branch was exercised with a throwaway launchd label whose job had RunAtLoad false; on a normal gui domain, launchctl bootstrap returns with runs = 1 already recorded, so the guard skips kickstart there. Verification on the reporter's machine is requested in the issue.

A hand-edited gpg-agent.conf or common.conf may end without a trailing
newline, and `echo >>` then glued the new option onto the last line
(`max-cache-ttl-ssh 28800enable-ssh-support` in #28), where the
`grep "^option"` guards never matched it again. Add the missing newline
before appending and write the line with `print -r --` so zsh does not
interpret backslashes or a leading dash.
On a machine whose gui launchd domain was in on-demand-only mode,
`launchctl bootstrap` registered both jobs but left their `RunAtLoad`
spawn pending as speculative, so neither daemon ever ran and the socket
wait failed (#28). Kickstart each job unless `launchctl print` already
reports a run: a second parent would exit 2 on the held socket and leave
that exit code in the diagnostics the failure message points at.

Keep `--daemon` with `AbandonProcessGroup` instead of the `--no-detach`
plus `KeepAlive` form proposed in #28: in GnuPG 2.5 `--no-detach` only
keeps the console and the launched process still forks, so launchd
would respawn a parent that exits 2 on the held socket.

The changed contents rerun this `run_once` script on every existing
machine at the next `chezmoi apply`, which restarts gpg-agent and
keyboxd and needs the YubiKey present.
@liby
liby force-pushed the bugfix/28-kickstart-gnupg-launchd-jobs branch from 49ce8c4 to 9de638f Compare September 3, 2026 05:51
@liby
liby merged commit b9044fe into main Sep 3, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GnuPG LaunchAgent bootstrap 后未实际启动

1 participant