#! /bin/sh -e silently () { ## Run the command discarding all of its output. "$@" >/dev/null 2>&1 } restart_services () { ## Restart the services we know about. echo -n "Restarting services:" ## Make sure that the server is actually running. if ! silently tripectl version; then echo " tripe server not running." return 0 fi ## Find out which of our services are actually configured to start. ## We'll assume that a link to the service script is a good indication. need_restart=$(perl -e ' for my $svc (@ARGV) { $svc{$svc} = 1; } for my $link () { next unless -l $link; my $targ = readlink $link; next unless defined $targ; next unless $targ =~ m#/usr/lib/(?:[^/]+/)?tripe/services/([^/]+)#; next unless exists $svc{$1}; print "$link\n"; }' "$@") ## If there's nothing to do then don't bother with the rest. any=nil for svc in $need_restart; do any=t; break; done case $any in nil) echo " none configured."; return 0 ;; esac ## Restart the services. This is more than a little tricky. for svc in $need_restart; do ## Find out about the service. set -- $("$svc" --version) name="$1" version="$2" ## Write some progress. echo -n " $name" ## If there's an instance of the service running already then we ask it ## to quit. This is where everything gets complicated. if silently tripectl svcensure "$name"; then ## So, what we want to do is ask the service to quit, and make sure it ## actually has done before starting the new version. Conveniently, ## the server emits a notification when a service quits. Now all we ## have to do is wait a reasonable time for the notification. ## ## So we read the output of tripectl(1). Of course, to do this, we ## must keep its standard input open, so we'll sleep for a bit. We can ## use this to implement our timeout. The only problem is curtailing ## the wait early if (as we expect) the service actually quits on time. ## The answer is /very/ cheesy: we'll report the process-id of our ## sleep(1) process through the server's notification mechanism. Then, ## when we see the `SVCRELEASE', we kill the sleep(1) and return ## success. if ! { echo "watch n" echo svcsubmit "$name" quit sleep 1& sleepkid=$! echo notify tripe-peer-services.postinst.$$ SLEEPKID=$sleepkid wait $sleepkid || : } | tripectl | { while read line; do case "$line" in "NOTE USER tripe-peer-services.postinst.$$ SLEEPKID="*) sleepkid=${line##*=} ;; "NOTE SVCRELEASE $name") kill $sleepkid exit 0 ;; esac done; exit 1; } then echo -n " (STUCK)" continue fi fi ## Restart the service. Pass `--startup' because (a) the server might ## have started recently, and failed to start our services, and (b) our ## services are (modulo some annoying warning messages) idempotent ## anyway. if ! "$svc" --daemon --startup; then echo -n " (FAILED)"; fi done echo "." } retire_service () { name=$1 version=$2 ## If the service is currently running, then ask it to stop. if tripectl >/dev/null 2>&1 svcensure $name && \ ! tripectl >/dev/null 2>&1 svcensure $name $version~ then tripectl svcsubmit $name quit fi ## Remove the symbolic link if it's there. if [ -L /etc/tripe/services/$name ]; then case $(readlink /etc/tripe/services/$name) in /usr/lib/tripe/services/$name) rm /etc/tripe/services/$name ;; esac fi } case "$1" in configure) v=$2 ## Apply upgrades iteratively until we catch up with reality. while :; do ## Here, we killed the `watch' service. if dpkg --compare-versions "$v" lt-nl 1.0.0pre14~; then retire_service watch 1.0.0pre14 v=1.0.0pre14 ## No more updates to apply. else break fi done ;; esac restart_services conntrack connect #DEBHELPER#