-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Summary
My organization has a fairly large macOS VM cluster, for which we use Ansible to manage services and such. At the moment, we have a number of boilerplate tasks to do this and we'd like to use the launchd
module, but it does not support many of the things that we need. I feel that the launchd
module, as it is currently architected, has some big shortcomings and is in need of a rewrite. I am happy to undertake this, but before submitting a "big bang" PR for a very large breaking change, I wanted to gather input from the community to see if this would be at all desirable.
I will detail below the changes that I would propose.
Change the meaning of the start
/stop
states
In macOS 10.11 (El Capitan), which was released in 2015, the launchctl load
/launchctl unload
/launchctl start
/launchctl stop
commands were replaced by launchctl bootstrap
/launchctl bootout
. The old commands remain in place to this day but are considered deprecated. Apple has (predictably) not given any public timeline for removing them, but they could disappear spontaneously in any new macOS release.
We should get rid of the old actions and replace them with bootstrap
/bootout
. Unfortunately, "bootout" does not lend itself nicely to a past tense verb for state
, so I would suggest replacing the behavior of started
/stopped
with launchctl bootstrap
/launchctl bootout
instead. This could be a bit confusing, so we'll need to document it well. The loaded
/unloaded
states will be deprecated and removed in a future release.
Note that the new behavior for these actions will require a user ID, which will be obtained from the owner
parameter (see below).
Add new states for enabled
/disabled
Since the launchd
module is used as the backend for the service
module on macOS 10.4+, the enabled
parameter cannot be changed, since the documentation for the same parameter in ansible.builtin.service
states:
Whether the service should start on boot.
However, we also need a mechanism to enable or disable the service in general. I propose adding two new state actions: enabled
/disabled
, which would correspond to launchctl enabled
/launchctl disabled
, respectively. Note that these state actions will require a user ID, which will be obtained from the owner
parameter (see below).
Eliminate the unloaded
and reloaded
states
Similar to the above suggestion, launchctl bootout
should replace launchctl unload
. Thus, the unload
state should be deprecated and removed in a future release. As reloaded
is essentially an alias for launchctl load
or launchctl reload
(depending on the service state), it should also be deprecated and removed.
Add a new required parameter, owner
The launchctl
actions for enable
/disable
/bootstrap
/bootout
all require a numeric user ID. We'll need a new integer parameter for this, and in the spirit of Ansible conventions, I suggest calling it owner
. We'll need to do some runtime checks to see if we get passed an integer or a string, and if the value is a string we'll need to do a UID lookup on the system via id -u <owner>
and consequently, throw an error if the UID cannot be determined.
Compatibility concerns
From what I understand, the community.general
collection requires Ansible 2.16+, which in turn requires macOS 10.15 (Catalina) or newer. I don't think that support for pre-10.11 hosts should be a concern.
Implementation
I propose the following plan to implement the above suggestions over the course of several releases:
- Future minor release(s):
- The
owner
parameter is introduced tolaunchd
. It is not required, but the documentation will state that it will be required in a future release. Whenowner
is specified andstate
isstarted
/stopped
, then thelaunchd
module will instead uselaunchctl bootstrap
/launchctl bootout
. Withoutowner
, the old behavior is used but a deprecation warning will be printed. - The
unloaded
/reloaded
states are considered deprecated. Using these states is still supported but a deprecation warning will be printed. Using either state with the newowner
parameter will result in an error. - Introduce the new
enabled
/disabled
states. Note thatowner
is required for these states.
- The
- Future major release:
- The
owner
parameter now becomes a required parameter. - Codepaths for the previous behavior of
state: started
/state stopped
are removed and replaced with the newlaunchctl bootstrap
/launchctl bootout
ones. - The state actions for
unloaded
/reloaded
are also removed.
- The
For the first step, these actions can be spread across any number of minor releases. However, making owner
mandatory and switching to the new behavior should be done in a single major release.
Issue Type
Feature Idea
Component Name
launchd
Code of Conduct
- I agree to follow the Ansible Code of Conduct