4

Upstart FAQ says:

Will Upstart replace cron, atd or anacron?

Yes. A planned feature for Upstart is the ability to generate events at a particular scheduled time, regular scheduled time or particular timed intervals.

However, the bottom of the page says it was written in 2009. Are these planned features in place yet, and is in practical to use upstart instead of anacron?

Also, can upstart handle per-user tasks out of the box (unlike anacron, for instance)?

Eric Carvalho
  • 55,453

1 Answers1

2

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.

user535733
  • 68,493