-
Notifications
You must be signed in to change notification settings - Fork 13
Outset is controlled by six launchd plists:
/Library/LaunchDaemons/io.macadmins.outset.boot.plist
/Library/LaunchDaemons/io.macadmins.outset.cleanup.plist
/Library/LaunchDaemons/io.macadmins.outset.login-privileged.plist
/Library/LaunchAgents/io.macadmins.outset.login.plist
/Library/LaunchAgents/io.macadmins.outset.login-window.plist
/Library/LaunchAgents/io.macadmins.outset.on-demand.plist
Optionally on macOS 13+ all except login-window
can be managed using the SMAppService framework and the plists are located and loaded from within the app bundle.
Under macOS 13, the following commands are used to interact with Outset's agents:
-
--enable-services
: will check for and load services. If no config profile to manage login items forio.macadmins.Outset
is present this will cause a user notification of a new background process to be approved -
--disable services
: unloads the services. This does not remove the entry from login items which is by design according to Apple -
--service-status
: shows the current service status (Enabled
,Not Registered
,Requires Approval
orNot Found
)
For each folder of items to process, if a file type is present, it always operates on:
- packages
- then scripts
If multiple items of a file type are present in a directory, processing will take place with alphabetical priority.
For all script processing, the current console user (if present) is passed in as the first argument.
This can cause some previously working scripts to hiccup when migrating from Outset 3. An example below covers Python's argparse
library:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("user", metavar="user", nargs=1, help="User to run against, used by outset")
args = parser.parse_args()
print(args)
> Namespace(user=['alice'])
The boot
LaunchDaemon processes packages and scripts during the boot sequence, and will either run once, or at every subsequent boot, depending on the directory in which the files are placed:
/usr/local/outset/boot-once/
/usr/local/outset/boot-every/
When the Mac boots, launchd will run /usr/local/outset/outset --boot
which does the following:
- Verifies that all working directories exist, and creates them if not.
- If the
network_wait
setting is set to True (which is the default setting):- disables the loginwindow process
- waits until the Mac has a valid IP address
- Processes and deletes everything in
/usr/local/outset/boot-once/
- Loads the loginwindow.
- Processes everything in
/usr/local/outset/boot-every/
The login window runs user scripts located in the following directory:
/usr/local/outset/login-window/
Login window scripts are run as root.
When the system is at the login window either after boot or if the user logs out, launchd will run /usr/local/outset/outset --login-window
NOTE
Scripts in this location are always run. For limiting if/when login window scripts are run you will need to provide checks within your scripts to prevent undesired results, e.g. if you wish to run a task on user logout only, not before login.
When the login windows appers after boot, scripts here will run at the same time as boot-every
or boot-once
scripts however order is not guaranteed so the boot scripts may run first or the login-window script may run first. Therefore priority cannot be assumed.
The login
LaunchAgent runs any scripts during user login, and will run either once, or at every subsequent login, depending on the directory in which the files are placed:
/usr/local/outset/login-once/
/usr/local/outset/login-every/
When the user logs in, launchd will run /usr/local/outset/outset --login
which does the following:
- If the user is not in the
ignored_users
array:- Processes everything in
/usr/local/outset/login-once/
in the user context. - Logs the names of all login-once items to
~/Library/Preferences/io.macadmins.Outset.plist
under the keyrun_once
- Processes everything in
/usr/local/outset/login-every/
in the user context.
- Processes everything in
Outset completes the login
run by checking if there are any packages or scripts in the the following directories:
/usr/local/outset/login-privileged-once/
/usr/local/outset/login-privileged-every/
If there are any files defined in these directories, Outset triggers an additional LaunchDaemon to run /usr/local/outset --login-privileged
as root, which does the following:
- If the user is not in the
ignored_users
array:- Processes everything in
/usr/local/outset/login-privileged-once/
in the root context. - Logs the names of all login-privileged-once items to
/Library/Preferences/io.macadmins.Outset.plist
in arun_once-<username>
array where<username>
is the user name of the console user. - Processes everything in
/usr/local/outset/login-privileged-every/
in the root context.
- Processes everything in
When processing items Outset handles each type (all pkgs then scripts) alphanumerically, meaning a file starting with 000
will be evaluated before one that starts with 0a
, after which would be files like AAA
that start with capitalized characters, then lowercase files aaa
.
The on-demand
LaunchAgent and cleanup
LaunchDaemon, respectively, process and remove scripts from the following directory immediately, in the user context, for any currently logged in user (for those using Fast User Switching, it will only run in the current GUI session, and will not run in any background sessions):
/usr/local/outset/on-demand/
When on-demand is initiated, launchd will run /usr/local/outset/outset --on-demand
, which does the following in the current user session only:
- Processes everything in
/usr/local/outset/on-demand/
- Deletes everything in
/usr/local/outset/on-demand/
If you decide you don't want to use Outset any more, these commands should remove all traces of the tool:
sudo launchctl bootout system /Library/LaunchDaemons/io.macadmins.outset.*
sudo rm -fv "/Library/LaunchDaemons/io.macadmins.outset.*"
userID=$(id -u $(whoami))
launchctl bootout gui/$userID /Library/LaunchAgents/io.macadmins.outset.login.plist
launchctl bootout gui/$userID /Library/LaunchAgents/io.macadmins.outset.on-demand.plist
launchctl bootout gui/$userID /Library/LaunchAgents/io.macadmins.outset.login-window.plist
sudo rm -fv /Library/LaunchAgents/io.macadmins.outset.*
sudo rm -rfv /usr/local/outset
sudo pkgutil --forget io.macadmins.Outset
If you decide that you may need to skip a run-once script or ensure that it's not ran when migrating to Outset v4, you can do so with this logic:
/usr/bin/defaults write ~/Library/Preferences/io.macadmins.Outset.plist run_once -dict-add "/usr/local/outset/login-once/SCRIPT_PATH_WITH_ENDING_HERE" -date "1970-01-01 00:00:00 +0000"
If you are running this as root (such as with JAMF or Munki when installing Outset), you'll need to run it as the user in question.
#!/bin/zsh
CURRENTUSER="$( echo 'show State:/Users/ConsoleUser' | /usr/sbin/scutil | /usr/bin/awk '/Name :/ { print $3 }' )"
USERID="$(/usr/bin/id -u "$CURRENTUSER")"
/bin/launchctl asuser $USERID /usr/bin/sudo -u $CURRENTUSER /usr/bin/defaults write /Users/$CURRENTUSER/Library/Preferences/io.macadmins.Outset.plist run_once -dict-add "/usr/local/outset/login-once/SCRIPT_PATH_WITH_ENDING_HERE" -date "1970-01-01 00:00:00 +0000"
Just follow the deployment instructions. The installer will take care updating Outset 3 to Outset 4 and backup any preferences files.
Log files are saved to the logs directory in your outset directory.