5

I've an OpenERP server running on one of my servers. It's started by a traditional /etc/init.d/ script. It uses a PostgreSQL database and needs a manual restart every time PostgreSQL is restarted.

Every time Ubuntu releases a security update for PostgreSQL, my OpenERP server becomes non-functional until I ssh to the server and manually run sudo /etc/init.d/my-openerp restart. I usually forget to do that after I do the sudo apt-get upgrade.

Can I configure upstart to do that for me, every time postgresql is restarted by apt?

3
  • Will start on started posgre and stop on stopped postgre work for you? It will start/stop my-openerp always on started/stopped postgre and not only after upgrade. Please not that I don't know what is the exact name of PostgeSQL server Upstart configuration file. Feb 13, 2013 at 19:51
  • It would appear that PostgreSQL doesn't have an Upstart file in 12.04, and is instead started by /etc/init.d/postgresql. Feb 14, 2013 at 6:56
  • Note to self: code.launchpad.net/~florent.x/openobject-server/… aims to fix the actual problem (OpenERP not reconnecting). Feb 14, 2013 at 15:57

3 Answers 3

4

Since the postgresql server is still using deprecated System-V init script there are two options:

  • Emit events from the existing System-V init script
  • Port existing System-V init script to upstart job

In both cases you can use start on started-postgresql and stop on stopping-postgresql in your job. As mentioned in the comment my-openerp will start/stop always on started/stopped postgresql and not only after upgrade.

If you opt for emitting events from the existing System-V init script you will need to add in /etc/init.d/postgresql:

# just before the service is started
initctl emit starting-postgresql
# just after the service is started
initctl emit started-postgresql 
# just before stopping the service
initctl emit stopping-postgresql
# just after the service is stopped
initctl emit stopped-postgresql

For details see Helpful Tips in Writing Services section on Ubuntu Boot up Howto page.

In case that you opt for creating Upstart job the simplest configuration might look like this:

start on runlevel [2345]
stop on runlevel [016]
respawn

exec su -c "/etc/postgresql/bin/postgres -D /usr/local/pgsql/data" postgres

More elaborated Upstart config can be found here.

I would play around and instead of starting postgresql on runlevel [2345] perhaps say

start on filesystem and net-device-up IFACE!=lo

or

start on started networking

You might also consider adding kill timeout stanza

kill timeout 300
3

To elaborate on schkovich's first option, here's a simple modification to the System V /etc/init.d/postgresql script.

So whenever postgres is sent "start/restart"/"reload"/"force-restart", I send the "starting-postgresql" event before the command is issued, and the "started-postgresql" after its finished. Similarly, with "stop", I send the "stopping-postgresql" event before the command and "stopped-postgresql" after its issued.

I'm only showing the final case block (case "$1" in [...] esac at the bottom of the script. To make the changes clearer (in case future versions of postgres modify the system-V script, I've highlighted the lines that need to be inserted by putting them between #### BEGIN emit-upstart-event and #### END emit-upstart-event.

case "$1" in
    start|stop|restart|reload)
        if [ -z "`pg_lsclusters -h`" ]; then
            log_warning_msg 'No PostgreSQL clusters exist; see "man pg_createcluster"'
            exit 0
        fi
        #### BEGIN emit-upstart-event
        case "$1" in
            start|restart|reload)
                initctl emit starting-postgresql
            ;;
            stop)
                initctl emit stopping-postgresql
            ;;
        esac
        #### END emit-upstart-event
        for v in $versions; do
            $1 $v || EXIT=$?
        done
        #### BEGIN emit-upstart-event
        case "$1" in
            start|restart|reload)
                initctl emit started-postgresql
            ;;
            stop)
                initctl emit stopped-postgresql
            ;;
        esac
        #### END emit-upstart-event
        exit ${EXIT:-0}
        ;;
    status)
        LS=`pg_lsclusters -h`
        # no clusters -> unknown status                                                                                                                                                                                                                  
        [ -n "$LS" ] || exit 4
        echo "$LS" | awk 'BEGIN {rc=0} {if (match($4, "down")) rc=3; printf ("%s/%s (port %s): %s\n", $1, $2, $3, $4)}; END {exit rc}'
        ;;
    force-reload)
        #### BEGIN emit-upstart-event
        initctl emit starting-postgresql
        #### END emit-upstart-event
        for v in $versions; do
            reload $v
    done
        #### BEGIN emit-upstart-event
        initctl emit started-postgresql
        #### END emit-upstart-event
    ;;
    *)
        echo "Usage: $0 {start|stop|restart|reload|force-reload|status} [version ..]"
    exit 1
    ;;
