chiark / gitweb /
debian/tripe-peer-services.postinst: New script to restart services.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 12 Jul 2013 23:49:00 +0000 (00:49 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 13 Jul 2013 15:48:42 +0000 (16:48 +0100)
When the TrIPE suite is upgraded, the service package isn't usually in a
fit state when the server is restarted, so the services don't start
properly.  The answer is to have the services restarted explicitly by
their own `postinst' script.

Makefile.am
debian/tripe-peer-services.postinst [new file with mode: 0644]

index d86ec32..dbfa512 100644 (file)
@@ -137,6 +137,7 @@ EXTRA_DIST          += debian/python-tripe.install
 
 ## peer services
 EXTRA_DIST             += debian/tripe-peer-services.install
+EXTRA_DIST             += debian/tripe-peer-services.postinst
 
 ## monitor
 EXTRA_DIST             += debian/tripemon.install
diff --git a/debian/tripe-peer-services.postinst b/debian/tripe-peer-services.postinst
new file mode 100644 (file)
index 0000000..870ba1a
--- /dev/null
@@ -0,0 +1,100 @@
+#! /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 (</etc/tripe/services/*>) {
+           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 commplicated.
+    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#