Last week's sojourn with Leopard gave me a chance to learn about some new ways of performing common system administration tasks. I've already written about using iCal in place of cron. I also had a chance to get acquainted with launchctl.
I have some custom web app servers which need to launch at system startup, and which need to be restarted if they fail. (I guess I could launch them from within Apache...)
The last time I needed to launch anything at system startup on OS X,
/Library/StartupItems was in vogue. It's still usable, but now launchctl and
/Library/LaunchDaemons et al are recommended in its place. As the launchd man page states:
In Darwin it is preferable to have your daemon launch via launchd instead of modifying rc or creating a SystemStarter Startup Item.
At some point my web apps may be deployed on Linux. So instead of going all the way with launchctl I decided to introduce supervisor into the mix: use launchctl to keep supervisor running, and use supervisor to keep the custom services running.
Of course this is a stupid thing to do. Both launchctl and supervisor are intended for the same types of problems. But supervisor will be available on Linux whereas, presumably, launchd will not. This is as good a place as any to learn how to use supervisor.
Besides, I have a long history of solving problems in ways which are almost, but not quite, entirely incorrect.
After much bumbling about, this became the plist script which would get supervisor up and running at system boot:
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd > <plist version='1.0'> <dict> <key>Label</key><string>com.agendaless.supervisor</string> <key>ProgramArguments</key> <array> <string> /Library/Frameworks/Python.framework/Versions/Current/bin/supervisord </string> </array> <key>Debug</key><true/> <key>RunAtLoad</key><true/> <key>KeepAlive</key><true/> </dict>
This script is installed as
/Library/LaunchDaemons/com.agendaless.supervisord.plist. As the launchctl.plist man page says, that's the place for "System wide daemons provided by the administrator."
Both the name of the plist file and the value of the
Label are based on the domain of the copyright owner for supervisor: http://www.agendaless.com/
ProgramArguments consist solely of the path to the supervisord executable.
RunAtLoad ensures that supervisor is started as soon as it is loaded.
Debug to true increases the odds that, if some problem arises in running supervisor, the problem will be noted in the system log.
KeepAlive ensures that, if supervisor dies, it will be restarted. (KeepAlive is not documented in the OS X 10.4 man pages; it may make sense only for OS X 10.5. I need to re-read the blog where I saw it mentioned to better understand its intended use.)
I'm still such a novice with supervisor (not to mention launchctl) that I'm not sure supervisor meets the expectations of launchctl. But in any case, the above seems to work.