esac

If you want to handle restarting with all the proper signals (by splitting restart into a stop and start commands) you can do:

case "$1" in
    restart)
        ### HANDLING restart as a stop event and then a start event.
        if [ -z "`pg_lsclusters -h`" ]; then
            log_warning_msg 'No PostgreSQL clusters exist; see "man pg_createcluster"'
            exit 0
        fi
        initctl emit stopping-postgresql
        for v in $versions; do
            stop $v || EXIT=$?
        done
        initctl emit stopped-postgresql
        initctl emit starting-postgresql
        for v in $versions; do
            start $v || EXIT=$?
        done
        initctl emit started-postgresql
        ### END HANDLING restart separately
    start|stop|reload)
        if [ -z "`pg_lsclusters -h`" ]; then
            log_warning_msg 'No PostgreSQL clusters exist; see "man pg_createcluster"'
            exit 0
        fi
        #### BEGIN emit-upstart-event
        case "$1" in
            start|reload)
                initctl emit starting-postgresql
            ;;
            stop)
                initctl emit stopping-postgresql
            ;;
        esac
        #### END emit-upstart-event
        for v in $versions; do
            $1 $v || EXIT=$?
        done
        #### BEGIN emit-upstart-event
        case "$1" in
            start|reload)
                initctl emit started-postgresql
            ;;
            stop)
                initctl emit stopped-postgresql
            ;;
        esac
        #### END emit-upstart-event
        exit ${EXIT:-0}
        ;;
    status)
        LS=`pg_lsclusters -h`
        # no clusters -> unknown status                                                                                                                                                                                                                  
        [ -n "$LS" ] || exit 4
        echo "$LS" | awk 'BEGIN {rc=0} {if (match($4, "down")) rc=3; printf ("%s/%s (port %s): %s\n", $1, $2, $3, $4)}; END {exit rc}'
        ;;
    force-reload)
        #### BEGIN emit-upstart-event
        initctl emit starting-postgresql
        #### END emit-upstart-event
        for v in $versions; do
            reload $v
    done
        #### BEGIN emit-upstart-event
        initctl emit started-postgresql
        #### END emit-upstart-event
    ;;
    *)
        echo "Usage: $0 {start|stop|restart|reload|force-reload|status} [version ..]"
    exit 1
    ;;
esac
3
  • Thanks for posting the whole thing like this! If the postgres server is restarted, shouldn’t there be “stopping-postgresql” and “stopped-postgresql” events emitted before the restart? Otherwise, services that would be disrupted by a postgres restart might try to talk to the database while it’s restarting.
    – bdesham
    Aug 14, 2015 at 14:07
  • @bdesham - The problem with restart is the script runs restart 9.2 as one command in between which both stops and starts postgres. So sending emitting a stopping / stopped / starting signal before hand isn't right -- ideally you'd emit a stopping, call stop, then emit stopped, then emit starting, and then call starting. It wouldn't be too difficult to modify the script to do this.
    – dr jimbob
    Aug 14, 2015 at 19:50
  • @bdesham - Edit the answer to reflect this. The signals are still possibly wrong for reload (only getting starting / started signals, which may not be the most appropriate way to handle).
    – dr jimbob
    Aug 14, 2015 at 19:58
0

I wrote s a script in which I made a -system-update function, which stops openerp, updates the system by apt-get upgrade, then starts openerp, then restart web-client in case of version < 6.1. Problem is that it requires you use the script to update your server. I didn't use an alias.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .