| 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 complicated. |
| 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# |