A better package

The files we created in debian/ so far would create a working package. But we want a package that doesn't fail lintian, and that starts the daemon at install time if possible.

  1. A manpage for Resamad

    Every executable needs a man page. So we have one generated from resamad.8.xml, which is not shown here. It's too lengthy, and it's just docbook XML that generates a manpage one could easily write by hand.

  2. Getting Noninteractive at Install

    We use debconf. This way, the package can be provided with the name of RES AM Dispatchers at configuration time. At install time, it will then start the daemon and contact a dispatcher without asking questions. A few files are needed: debian/config

    #!/bin/sh -e
    
    # Source debconf library.
    . /usr/share/debconf/confmodule
    
    # Ask question
    db_input medium res-am-agent/dispatcherlist || true
    db_go
    	  

    debian/templates

    Template: res-am-agent/dispatcherlist
    Type: string
    Default:
    Description: comma-separated list of dispatcher host names:
     The agent needs to contact a dispatcher that will tell it what to do.
     Fill in a comma separated list of host names or IP numbers of dispatchers to use.
     If this is left blank, the daemon will try to start in autodetection mode.
    	  

  3. An Ubuntu Start/Stop Script

    The /etc/init.d/resamad provided with the Red Hat package is a bit on the lean side for Ubuntu. We don't install it. Instead, our package provides /etc/init.d/res-am-agent, which we offer to the packaging toolchain as debian/init.d:

    
    #!/bin/sh
    ### BEGIN INIT INFO
    # Provides:          res-am-agent
    # Required-Start:    $network $remote_fs
    # Required-Stop:     $remote_fs
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # Short-Description: RES Automation Manager Agent
    # Description:       RES Automation Manager Agent,
    #                    a daemon that brings the machine under
    #                    control of a RES Automation Manager server
    ### END INIT INFO
    
    # Author: Jurjen Bokma <j.bokma@rug.nl>
    
    # PATH should only include /usr/* if it runs after the mountnfs.sh script
    PATH=/sbin:/bin:/usr/sbin:/usr/bin
    DESC=res-am-agent             # Introduce a short description here
    NAME=res-am-agent             # Introduce the short server's name here
    DAEMON=/usr/sbin/resamad   # Introduce the server's location here
    DAEMON_ARGS=""             # Arguments to run the daemon with
    #PIDFILE=/var/run/$NAME.pid
    PIDFILE=/etc/res/resamad.pid
    SCRIPTNAME=/etc/init.d/$NAME
    
    # Exit if the package is not installed
    [ -x $DAEMON ] || exit 0
    
    # Read configuration variable file if it is present
    [ -r /etc/default/$NAME ] && . /etc/default/$NAME
    
    # Load the VERBOSE setting and other rcS variables
    . /lib/init/vars.sh
    
    . /lib/lsb/init-functions
    
    #
    # Function that starts the daemon/service
    #
    do_start()
    {
            # Return
            #   0 if daemon has been started
            #   1 if daemon was already running
            #   2 if daemon could not be started
            start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
                    || return 1
            start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
                    $DAEMON_ARGS \
                    || return 2
            # Add code here, if necessary, that waits for the process to be ready
            # to handle requests from services started subsequently which depend
            # on this one.  As a last resort, sleep for some time.
    }
    
    #
    # Function that stops the daemon/service
    #
    do_stop()
    {
            # Return
            #   0 if daemon has been stopped
            #   1 if daemon was already stopped
            #   2 if daemon could not be stopped
            #   other if a failure occurred
            start-stop-daemon --stop --quiet --retry=TERM/5/KILL/3 --pidfile $PIDFILE --exec ${DAEMON}
            RETVAL="$?"
            [ "$RETVAL" = 2 ] && return 2
            # Many daemons don't delete their pidfiles when they exit.
            rm -f $PIDFILE
            return "$RETVAL"
    }
    case "$1" in
      start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
        do_start
        case "$?" in
                    0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                    2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
            esac
      ;;
      stop)
            [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
            do_stop
            case "$?" in
                    0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                    2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
            esac
            ;;
      status)
           status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
           ;;
      #reload|force-reload)
            # not suported by daemon
      restart|force-reload)
            #
            # If the "reload" option is implemented then remove the
            # 'force-reload' alias
            #
            log_daemon_msg "Restarting $DESC" "$NAME"
            do_stop
            case "$?" in
              0|1)
                    do_start
                    case "$?" in
                            0) log_end_msg 0 ;;
                            1) log_end_msg 1 ;; # Old process is still running
                            *) log_end_msg 1 ;; # Failed to start
                    esac
                    ;;
              *)
                    # Failed to stop
                    log_end_msg 1
                    ;;
            esac
            ;;
      *)
            #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
            echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
            exit 3
            ;;
    esac
    
    :
    
    	  

  4. {pre,post}{install,rm}

    The pre- and post-install and -remove files are run at package installation, deinstallation, replacement etc. etc..

    debian/preinst:

    
    #!/bin/sh
    # preinst script for res-am-agent
    #
    # see: dh_installdeb(1)
    
    set -e
    
    case "$1" in
        install)
            # This is a kludge to get around that soname difference of libssl:
    	# symlink to libssl0.9.8, on which the package depends
            [ -e /lib/x86_64-linux-gnu/libssl.so.6 ] || ln -s libssl.so.0.9.8 /lib/x86_64-linux-gnu/libssl.so.6
        ;;
        upgrade)
        ;;
    
        abort-upgrade)
        ;;
    
        *)
            echo "preinst called with unknown argument \1'" >&2
            exit 1
        ;;
    esac
    
    # dh_installdeb will replace this with shell code automatically
    # generated by other debhelper scripts.
    
    #DEBHELPER#
    
    exit 0
    
    
    	

    debian/postinst:

    
    #!/bin/sh
    
    set -e
    
    . /usr/share/debconf/confmodule
    
    case "$1" in
        configure)
            db_get res-am-agent/dispatcherlist
            if [ -n "$RET" ]; then
    	    # If we know of any dispatchers through debconf,
    	    # start the daemon, and use the first in the list
    	    # This also uses the expect script we created
                DISPATCHERS="${RET}" /usr/share/res-am-agent/init-resamad.exp
            fi
        ;;
    
        abort-upgrade|abort-remove|abort-deconfigure)
        ;;
    
        *)
            echo "postinst called with unknown argument \1'" >&2
            exit 1
        ;;
    esac
    
    # dh_installdeb will replace this with shell code automatically
    # generated by other debhelper scripts.
    
    #DEBHELPER#
    
    exit 0
    
    
    	

    debian/prerm:

    
    #!/bin/sh
    # prerm script for res-am-agent
    #
    # see: dh_installdeb(1)
    
    set -e
    
    case "$1" in
        remove|upgrade|deconfigure)
            /etc/init.d/res-am-agent stop
        ;;
    
        failed-upgrade)
        ;;
    
        *)
            echo "prerm called with unknown argument \1'" >&2
            exit 1
        ;;
    esac
    
    # dh_installdeb will replace this with shell code automatically
    # generated by other debhelper scripts.
    
    #DEBHELPER#
    
    exit 0
    
    	

    debian/postrm:

    
    #!/bin/sh
    # postrm script for res-am-agent
    #
    # see: dh_installdeb(1)
    
    set -e
    
    case "$1" in
        purge|remove|abort-install|disappear)
            # Remove that ugly symlink if we are really being removed
            if [ -L /lib/x86_64-linux-gnu/libssl.so.6 ] ; then
                rm -f /lib/x86_64-linux-gnu/libssl.so.6
            fi
            ;;
        upgrade|failed-upgrade|abort-upgrade)
            ;;
    
        *)
            echo "postrm called with unknown argument \1'" >&2
            exit 1
            ;;
    esac
    
    case "$1" in
        purge)
            rm -f /etc/res/resamad.xml
            ;;
    esac
    
    # dh_installdeb will replace this with shell code automatically
    # generated by other debhelper scripts.
    
    #DEBHELPER#
    
    exit 0