As of Upstart 1.10 (used in Ubuntu 13.10):
Upstart current documenation is at http://upstart.ubuntu.com/cookbook
Cron and anacron functionality has not been implemented in Upstart yet.
Reference: http://upstart.ubuntu.com/cookbook/#run-a-job-periodically
11.26 Run a Job Periodically
This cannot currently be handled by Upstart directly. However, the
"Temporal Events" feature is being worked on now will address this.
Until Temporal Events are available you should either use cron(8), or
something like:
# /etc/init/timer.conf
instance $JOB_TO_RUN
script for var in SLEEP JOB_TO_RUN do
eval val=\${$var}
if [ -z "$val" ]
then
logger -t $0 "ERROR: variable $var not specified"
exit 1
fi done
eval _sleep=\${SLEEP} eval _job=\${JOB_TO_RUN}
while [ 1 ] do
stop $_job || true
sleep $_sleep
start $_job || true done end script
Per-user tasks could refer to either 1) Running a job as a user [Upstart does this] or 2) Emitting and Listening for user-level events instead of system events [Upstart does this, too]
Running a job as a user is described at http://upstart.ubuntu.com/cookbook/#run-a-job-as-a-different-user
11.43.2 Changing User
Some daemons start running as the super-user and then internally
arrange to drop their privilege level to some other (less privileged)
user. However, some daemons do not need to do this: they never need
root privileges so can be invoked as a non-root user.
How do you run a "system job" but have it run as a non-root user then?
As of Upstart 1.4, Upstart has the ability to run a System Job as a
specified user using the setuid and setgid stanzas.
However, if you are not using Upstart 1.4, it is easy to accomplish
the required goal. There are a couple of methods you can use. The
recommended method for Debian and Ubuntu systems is to use the helper
utility start-stop-daemon(8) like this:
exec start-stop-daemon --start -c myuser --exec command
The advantage of using start-stop-daemon(8) is that it simply changes
the user and group the command is run as. This also has an advantage
over su(1) in that su(1) must fork to be able to hold its PAM session
open, and so is harder for upstart to track, whereas
start-stop-daemon(8) will simply exec the given command after changing
the uid/gid.
Another potential issue to be aware of is that start-stop-daemon does
not impose PAM ("Pluggable Authentication Module") limits to the
process it starts. Such limits can be set using the appropriate
Upstart stanzas, you just cannot specify the limits via PAMs
limits.conf(5).
Of course, you may want PAM restrictions in place, in which case you
should either use su(1) or sudo(8), both of which are linked to the
PAM libraries.
The general advice is NOT to use su(1) or sudo(8) though since PAM
restrictions really not appropriate for system services. For example,
PAM will make a wtmp(5) entry every time su(1) or sudo(8) are called
and those records are not appropriate for system services.
If you want to use su(1) or sudo(8), the examples below show you how.
Using su(1):
exec su -s /bin/sh -c command $user
Note that although you could simplify the above to the following, it
is not recommended since if user "$user" is a system account with a
shell specified as /bin/false, the job will not run the specified
command: it will fail due to /bin/false returning "1":
exec su -c command $user
The job will silently fail if user "$user" is a system account with a
shell specified as /bin/false.
To avoid the fork(2) caused by the shell being spawned, you could
instead specify:
exec su -s /bin/sh -c 'exec "$0" "$@"' $user -- /path/to/command
--arg1=foo -b wibble
This technique is particularly useful if your job is a Service Job
that makes use of expect.
A basic example using sudo(8):
exec sudo -u $user command
User-level jobs (called "Session Jobs") are described at http://upstart.ubuntu.com/cookbook/#session-job
4.2.3 Session Job
As of Upstart v1.7
Session Jobs are analogous to the old User Jobs. Unlike the old User
Jobs, Session Jobs are not managed by Upstart running as PID 1 - they
are managed by the users own Session Init.
Unlike when Upstart runs as PID 1, a Session Init can read its Job
Configuration files from multiple directories. The list of directories
jobs are read from is as follows (in order):
$XDG_CONFIG_HOME/upstart/ (or $HOME/.config/upstart/ if $XDG_CONFIG_HOME not set).
$HOME/.init/ (deprecated - supported for legacy User Jobs).
$XDG_CONFIG_DIRS
/usr/share/upstart/sessions/
The name of each job is taken to be the basename when any of the
directory names above have been removed. For example, if a job
configuration file exists as $HOME/.config/upstart/hello/world.conf,
its name will be "hello/world" whereas if a job configuration file
exists as /usr/share/upstart/sessions/foo/bar.conf, its name will be
"foo/bar".
Upstart resolves any name collisions by simply accepting the first
valid job (or override file) that it finds. For example, if the
following two file exist:
$HOME/.init/foo.conf $HOME/.config/upstart/foo.conf
Only the first, $HOME/.init/foo.conf will be used. Whereas if the
following files exist:
$HOME/.init/foo.conf $HOME/.config/upstart/foo.conf
$HOME/.config/upstart/foo.override
Upstart will first read $HOME/.init/foo.conf, and then apply any
changes in $HOME/.config/upstart/foo.override.