chiark / gitweb /
debian/tripe-peer-services.postinst: Retire the old `watch' service.
[tripe] / debian / tripe-peer-services.postinst
1 #! /bin/sh -e
2
3 silently () {
4   ## Run the command discarding all of its output.
5   "$@" >/dev/null 2>&1
6 }
7
8 restart_services () {
9   ## Restart the services we know about.
10
11   echo -n "Restarting services:"
12
13   ## Make sure that the server is actually running.
14   if ! silently tripectl version; then
15     echo " tripe server not running."
16     return 0
17   fi
18
19   ## Find out which of our services are actually configured to start.
20   ## We'll assume that a link to the service script is a good indication.
21   need_restart=$(perl -e '
22           for my $svc (@ARGV) { $svc{$svc} = 1; }
23           for my $link (</etc/tripe/services/*>) {
24             next unless -l $link;
25             my $targ = readlink $link;
26             next unless defined $targ;
27             next unless $targ =~
28               m#/usr/lib/(?:[^/]+/)?tripe/services/([^/]+)#;
29             next unless exists $svc{$1};
30             print "$link\n";
31           }' "$@")
32
33   ## If there's nothing to do then don't bother with the rest.
34   any=nil
35   for svc in $need_restart; do any=t; break; done
36   case $any in nil) echo " none configured."; return 0 ;; esac
37
38   ## Restart the services.  This is more than a little tricky.
39   for svc in $need_restart; do
40
41     ## Find out about the service.
42     set -- $("$svc" --version)
43     name="$1" version="$2"
44
45     ## Write some progress.
46     echo -n " $name"
47
48     ## If there's an instance of the service running already then we ask it
49     ## to quit.  This is where everything gets commplicated.
50     if silently tripectl svcensure "$name"; then
51
52       ## So, what we want to do is ask the service to quit, and make sure it
53       ## actually has done before starting the new version.  Conveniently,
54       ## the server emits a notification when a service quits.  Now all we
55       ## have to do is wait a reasonable time for the notification.
56       ##
57       ## So we read the output of tripectl(1).  Of course, to do this, we
58       ## must keep its standard input open, so we'll sleep for a bit.  We can
59       ## use this to implement our timeout.  The only problem is curtailing
60       ## the wait early if (as we expect) the service actually quits on time.
61       ## The answer is /very/ cheesy: we'll report the process-id of our
62       ## sleep(1) process through the server's notification mechanism.  Then,
63       ## when we see the `SVCRELEASE', we kill the sleep(1) and return
64       ## success.
65       if ! { echo "watch n"
66              echo svcsubmit "$name" quit
67              sleep 1& sleepkid=$!
68              echo notify tripe-peer-services.postinst.$$ SLEEPKID=$sleepkid
69              wait $sleepkid || :
70            } |
71            tripectl |
72            { while read line; do
73                case "$line" in
74                  "NOTE USER tripe-peer-services.postinst.$$ SLEEPKID="*)
75                    sleepkid=${line##*=}
76                    ;;
77                  "NOTE SVCRELEASE $name")
78                    kill $sleepkid
79                    exit 0
80                    ;;
81                esac
82              done; exit 1; }
83       then
84         echo -n " (STUCK)"
85         continue
86       fi
87     fi
88
89     ## Restart the service.  Pass `--startup' because (a) the server might
90     ## have started recently, and failed to start our services, and (b) our
91     ## services are (modulo some annoying warning messages) idempotent
92     ## anyway.
93     if ! "$svc" --daemon --startup; then echo -n " (FAILED)"; fi
94   done
95   echo "."
96 }
97
98 retire_service () {
99   name=$1 version=$2
100
101   ## If the service is currently running, then ask it to stop.
102   if tripectl >/dev/null 2>&1 svcensure $name && \
103      ! tripectl >/dev/null 2>&1 svcensure $name $version~
104   then
105     tripectl svcsubmit $name quit
106   fi
107
108   ## Remove the symbolic link if it's there.
109   if [ -L /etc/tripe/services/$name ]; then
110     case $(readlink /etc/tripe/services/$name) in
111       /usr/lib/tripe/services/$name)
112         rm /etc/tripe/services/$name
113         ;;
114     esac
115   fi
116 }
117
118 case "$1" in
119   configure)
120     v=$2
121
122     ## Apply upgrades iteratively until we catch up with reality.
123     while :; do
124
125       ## Here, we killed the `watch' service.
126       if dpkg --compare-versions "$v" lt-nl 1.0.0pre14~; then
127         retire_service watch 1.0.0pre14
128         v=1.0.0pre14
129
130       ## No more updates to apply.
131       else
132         break
133       fi
134     done
135     ;;
136 esac
137
138 restart_services conntrack connect
139
140 #DEBHELPER#