Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I am using upstart instance jobs to start few of my services. The jobs are meant to have one instance per user i.e they take in the user name as the instance parameter. I have also configured them to be respawned by upstart. The respawning works. Here is what my config file looks like

start on runlevel [2345]
stop on runlevel [06]

normal exit 0

respawn
respawn limit 5 300
instance $user

chdir /home/talha/syncservice/
script
   exec python sync.py $user
end script

The issue is that I want these instance jobs to be restarted on system reboot. Obviously I cannot pass in all the usernames as the instance parameters on reboot as I do not know what and how many instances were spawned last time.

Is there a way that upstart can persist its state tables for instance jobs across reboots. Why I assume that there are some "state table"?, is because I assume that upstart keeps a track of all the running instance jobs. There would be a state table that tracks which instance to respawn when it crashes. Otherwise it wont be able to respawn an instance job. So if those tables can be made persistent across reboots my problem will be solved.

Can the persistence be somehow achieved.? Where does upstart keep the track of its running jobs? Is it only in memory or a file?

If that cannot be done, that means that the stanza

start on runlevel[2345]

has no meaning or benefit for instance jobs.

share|improve this question

2 Answers 2

up vote 1 down vote accepted

You could save the list of users to a file (user-sync.list in this example). To restore the user scripts you could use a for loop in a bash script that's run by root at boot. Where your init script is called user-sync:

#!/bin/sh
# /root/restore-user-sync.sh
for user in `cat user-sync.list`; do start user-sync user=$user; done

Add that to crontab, as root:

$ crontab -e

In the cron file:

@reboot /root/restore-user-sync.sh

Maintaining the list of active users is the most involved part. You could have the python script do that, or you could do it as part of the Upstart script:

# /etc/init/user-sync.conf

start on runlevel [2345]
stop on runlevel [06]

normal exit 0

respawn
respawn limit 5 300
instance $user

chdir /home/talha/syncservice/

pre-start script
    # if $user doesn't already exist in list, add $user to list
    if ! grep $user user-sync.list; then echo $user >> user-sync.list; fi
end script

script
   exec python sync.py $user
end script

pre-stop script
    # remove line(s) from list that exactly match $user
    sed -i "/\b$user\b/d" user-sync.list
end script

You might be able to substitute $USER (which is automatically defined as the current username) for $user, otherwise when you call the upstart script you'll need to pass the username as a parameter:

sudo start user-sync user=myusername
share|improve this answer
    
This solution make the whole upstart system meaningless, as the job startup time would depend on cron, and not on events generated by upstart. –  komuta Aug 22 at 6:32
    
It may not be optimal, however it does accomplish what was requested. Using Upstart still has meaning during normal operation because of the respawn directives. You are welcome to implement the user persistence completely within Upstart if you wish, otherwise I'll revisit this when I have some free time. –  thinkmassive Aug 22 at 12:29

I would definitely lean away from getting under upstart's hood. You can do this another way.

The Cookbook's section on the instance stanza has some example of how to do things like this. I do something like this with multiple PostgreSQL instances; see this answer.

The basic idea here is to create what I call a "pony engine" job that starts all your instance jobs. In your case you could have it iterate through the sub-directories of /home, or keep a separate conf file that lists users you want the service to run for. For each user start a sync.py instance.

You are correct that the start on/stop on is useless in the instance job. Move it to the "pony engine" job.

Unfortunately I don't have access to a Linux box right now, but see the aforementioned answer for examples.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.