Scenario: I need to figure out how to run the /usr/local/bin/RemoteUpdateManager
at DeepFreeze maintenance cycle. During this maintenance cycle, the computers will restart to the login screen and enter a thaw and locked mode for a period of time. As mentioned we do not have a MDM yet, so I created a launch daemon which to my understanding should run the script at boot without requiring any input or to login.
Update.sh
#!/bin/bash
rum=/usr/local/bin/RemoteUpdateManager
if [[ -f $rum ]]; then
echo "Starting Adobe RemoteUpdateManger..."
sudo $rum --action=list #Listing the updates for now, but will install later
else
echo "Adobe RemoteUpdateManager not found."
fi
Based off Adobe's RUM guide, link, you have to use sudo for RemoteUpdateManager
com.test.schedule.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>EnviromentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:</string>
</dict>
<key>Label</key>
<string>com.test.updateschedule</string>
<key>ProgramArguments</key>
<array>
<string>sudo</string>
<string>sh</string>
<string>/Library/Scripts/Updates.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/var/log/EsoUpdateError.log</string>
<key>StandardOutPath</key>
<string>/var/log/EsoUpdate.log</string>
Steps Taken
- Copy update.sh to
/Library/Scripts/
and the .plist to/Library/LaunchDaemons/
sudo chown root:wheel
.shsudo chown root:wheel
.plist.sudo launchctl load -w /Library/LaunchDaemons/.plist
- The moment I load the .plist, it creates two logs at
/var/log/
. The standardoutpath log lists all the updates which is exactly what I want.
Issue
After restarting the computer to see if results stick, I notice that the results cannot be replicated. Instead I receive the following in StandardErrorPath log:
RemoteUpdateManager exiting with Return Code (1)
Based of the RUM guide, Return Code (1) is: "Generic error, for example an internal error. For example, this might be the case where Adobe Application Manager installation is corrupted or network is not present. In this case, typically, the process of downloading or installing updates cannot be started at all."
I went as far to apply chmod 777 and chown root:wheel to both the .sh and .plist, along with `/usr/local/bin/RemoteUpdateManager'. Tried without sudo in the .plist and .sh.
Best Answer
Since the launchd plist is in /Library/LaunchDaemons/ it's going to be run as root. Given that, you don't need to call
sudo
as your first program argument, nor do you need it in the shell script. Also, it's good practice to use full paths in program arguments so/bin/sh
instead ofsh
.That's all just housekeeping though. What I find interesting is that it works when you are logged in as a user but does not work when launchd runs it upon load during restarting. The launchd.plist man page section for
RunAtLoad
has this little warning:For that reason I avoid using
RunAtLoad
true for root level launchd tasks. I suspect what you're seeing is that the system is not ready to run RemoteUpdateManager at the moment when launchd loads your plist.RunAtLoad
is awfully handy, though, so you may have to stick with it, but I'd play around other mechanisms to tell launchd when to run your script. You could try usingStartInterval
60 or something to give the system 60 seconds to fully spin up after loading the plist. That assumes your maintenance window is at least 60 seconds long plus whatever time is needed by your script. An alternative could potentially be to useStartCalendarInterval
but you'd want to be very sure that the maintenance window is rigidly defined in time and not cancellable by your users.You could also keep
RunAtLoad
and useKeepAlive
withSuccessfulExit
true to make launchd keep trying to run your script until it successfully exits. It's not an elegant solution but it may work. If you're doing this make sure to set yourThrottleInterval
to something reasonable or else launchd will complain mercilessly if the task is permanently failing.The last thing to keep in mind is that your plist is going to cause your shell script to be run at EVERY restart. You should incorporate some mechanism in your shell script to detect if you're in a maintenance period and
exit 0
if not.