source: trunk/debathena/config/auto-update/debian/athena-auto-update @ 24376

Revision 24376, 5.8 KB checked in by jdreed, 14 years ago (diff)
In auto-update: * Create a status file (/var/lib/athena-update-status) that can be easily queried with athinfo. The file contains the timestamp of the last successful update, the timestamp of the last attempted update, the status of the last attempted update, and any addition status messages.
Line 
1#!/bin/sh
2
3complain() {
4  logger -t "$(hostname --fqdn)" -p user.notice "update: $*"
5  updstatus="failed"
6  updmsg="$*"
7}
8
9save_success() {
10  updstatus="ok"
11  updmsg=$1
12}
13
14save_state() {
15  rm -f $statfile
16  echo "$updlast|$(date)|$updstatus|$updmsg" > $statfile
17
18
19maybe_reboot() {
20  if [ -f /var/run/reboot-required ]; then
21    # A package wants us to reboot the machine.  Do so if no one is
22    # logged in.  Be paranoid about stale utmp entries.
23    ttys=$(w -h -s | awk '{print $2}')
24    for tty in $ttys; do
25      pids=$(ps --no-heading -j -t "$tty" 2>/dev/null \
26             | awk '($1 == $3) {print $1}')
27      if [ -n "$pids" ]; then
28        return
29      fi
30    done
31    # screen processes count as logins.
32    if pgrep '^screen' > /dev/null; then
33      return
34    fi
35    save_state
36    reboot
37    exit
38  fi
39}
40
41if [ 0 != "$(id -u)" ]; then
42  echo "This script must be run as root." >&2
43  exit 1
44fi
45
46# Don't run updates during a cluster login.
47if [ -e /var/run/athena-login ]; then
48  exit 0
49fi
50
51# Avoid confusing the system by running two updates at once.
52pidfile=/var/run/athena-update.pid
53if [ -e $pidfile ]; then
54  if ! kill -0 "$(cat $pidfile)" 2>/dev/null; then
55    rm -f $pidfile
56  fi
57fi
58(set -o noclobber; echo $$ > $pidfile) 2>/dev/null || exit
59
60trap 'rm -f $pidfile' EXIT
61
62statfile="/var/lib/athena-update-status"
63updstatus="unknown"
64updmsg=""
65updlast=$(date)
66
67# Get the last successful update
68if [ -f $statfile ]; then
69    updlast=$(awk -F\| '{print $1;}' $statfile)
70fi
71
72# Make sure nothing expects input on stdin.
73exec </dev/null
74
75# Redirect further output to a log file.
76exec >>/var/log/athena-update 2>&1
77
78# Write a log header now and a footer at exit.
79# Also write a target for cluster's /etc/nologin symlink.
80echo "-----"
81echo "** Beginning Athena auto-update at $(date)"
82
83cat > /var/run/athena-nologin << NOLOGIN
84This system is currently taking software updates.
85Please log in to a different system.
86NOLOGIN
87
88finish() {
89    echo "** Ending Athena auto-update at $(date)"
90    echo "-----"
91    echo
92    rm -f $pidfile
93    rm -f /var/run/athena-nologin
94    save_state
95    exit
96}
97trap finish EXIT
98
99v() {
100  echo "** Running:" "$@"
101  "$@"
102}
103
104
105# Allow hesiod cluster info to specify the debathena apt release.
106# (Will do nothing if debathena-clusterinfo isn't installed.)
107[ -x /usr/sbin/save-cluster-info ] && v /usr/sbin/save-cluster-info
108cinfo=/var/run/athena-clusterinfo.sh
109slist=/etc/apt/sources.list.d/debathena.clusterinfo.list
110if [ -r "$cinfo" ] && ( [ ! -e "$slist" ] || [ -w "$slist" ] ); then
111  echo "** Updating debathena.clusterinfo.list"
112  [ -e "$slist" ] && rm "$slist"
113  dsource="$(egrep -h '^deb(-src)? http://debathena\.mit\.edu/apt ' /etc/apt/sources.list /etc/apt/sources.list.d/*.list 2>/dev/null | sort -u)"
114  if [ -n "$dsource" ]; then
115    (. $cinfo
116     echo "# This file is automatically updated by debathena-auto-update"
117     echo "# based on your Hesiod cluster information. If you want to"
118     echo "# make changes, do so in another file."
119     echo
120     case $APT_RELEASE in
121       production)  ;;
122       proposed)    echo "$dsource" | awk '$3 !~ /-/ {$3 = $3 "-proposed"; print}' ;;
123       development) echo "$dsource" | awk '$3 != /-/ {$3 = $3 "-proposed"; print}'
124                    echo "$dsource" | awk '$3 != /-/ {$3 = $3 "-development"; print}' ;;
125     esac
126    ) > $slist
127  else
128    echo "Never mind, I can't figure out which sources.list line is Debathena's"
129  fi
130else
131  echo "** Skipping update of debathena.clusterinfo.list"
132fi
133
134# Tell apt not to expect user input during package installation.
135export DEBIAN_FRONTEND=noninteractive
136
137# Configure any unconfigured packages (Trac #407)
138if ! v dpkg --configure -a; then
139  complain "Failed to configure unconfigured packages."
140  exit
141fi 
142
143# A recently configured package may want a reboot
144save_success "Rebooted after dpkg --configure -a"
145maybe_reboot
146
147# Update the aptitude cache.
148if ! v aptitude --quiet --assume-yes update; then
149  complain "aptitude update failed"
150  exit
151fi
152
153# Exit quietly (except for perhaps rebooting) if there are no upgrades
154# to take.
155pattern='^0 packages upgraded, 0 newly installed, 0 to remove'
156if v aptitude --simulate --assume-yes full-upgrade | grep -q "$pattern"; then
157  echo "Nothing to do!"
158  save_success "No updates"
159  maybe_reboot
160  exit
161fi
162
163# Download packages first.
164if ! v aptitude --quiet --assume-yes --download-only full-upgrade; then
165  complain "download failed"
166  exit
167fi
168
169# If the debathena-reactivate package is installed, call into the
170# login snapshot script to create a root snapshot for the next update.
171if [ -x /usr/sbin/athena-login-snapshot ]; then
172  echo "** Creating root snapshot"
173  /usr/sbin/athena-login-snapshot update-start
174fi
175
176# Perform the update.  In some corner cases, aptitude might decide
177# that the best course of action is to remove the Debathena
178# metapackage, so be paranoid about that.
179v aptitude --quiet --assume-yes keep-all
180v aptitude --quiet --assume-yes --download-only dist-upgrade
181if result=$(aptitude -F "%p" search '~i!~VTARGET(^debathena-cluster$ | ^debathena-workstation$ | ^debathena-login$ | ^debathena-standard$ | ^openafs-modules-~D^linux-image-)')
182  [ -n "$result" ]; then
183  echo "** metapackages would be removed by the update, aborting:" $result
184  v aptitude --quiet --assume-yes keep-all
185  complain "metapackages would be removed by update:" $result
186elif result=$(aptitude -F "%p" search '~b')
187  [ -n "$result" ]; then
188  echo "** packages would be broken by the update, aborting:" $result
189  v aptitude --quiet --assume-yes keep-all
190  complain "packages would be broken by update:" $result
191else
192  v aptitude --quiet --assume-yes install
193  # Successful update, reset $updlast
194  updlast=$(date)
195  save_success "Successful update"
196fi
197
198# Finally, update the apt-file cache
199v apt-file update
200
201if [ -x /usr/sbin/athena-login-snapshot ]; then
202  echo "** Cleaning up root snapshot"
203  /usr/sbin/athena-login-snapshot update-end
204fi
205
206maybe_reboot
207exit
Note: See TracBrowser for help on using the repository browser.