Commit | Line | Data |
---|---|---|
101acb51 MW |
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 | |
904828ef | 49 | ## to quit. This is where everything gets complicated. |
101acb51 MW |
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 | ||
a78cb349 MW |
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 | ||
d64ce4ae | 138 | restart_services conntrack connect |
101acb51 MW |
139 | |
140 | #DEBHELPER# |