feat(autostart): add LaunchDaemon support for headless macOS servers#4984
feat(autostart): add LaunchDaemon support for headless macOS servers#4984resker wants to merge 8 commits into
Conversation
Introduces `limactl daemon install/uninstall` to register Lima instances
as system LaunchDaemons, enabling VM startup at boot without requiring a
user session or auto-login.
LaunchAgents (the existing `start-at-login` mechanism) require a GUI
login session and do not start on headless macOS servers. A LaunchDaemon
with a `UserName` key runs as a specified user at system boot, before
any login, solving this gap.
Changes:
- pkg/autostart/launchd: add DaemonTemplate, GetDaemonPlistPath,
DaemonServiceNameFrom; restore RequestStop to its original form
- pkg/autostart/managers: add extraTemplateVars to
TemplateFileBasedManager to support templates requiring additional
variables (e.g. UserName)
- pkg/autostart/managers_darwin: add DaemonManager(userName string) for
rendering daemon plists and tracking registration state
- pkg/autostart/managers_{linux,others}: add DaemonManager stubs
returning notSupportedManager
- cmd/limactl: add `daemon` subcommand with `install` and `uninstall`;
runs as normal user; privileged operations (writing to
/Library/LaunchDaemons/ and launchctl system domain) are performed via
sudo internally so limactl itself never runs as root
- tests: add TestGetDaemonPlistPath, TestDaemonServiceNameFrom, and a
daemon plist render test verifying UserName substitution
Developed with AI assistance.
Signed-off-by: Robert Esker <resker@gmail.com>
Signed-off-by: Robert Esker <resker@gmail.com>
f2ca93d to
0c20526
Compare
Signed-off-by: Robert Esker <resker@gmail.com>
Unifies LaunchAgent (login) and LaunchDaemon (boot) management under a single `limactl autostart enable/disable` command per maintainer feedback. - `limactl autostart enable --condition=login` (default): installs a LaunchAgent on macOS or a systemd user service on Linux, equivalent to the existing `start-at-login` command - `limactl autostart enable --condition=boot --user=$USER`: installs a system LaunchDaemon on macOS (macOS only, prompts for sudo) - `limactl autostart disable`: removes whichever registration is present `limactl start-at-login` is kept but marked deprecated in favor of `limactl autostart enable`. Adds a dedicated usage/autostart.md subpage for the documentation. Signed-off-by: Robert Esker <resker@gmail.com>
- Call Flags() once in newAutostartEnableCommand via local var - Mark autostart docs as requiring Lima >= 2.2 Signed-off-by: Robert Esker <resker@gmail.com>
|
@resker May I confirm that your commits were DCO-signed by you human, not by a bot? |
- Shorten start-at-login deprecated message to "use limactl autostart instead" - Add Lima < 2.2 section to autostart.md documenting limactl start-at-login - Add limactl start-at-login to deprecated features page Signed-off-by: Robert Esker <resker@gmail.com>
Signed-off-by: Robert Esker <resker@gmail.com>
@AkihiroSuda - yes, confirmed... I am not now nor have I ever been a bot :-) The turnaround assisted by AI tools (everything reviewed and submitted by me though). |
Signed-off-by: Robert Esker <resker@gmail.com>
Sorry for doubting you 😅 |
AkihiroSuda
left a comment
There was a problem hiding this comment.
Thanks, LGTM after squashing commits.
WIll merge after the release of v2.1.2
Closes #4983
Summary
Adds
limactl autostart enable --condition=bootto register a Lima instanceas a system-level LaunchDaemon. The VM starts at boot without requiring a user
login session, enabling headless macOS server deployments.
Also unifies the existing
start-at-loginfunctionality under the newlimactl autostartcommand and deprecateslimactl start-at-login.Commands
Design
Privilege model:
limactlitself stays non-root (the existing root checkis not bypassed). The
--condition=bootpath execssudointernally forexactly two operations — writing to
/Library/LaunchDaemons/and runninglaunchctl bootstrap system— and prompts for a password once at install time.UserNameplist key: launchd runs the daemon process as the specified user(defaulting to
$USER), so the Lima instance runs under the correct user'shome directory and config without requiring that user to be logged in.
Runtime: the daemon plist calls
limactl start <instance> --foreground,consistent with the existing LaunchAgent approach. Normal
limactl start/stopcontinues to work; no privileged runtime operations are needed.
Changes
pkg/autostart/launchd/io.lima-vm.daemon.INSTANCE.plist— daemon plist templatepkg/autostart/launchd/launchd.go—GetDaemonPlistPath,DaemonServiceNameFrom,DaemonTemplatepkg/autostart/managers.go—extraTemplateVarsfield onTemplateFileBasedManagerpkg/autostart/managers_darwin.go—DaemonManager(userName string)constructorpkg/autostart/managers_linux.go,managers_others.go—DaemonManagerstubscmd/limactl/autostart.go—limactl autostartcommand group (cross-platform)cmd/limactl/autostart_darwin.go— macOS: login → LaunchAgent, boot → LaunchDaemoncmd/limactl/autostart_others.go— non-macOS: login only, boot returns unsupported errorcmd/limactl/start-at-login.go— marked deprecatedcmd/limactl/main.go— registerautostartsubcommandwebsite/content/en/docs/usage/autostart.md— new documentation subpageTesting
GetDaemonPlistPath,DaemonServiceNameFrom, and daemon plist renderingNotes
--condition=bootis macOS only; other platforms return an unsupported errorBy submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license and I have signed off all commits per the DCO.