source: trunk/packs/update/do-update.sh @ 20502

Revision 20502, 12.4 KB checked in by rbasch, 20 years ago (diff)
Error out if the package directory does not have a .order-version file with size greater than 0.
Line 
1#!/bin/sh
2# $Id: do-update.sh,v 1.46 2004-05-25 17:22:55 rbasch Exp $
3
4# Copyright 1996 by the Massachusetts Institute of Technology.
5#
6# Permission to use, copy, modify, and distribute this
7# software and its documentation for any purpose and without
8# fee is hereby granted, provided that the above copyright
9# notice appear in all copies and that both that copyright
10# notice and this permission notice appear in supporting
11# documentation, and that the name of M.I.T. not be used in
12# advertising or publicity pertaining to distribution of the
13# software without specific, written prior permission.
14# M.I.T. makes no representations about the suitability of
15# this software for any purpose.  It is provided "as is"
16# without express or implied warranty.
17
18# Eliminate duplicates in the argument list, putting the result into
19# a variable "out".  Not super-robust, but it's only intended to work
20# on filenames added to CONFCHG.  We have this because we can't rely
21# on "sort" working across OS versions.
22undup() {
23        for i in "$@"; do
24                case $out in
25                *" $i "*)
26                        ;;
27                *)
28                        out="$out $i "
29                        ;;
30                esac
31        done
32}
33
34# Let reactivate know that an update is running.
35onexit()
36{
37        rm -rf /var/athena/update.running
38}
39trap onexit EXIT
40touch /var/athena/update.running
41
42# We get three arguments: the method by which the machine was rebooted.
43# (possible values are Auto, Manual, and Remote), the current workstation
44# version, and the new version.
45method=$1
46version=$2
47newvers=$3
48
49echo "Beginning update from $version to $newvers at `date`."
50. /srvd/usr/athena/lib/update/update-environment
51
52# Remove the version script state files.
53rm -f "$CONFCHG" "$CONFVARS" "$AUXDEVS" "$OLDBINS" "$OLDLIBS" "$DEADFILES"
54rm -f "$OSCONFCHG" "$PACKAGES" "$PATCHES" "$OLDPKGS" "$OLDPTCHS"
55if [ -n "$PACKAGES" ]; then
56      rm -f "$PACKAGES".*
57fi
58rm -f $MIT_CORE_PACKAGES $MIT_NONCORE_PACKAGES $MIT_OLD_PACKAGES
59
60# Get the platform name for Solaris.  "uname -i" is the documented way, but
61# it doesn't work in Solaris 2.4 and prior, and "uname -m" works for now.
62# Also determine the root disk based on the mount table.
63case "$HOSTTYPE" in
64sun4)
65        SUNPLATFORM=`uname -m`
66        ROOTDISK=`mount | sed -n '/^\/ /s#^/ on /dev/dsk/\([^ ]*\).*$#\1#p'`
67        export SUNPLATFORM ROOTDISK
68        ;;
69esac
70
71# On IRIX, reboot prompts for confirmation when logged in remotely.
72# The following kludge prevents the prompt.
73unset REMOTEHOST
74
75# Some versions of Solaris will panic if they are hit with a certain
76# type of port scan and you then kill a network daemon.  As a
77# work-around, sync the disks first, and sleep to give the machine a
78# chance to panic if it is going to.
79sync
80sleep 2
81# We could be more intelligent and shutdown everything, but...
82echo "Shutting down running services"
83if [ -f /var/athena/inetd.pid ]; then
84        kill `cat /var/athena/inetd.pid` > /dev/null 2>&1
85fi
86if [ -f /var/athena/named.pid ]; then
87        kill `cat /var/athena/named.pid` > /dev/null 2>&1
88fi
89case "$HOSTTYPE" in
90sgi)
91        killall inetd snmpd syslogd
92        ;;
93*)
94        if [ -f /etc/syslog.pid ]; then
95                kill `cat /etc/syslog.pid` > /dev/null 2>&1
96        fi
97        if [ -f /var/athena/snmpd.pid ]; then
98                kill `cat /var/athena/snmpd.pid` > /dev/null 2>&1
99        fi
100        ;;
101esac
102sleep 10
103
104echo "Athena Workstation ($HOSTTYPE) Version Update `date`" >> \
105        "$CONFDIR/version"
106
107if [ "$version" != "$newvers" ]; then
108        echo "Version-specific updating.."
109        cp /dev/null "$CONFCHG"
110        cp /dev/null "$OSCONFCHG"
111        cp /dev/null "$CONFVARS"
112        cp /dev/null "$OLDBINS"
113        cp /dev/null "$OLDLIBS"
114        upvers "$version" "$newvers" "$LIBDIR"
115fi
116
117. $CONFDIR/rc.conf
118if [ -f $CONFVARS ]; then
119        . $CONFVARS
120fi
121
122# The version scripts may have modified the following files:
123#       $CONFCHG        A list of configuration files to update
124#       $AUXDEVS        A list of auxiliary device scripts to run
125#                       from /srvd/install/aux.devs (sun4 only)
126#       $OLDBINS        A list of binaries to preserve before tracking
127#       $OLDLIBS        A list of libraries to preserve before tracking
128#       $DEADFILES      A list of local files to be removed
129#       $PACKAGES       A list of OS packages to be de/installed
130#       $OSCONFCHG      A list of config files to save/restore around
131#                       an update to the OS
132#       $CONFVARS       Can set variables to "true", including:
133#               NEWUNIX         Update kernel
134#               NEWBOOT         Boot blocks have changed
135#               NEWDEVS         New pseudo-devices required
136#               NEWOS           OS version has changed
137#               TRACKOS         OS files relevant to local disk have changed
138#               MINIROOT        some OS files require a miniroot update
139#               OSCHANGES       Need to run /srvd/install/oschanges
140#                               (always set if any OS packages are installed)
141
142configfiles=`cat $LIBDIR/configfiles`
143
144if [ "$PUBLIC" = true ]; then
145        NEWUNIX=true
146        NEWBOOT=true
147        for i in $configfiles; do
148                echo "$i" >> $CONFCHG;
149        done
150        rm -f /.hushlogin /etc/*.local /etc/athena/*.local
151fi
152for i in $configfiles; do
153        if [ ! -f "$i" ]; then
154                echo "$i" >> $CONFCHG
155        fi
156done
157
158if [ -s "$CONFCHG" ]; then
159        undup `cat "$CONFCHG"`
160        conf=$out
161        if [ "$PUBLIC" != true ]; then
162                for i in $conf; do
163                        if [ -f $i ]; then
164                                mv -f $i $i.old
165                        fi
166                done
167        fi
168        for i in $conf; do
169                rm -rf $i
170                if [ -f /srvd$i ]; then
171                        cp -p /srvd$i $i
172                elif [ -f /os$i ]; then
173                        cp -p /os$i $i
174                elif [ -f /install$i ]; then
175                        cp -p /install$i $i
176                fi
177        done
178fi
179
180if [ "$PUBLIC" = true ]; then
181        # Just substitute who we are into the current rc.conf from the srvd.
182        echo "Updating $CONFDIR/rc.conf from /srvd$CONFDIR/rc.conf"
183        sed -n  -e "s#^HOST=[^;]*#HOST=$HOST#" \
184                -e "s#^ADDR=[^;]*#ADDR=$ADDR#" \
185                -e "s#^MACHINE=[^;]*#MACHINE=$MACHINE#" \
186                -e "s#^SYSTEM=[^;]*#SYSTEM=$SYSTEM#" \
187                -e "s#^NETDEV=[^;]*#NETDEV=$NETDEV#" \
188                -e "s#^PUBLIC=[^;]*#PUBLIC=$PUBLIC#" \
189                -e p "/srvd$CONFDIR/rc.conf" > "$CONFDIR/rc.conf"
190else
191        # Add any new variables to rc.conf.
192        echo "Looking for new variables to add to $CONFDIR/rc.conf"
193        conf=`cat "/srvd$CONFDIR/rc.conf" | awk -F= '(NF>1){print $1}'`
194        vars=""
195        for i in $conf; do
196                if [ `grep -c "^$i=" "$CONFDIR/rc.conf"` = 0 ]; then
197                        vars="$vars $i"
198                fi
199        done
200        if [ -n "$vars" ]; then
201                echo "Backing up $CONFDIR/rc.conf to $CONFDIR/rc.conf.orig"
202                rm -f "$CONFDIR/rc.conf.orig"
203                cp -p "$CONFDIR/rc.conf" "$CONFDIR/rc.conf.orig"
204
205                echo "The following variables are being added to" \
206                        "/etc/athena/rc.conf:"
207                echo "  $vars"
208                for i in $vars; do
209                        grep "^$i=" "/srvd$CONFDIR/rc.conf" \
210                                >> "$CONFDIR/rc.conf"
211                done
212        fi
213fi
214
215# Determine if there are any Athena packages to add or remove.  We do
216# this here because the miniroot may not be able to run the pkg-order
217# program used below.
218
219# The logic here is to compare the package list given by the
220# .order-version file (containing each package name and its version)
221# in the new version's packages directory against the list of
222# packages, with their version numbers, currently installed on the
223# system.  Unique lines in the new version list are packages to be
224# installed or updated.  To determine packages to be removed we
225# compare only the package names from the two lists; packages named in
226# only the currently installed list are slated for removal.
227
228# Most Athena packages are installed in finish-update; if this is a
229# miniroot update, finish-update will not run until after we reboot
230# into the updated root.  However, we must make sure that any packages
231# needed for finish-update to be able to do its work (e.g. AFS) are
232# installed prior to that reboot, since previous versions of such
233# software may not run any more.  These packages are marked as
234# belonging to the "MITcore" category in pkginfo.  So we further
235# separate the list of packages to be added into core and non-core
236# lists; the former are installed by update-os, i.e. prior to
237# rebooting into the updated root.
238
239echo "Determining update actions ..."
240
241old_list=/tmp/old_list$$
242new_list=/tmp/new_list$$
243old_verlist=/tmp/old_verlist$$
244new_verlist=/tmp/new_verlist$$
245add_list=/tmp/add_list$$
246core_list=/tmp/core_list$$
247
248pkgdir="/srvd/pkg/$newvers"
249install_order="$pkgdir/.order-version"
250if [ ! -s "$install_order" ]; then
251        echo "Cannot find $install_order, aborting update." 1>&2
252        exit 1
253fi
254
255rm -rf $old_list $new_list $old_verlist $new_verlist $add_list $core_list
256
257# Get the list of currently installed Athena packages, with and without
258# version numbers.
259pkginfo -l -R "${UPDATE_ROOT:-/}" | awk '
260        /PKGINST:/ { pkg = $2; }
261        /VERSION:/ { if (pkg ~ /^MIT-/) print pkg, $2; pkg = ""; }' \
262        | sort -u | tee $old_verlist | awk '{ print $1; }' > $old_list
263
264# Sort the package list for the version we are updating to.
265sort -u $install_order | tee $new_verlist | awk '{ print $1; }' > $new_list
266
267# Get the new or updated packages in the new list, stripping off the
268# version number.
269comm -13 $old_verlist $new_verlist | awk '{ print $1; }' > $add_list
270if [ -s $add_list ]; then
271        # We have a list of packages to install.  We must split this list
272        # into lists of core and non-core packages; the former must be
273        # installed by update-os.  So we use pkginfo to select core
274        # packages from the list of packages to be added.
275        pkginfo -c MITcore -d $pkgdir `cat $add_list` 2>/dev/null \
276                | awk '{ print $2; }' | sort -u > $core_list
277        corepkgs=`cat $core_list`
278        if [ -n "$corepkgs" ]; then
279                # We have core packages to install.  Get them in
280                # install order.
281                $LIBDIR/pkg-order -d $pkgdir $corepkgs \
282                        > $MIT_CORE_PACKAGES || exit 1
283        fi
284        noncorepkgs=`comm -23 $add_list $core_list`
285        if [ -n "$noncorepkgs" ]; then
286                # We have noncore packages to install.  Get them in
287                # install order.
288                $LIBDIR/pkg-order -d $pkgdir $noncorepkgs \
289                        > $MIT_NONCORE_PACKAGES || exit 1
290        fi
291fi
292
293# Get the list of packages present in the old list, but not the new
294# list, i.e. the packages to be removed.
295oldpkgs=`comm -23 $old_list $new_list`
296if [ -n "$oldpkgs" ]; then
297        # Get the order in which to remove the packages; the depend
298        # file should be saved in the system pkg directory.  If
299        # that fails, just remove them in the sorted order.
300        $LIBDIR/pkg-order -r -d /var/sadm/pkg $oldpkgs \
301                > $MIT_OLD_PACKAGES || echo "$oldpkgs" > $MIT_OLD_PACKAGES
302fi
303
304rm -f $old_list $new_list $old_verlist $new_verlist $add_list $core_list
305
306if [ "$MINIROOT" = true ]; then
307        # Set up a miniroot in the swap partition. We will boot into
308        # it, and update-os will be run from there.
309
310        case "$HOSTTYPE" in
311        sgi)
312                echo "Suppressing network daemons for reboot"
313                chkconfig -f suppress-network-daemons on
314
315                # Note the volume header must be updated before the miniroot
316                # can boot (Irix only).
317                if [ "$NEWBOOT" = true ]; then
318                        # Make sure the volume header has an up-to-date sash.
319                        echo "Updating sash volume directory entry..."
320                        dvhtool -v creat /install/lib/sash sash
321                fi
322                ;;
323        esac
324
325        sh /install/miniroot/setup-swap-boot "$method" "$newvers"
326        case "$?" in
327        0)
328                echo "Rebooting into swap to update OS files..."
329                ;;
330        2)
331                echo "Rebooting to clear swap..."
332                echo "Athena Workstation ($HOSTTYPE) Version" \
333                      "ClearSwap $method $newvers `date`" \
334                        >> "$CONFDIR/version"
335                # Make sure this machine knows what the heck to do
336                # with "ClearSwap" in version, since it may not be
337                # updated to a release that understands it yet.
338                cp /srvd/etc/init.d/finish-update /etc/init.d
339                ;;
340        *)
341                echo "Please contact Athena Hotline at x3-1410."
342                echo "Thank you. -Athena Operations"
343                exit 0
344                ;;
345        esac
346
347        echo "Update partially completed, system will reboot in 15 seconds."
348        sync
349        sleep 15
350        exec reboot
351fi
352
353# Not a miniroot update; run update-os here.  This is a good place to
354# handle OLDBINS and OLDLIBS, since we need the environment variables
355# after update-os.
356
357if [ -s "$OLDBINS" ]; then
358        echo "Making copies of OS binaries we need"
359        mkdir -p /tmp/bin
360        bins="`cat $OLDBINS`"
361        for i in $bins; do
362                cp -p $i /tmp/bin/`basename $i`
363        done
364        PATH=/tmp/bin:$PATH; export PATH
365fi
366
367if [ -s "$OLDLIBS" ]; then
368        echo "Making copies of OS libraries we need"
369        mkdir -p /tmp/lib
370        libs="`cat $OLDLIBS`"
371        for i in $libs; do
372                cp -p $i /tmp/lib/`basename $i`
373        done
374        LD_LIBRARY_PATH=/tmp/lib; export LD_LIBRARY_PATH
375fi
376
377sh /srvd/usr/athena/lib/update/update-os "$newvers"
378
379if [ "$NEWOS" = true ]; then
380        # Reboot to finish update.
381
382        case "$HOSTTYPE" in
383        sgi)
384                echo "Suppressing network daemons for reboot"
385                chkconfig -f suppress-network-daemons on
386                ;;
387        esac
388
389        echo "Updating version for reboot"
390        echo "Athena Workstation ($HOSTTYPE) Version Reboot" \
391                "$method $newvers `date`" >> "$CONFDIR/version"
392        echo "Update partially completed, system will reboot in 15 seconds."
393        sync
394        sleep 15
395        exec reboot
396fi
397
398# Not an OS update; run finish-update here.  Restart named first, since
399# mkserv has to resolve names.
400/etc/athena/named
401sh /srvd/usr/athena/lib/update/finish-update "$newvers"
402if [ "$method" = Auto ]; then
403        echo "Automatic update done; system will reboot in 15 seconds."
404        sync
405        sleep 15
406        exec reboot
407fi
408
409# Not an automatic update; just sync the disk and drop back to the shell.
410sync
Note: See TracBrowser for help on using the repository browser.