#! /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 "." } restart_services conntrack connect watch #DEBHELPER#