It’s well known and documented that the usual way to define a daemon or long-running process with Upstart is to use the exec stanza, so that Upstart knows the pid of the daemon, can supervise it when used with the respawn process and can send appropriate signals to its process group to stop it again.
But what do you do when the job just doesn’t fit that pattern? Perhaps the procedure for starting and stopping is particularly custom or complicated, or perhaps there’s no process at all and the purpose of the job is simply to toggle some state or kernel setting.
Fortunately Upstart allows you to do this. The exec or script keywords are in fact optional in a job, it’s perfectly acceptable to omit them. To perform the work you need to do, you can use the pre-start and post-stop keywords instead.
For example, here’s a job that wraps a System-V style init script:
pre-start exec /etc/init.d/scriptname start post-stop exec /etc/init.d/scriptname stop
The start command will result in the init script being run with the start argument thus starting the daemon (or failing which will cause the command to error). Upstart won’t know the pid but it will report it’s in the running state. And the stop command will result in the init script being run with the stop argument.
You can use the same pattern with shell-scripts, for example, here’s a script to manage firewalls:
pre-start script iptables -t nat -F POSTROUTING iptables -t nat -P POSTROUTING DROP iptables -t nat -A POSTROUTING... end script post-stop script iptables -t nat -F POSTROUTING iptabels -t nat -P POSTROUTING ACCEPT end script
As you can see, this approach is quite flexible.