File: [local] / openbsd / update_openbsd / update_openbsd (download)
Revision 1.49, Sun Oct 20 00:13:38 2013 UTC (10 years, 8 months ago) by andrew
Branch: MAIN
Changes since 1.48: +4 -3 lines
Check for a new kernel, not a new version
To better insulate from changes, rather than insisting on a reboot only between versions, instead force the reboot for each kernel change.
This does mean an extra reboot that may not be strictly necessary most of the time, but it is safer.
|
#!/bin/sh
# $AFresh1: update_openbsd,v 1.49 2013/10/20 00:13:38 andrew Exp $
#
# Copyright (c) 2012 Andrew Fresh <andrew@afresh1.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
installed_sets() {
local misc=/usr/share/doc/README
local man=/usr/share/man/cat1/intro.0
local comp=/usr/bin/cc
local game=/usr/games/
local xbase=/usr/X11R6/
local xetc=/etc/X11/xinit/xinitrc
local xfont=/usr/X11R6/lib/X11/fonts
local xserv=/usr/X11R6/bin/X
local xshare=/usr/X11R6/bin/startx
local _c _d _e
echo -n base
echo -n ' etc'
for _d in misc man comp game xbase xetc xfont xserv xshare; do
eval _e=\$${_d}
_c=`ls $_e 2> /dev/null | wc -l`
#echo $_c $_d $_e
if [ $_c -ne 0 ]; then
echo -n " $_d"
fi
done
sendmail -d0.1 --badoption </dev/null 2>/dev/null | grep -q SASL
if [ $? == 0 ]; then
echo -n ' sendmail-smtp_auth'
fi
}
kernel_file_version() {
echo exit | config -e $1 | grep -A1 ^OpenBSD
#what $1 | sed -ne 's/[[:blank:]]\{1,\}//p'
}
version_in() {
local _proto=${FTP%%://*}
local _file
if [ X"ftp" == X"${_proto}" ]; then
local _list=`echo "ls base*.tgz" | ${FTP_CMD} ${FTP}/`
_file=`echo ${_list} | awk '/base[0-9][0-9].tgz/ { print $9 }'`
elif [ X"http" == X"${_proto}" ]; then
local _list=`${FTP_CMD} -V -o - ${FTP}/`
_file=`echo ${_list} | awk '/[^x]base[0-9][0-9]*\.tgz/ {
sub("^.*base","base");
sub("\.tgz.*",".tgz");
print $0;
}'`
elif [ X"scp" == X"${_proto}" ]; then
echo SCP is not yet supported >&2
return 2
else
echo Unsupported FTP ${FTP} >&2
return 2
fi
local _v=${_file##*base}
_v=${_v%.tgz*}
echo $_v
}
set_version() {
CUR_VER=`uname -r`
NEW_VER=`dc -e "$CUR_VER 0.1 + p"`
FILE_VER=""
FTP=""
local _cv=`echo $CUR_VER | sed -e 's/\.//'`
local _nv=`echo $NEW_VER | sed -e 's/\.//'`
local _v
if [ X"No" != X"$FORCE_DIR" -a -d $FORCE_DIR ]; then
_dir=$FORCE_DIR
if [ -e ${_dir}/base${_nv}.tgz ]; then
_v=$_nv
elif [ -e ${_dir}/base${_cv}.tgz ]; then
NEW_VER=$CUR_VER
_v=$_cv
fi
elif [ -d $CUR_VER ]; then
_dir=$CUR_VER
NEW_VER=$CUR_VER
if [ -e ${_dir}/base${_cv}.tgz ]; then
_v=$_cv
fi
elif [ -d $NEW_VER ]; then
_dir=$NEW_VER
if [ -e ${_dir}/base${_nv}.tgz ]; then
_v=$_nv
fi
fi
if [ X"" != X"${MIRROR}" -a X"" == X"${_v}" ]; then
if [ X"No" == X"${FORCE_DIR}" ]; then
_dir=${NEW_VER}
else
_dir=${FORCE_DIR}
fi
FTP=${MIRROR}/${_dir}/`machine`
_v=`version_in`
if [ X"" == X"${_v}" ]; then
if [ X"No" != X"$FORCE_DIR" ]; then
echo No sets in forced [${FTP}] >&2
return 2
fi
NEW_VER=$CUR_VER
_dir=${NEW_VER}
FTP=${MIRROR}/${_dir}/`machine`
_v=`version_in`
fi
if [ X"" == X"${_v}" ]; then
echo No sets in [${FTP}] >&2
return 2
elif [ X"${_cv}" == X"${_v}" ]; then
NEW_VER=$CUR_VER
elif [ X"${_nv}" == X"${_v}" ]; then
NEW_VER=$NEW_VER
else
echo Invalid version [$_v] >&2
return 2
fi
if [ X"No" == X"$FORCE_DIR" ]; then
_dir=$NEW_VER
fi
fi
if [ X"" == X"${_v}" ]; then
echo ERROR: Unable to determine file version! >&2
return 1
fi
if [ X"" == X"$RELEASEDIR" ]; then
RELEASEDIR=`pwd`/$_dir
fi
FILE_VER=$_v
if [ X"" != X"${MIRROR}" ]; then
FTP=${MIRROR}/${_dir}/`machine`
fi
BOOT_KERNEL=`( \
echo bsd; \
[ -e /boot.conf ] && sed -E '/^ *(set +image|boot) +/!d ; \
s///; s/^.*://; s/ .*$//' /boot.conf \
) | tail -1`
BOOT_KERNEL=`follow_symlink /$BOOT_KERNEL`
BOOT_KERNEL="/${BOOT_KERNEL#/}"
BOOT_KERNEL_VERSION=`kernel_file_version $BOOT_KERNEL`
BOOTED_KERNEL_VERSION=`sysctl -n kern.version`
NEW_KERNEL_VERSION=""
# We want to default to what we had
INSTALL_KERNELS="${BOOT_KERNEL#/}"
# if the boot kernel was our specially named bsd.sp, we install from bsd
if [ X"$INSTALL_KERNELS" == X"bsd.sp" ]; then
INSTALL_KERNELS="bsd"
fi
# with a second option of an mp kernel if is is a likely candidate
if [ X"$INSTALL_KERNELS" != X"bsd.mp" ]; then
local _ncpu=$(sysctl -n hw.ncpufound)
[ $_ncpu -gt 1 ] && INSTALL_KERNELS="$INSTALL_KERNELS bsd.mp"
fi
# or just bsd otherwise
if [ X"${INSTALL_KERNELS% *}" != X"bsd" ]; then
INSTALL_KERNELS="$INSTALL_KERNELS bsd"
fi
BOOT_KERNELS=$INSTALL_KERNELS
INSTALL_KERNELS="$INSTALL_KERNELS bsd.rd"
}
get_sets() {
echo '### GETTING SETS ###'
if [ X"" == X"$FTP" ]; then
echo ERROR: No FTP site set! >&2
return 1
fi
mkdir -p ${RELEASEDIR}
cd $RELEASEDIR
local _v=$FILE_VER
for _b in $INSTALL_KERNELS; do
if [ ! -e ./${_b} ]; then
echo $FTP_CMD ${FTP}/${_b}
$FTP_CMD ${FTP}/${_b}
fi
done
for _s in $INSTALLED_SETS; do
local _file=${_s}${_v}.tgz
if [ ${_s} == sendmail-smtp_auth ]; then
_file=${_s}.gz
fi
if [ ! -e ./${_file} ]; then
echo $FTP_CMD ${FTP}/${_file}
$FTP_CMD ${FTP}/${_file}
fi
done
local _type
for _type in $CHECKSUM_TYPES; do
[ -e $_type ] && break
echo $FTP_CMD ${FTP}/$_type
$FTP_CMD ${FTP}/$_type
done
}
follow_symlink () {
local _file=$1
# This could go circular, but I dunno how to fix that.
if [ -h $_file ]; then
follow_symlink $( file $_file |
grep 'symbolic link' |
sed -e s/^.*\\\`// -e s/\\\'\$// )
else
echo $_file
fi
}
check_sum () {
local _type=$1
echo "### CHECKING $_type SUMS ###"
cd $RELEASEDIR
if [ ! -e $_type ]; then
echo $_type File does not exist!
return 1
fi
ls bsd* *gz | sed -e 's/\(.*\)/(\1)/' > index
grep -f index $_type | sum -c
if [ $? -ne 0 ]; then
echo ERROR: $_type does not match! >&2
return 1
fi
}
check_sets() {
echo '### CHECKING SETS ###'
cd $RELEASEDIR
local _missing_sets
local _v=$FILE_VER
for _n in $INSTALL_KERNELS; do
local _o=$_n
[ X"bsd" == X"${_o}" -a -e /bsd.sp ] && _o=bsd.sp
if [ -e /${_o} -a ! -e ./${_n} ]; then
echo ${_o} does not exist
_missing_sets=1
fi
if [ X"${BOOT_KERNEL}" == X"/${_o}" -a -e ./${_n} ]; then
NEW_KERNEL_VERSION=`kernel_file_version ./${_n}`
fi
done
if [ X"$NEW_KERNEL_VERSION" == X"" ]; then
echo Missing replacement for boot kernel $BOOT_KERNEL >&2
_missing_sets=1
fi
for _s in $INSTALLED_SETS; do
local _file=${_s}${_v}.tgz
if [ ${_s} == sendmail-smtp_auth ]; then
_file=${_s}.gz
fi
if [ ! -e ./${_file} ]; then
echo ${_file} does not exist
_missing_sets=1
fi
done
if [ X"" == X"${_missing_sets}" ]; then
echo All OK
fi
local _type
for _type in $CHECKSUM_TYPES; do
if [ -e $_type ]; then
check_sum $_type
fi
done
}
install_kernels() {
echo '### INSTALLING KERNEL ###'
if [ X"$USER" != X"root" -a X"$SUDO" == X"" ]; then
echo ${0##*/} must be run as root or SUDO must be set! >&2
exit 1
fi
if [ X"" == X"$RELEASEDIR" ]; then
echo ERROR: no source for new kernels! >&2
exit 1
fi
if [ X"$BOOT_KERNEL_VERSION" != X"$NEW_KERNEL_VERSION" ]; then
echo "Backing up $BOOT_KERNEL to /obsd"
$SUDO ln -f $BOOT_KERNEL /obsd
if [ $? -ne 0 ]; then
echo "Error copying old kernel!" >&2
exit 1
fi
fi
cd $RELEASEDIR
for _b in $INSTALL_KERNELS; do
$SUDO rm -f /nbsd
local _bd=$_b
[ X"${_b}" == X"bsd" ] && _bd="bsd.sp"
local _is_boot=""
[ X"$BOOT_KERNEL" == X"/${_bd}" ] && _is_boot="# boot kernel"
echo "Copying $_b to /$_bd $_is_boot"
$SUDO cp ${_b} /nbsd && $SUDO mv /nbsd /${_bd}
if [ $? -ne 0 ]; then
echo ERROR: Could not copy new $_bd kernel! >&2
exit 1
fi
done
cd $OLDPWD
if [ ! -h /bsd ]; then
cd /
for _b in $BOOT_KERNELS; do
[ X"$_b" == X"bsd" ] && _b="bsd.sp"
if [ -e $_b ]; then
echo symlinking $_b to /bsd
$SUDO ln -sf $_b bsd
if [ $? -ne 0 ]; then
echo ERROR: Could not symlink new kernel! >&2
exit 1
fi
break
fi
done
cd $OLDPWD
fi
}
install_sets() {
echo '### INSTALLING SETS ###'
if [ X"$USER" != X"root" -a X"$SUDO" == X"" ]; then
echo ${0##*/} must be run as root or SUDO must be set! >&2
exit 1
fi
if [ X"" == X"$RELEASEDIR" ]; then
echo ERROR: no source for sets! >&2
exit 1
else
cd $RELEASEDIR
fi
local _v=$FILE_VER
if [ X"$BOOT_KERNEL_VERSION" != X"$BOOTED_KERNEL_VERSION" \
-a ! -e /sbin/oreboot ]; then
$SUDO cp /sbin/reboot /sbin/oreboot
if [ $? -ne 0 ]; then
echo "Error copying old reboot command!" >&2
exit 1
fi
echo "/sbin/reboot copied to /sbin/oreboot"
fi
local _sets=`ls *${_v}.tgz | grep -v ^base `
for _f in ${_sets} base${_v}.tgz; do
_path=$DESTDIR
if [ X"etc${_v}.tgz" == X"$_f" \
-o X"xetc${_v}.tgz" == X"$_f" ]; then
[ X"" != X"$SYSMERGE" ] && continue
_path=/var/tmp/temproot
fi
echo Extracting $_f to $_path
$SUDO mkdir -p $_path
$SUDO tar -C $_path -xzphf ${RELEASEDIR}/${_f}
if [ $? -ne 0 ]; then
echo ERROR: Could not extract ${_f}! >&2
exit 1
fi
done
echo Extracted all sets.
if [ -e ${RELEASEDIR}/sendmail-smtp_auth.gz ]; then
gzcat ${RELEASEDIR}/sendmail-smtp_auth.gz > \
${RELEASEDIR}/sendmail-smtp_auth
fi
if [ -e ${RELEASEDIR}/sendmail-smtp_auth ]; then
if ! pkg_info -qe 'cyrus-sasl-*'; then
$SUDO pkg_add -i cyrus-sasl
fi
$SUDO install -o root -g smmsp -m 2555 \
${RELEASEDIR}/sendmail-smtp_auth \
/usr/libexec/sendmail/sendmail
echo Installed sendmail with smtp_auth
fi
}
update_etc() {
echo '### UPDATING ETC ###'
if [ ! -e $SYSMERGE ]; then
echo "ERROR: Can't find sysmerge!" >&2
exit 1;
fi
if [ X"" == X"$RELEASEDIR" ]; then
echo "ERROR: no source for etc!" >&2
exit 1
fi
cd $RELEASEDIR
local _v=$FILE_VER
local _args=""
if [ -e etc${_v}.tgz ]; then
_args="$_args -s etc${_v}.tgz"
fi
if [ -e xetc${_v}.tgz ]; then
_args="$_args -x xetc${_v}.tgz"
fi
if [ X"" == X"$_args" ]; then
echo ERROR: No upgrade sets found! >&2
else
echo '### RUNNING SYSMERGE ###'
$SUDO $SYSMERGE $_args
fi
cd $OLDPWD
}
if [ -e /etc/update_openbsd.conf ]; then
. /etc/update_openbsd.conf
fi
if [ -e ${HOME}/.update_openbsdrc ]; then
. ${HOME}/.update_openbsdrc
fi
#MIRROR=${MIRROR:=ftp://ftp.openbsd.org/pub/OpenBSD}
FTP_CMD=${FTP_CMD:=ftp -V}
PKG_PATH=${PKG_PATH:=/usr/ports/packages/`machine`/all/:${MIRROR}/`uname -r`/packages/`machine`/}
DESTDIR=${DESTDIR:=/}
SYSMERGE=${SYSMERGE:=/usr/sbin/sysmerge}
FORCE_DIR=${FORCE_DIR:=No}
INSTALLED_SETS=${INSTALLED_SETS:=`installed_sets`}
CHECKSUM_TYPES=${CHECKSUM_TYPES:=SHA256 MD5}
set_version
local _error=$?
echo
echo "-= update_openbsd - helper script to update OpenBSD =-"
echo "------------------------------------------------------"
echo
echo " SUDO: $SUDO"
echo " SYSMERGE: $SYSMERGE"
echo " MIRROR: $MIRROR"
echo " RELEASEDIR: $RELEASEDIR"
echo " DESTDIR: $DESTDIR"
echo " BOOT_KERNEL: $BOOT_KERNEL"
echo "INSTALL_KERNELS: $INSTALL_KERNELS"
echo " INSTALLED_SETS: $INSTALLED_SETS"
echo
echo " CUR_VER: $CUR_VER"
echo " NEW_VER: $NEW_VER"
#echo " FILE_VER: $FILE_VER"
echo
if [ ${_error} -ne 0 ]; then
exit ${_error}
fi
if [ X"" != X"${FTP}" ]; then
get_sets
fi
check_sets || exit
echo "Last booted:\n$BOOTED_KERNEL_VERSION"
if [ X"$BOOT_KERNEL_VERSION" != X"$BOOTED_KERNEL_VERSION" \
-a X"$BOOT_KERNEL_VERSION" != X"$NEW_KERNEL_VERSION" ]; then
echo "Next boot (unless replaced):\n$BOOT_KERNEL_VERSION"
fi
if [ -n "$NEW_KERNEL_VERSION" ]; then
echo "New $BOOT_KERNEL:\n$NEW_KERNEL_VERSION";
else
echo "\n!!! WARNING: Will not replace boot kernel $BOOT_KERNEL! !!!\n" >&2
echo "ctrl+C to cancel, enter to continue anyway" >&2
local _temp
read _temp
fi
if [ -n "$SUDO" -a $CUR_VER != $NEW_VER ]; then
echo >&2
echo "!!! You are upgrading between OpenBSD versions. !!!" >&2
echo "!!! You should make sure you have a root shell open !!!" >&2
echo "!!! It is needed in order to run /sbin/oreboot. !!!" >&2
echo "!!! sudo MAY NOT WORK after sets are extracted. !!!" >&2
echo >&2
echo "ctrl+C to cancel, enter to continue" >&2
local _temp
read _temp
fi
if [ -n "$SUDO" ]; then
echo
echo You may be asked for your sudo password multiple times.
$SUDO -v -p "sudo Password: "
fi
install_kernels
install_sets
if [ X"$BOOT_KERNEL_VERSION" == X"$BOOTED_KERNEL_VERSION" ]; then
if [ -e /sbin/oreboot ]; then
echo Removing /sbin/oreboot
$SUDO rm -f /sbin/oreboot
fi
update_etc
echo '### UPDATING PACKAGES ###'
$SUDO pkg_add -ui -F update -F updatedepends
else
echo Instructions for updating to the new version available from
if [ X"snapshots" == X"$FORCE_DIR" ]; then
echo " http://www.openbsd.org/faq/current.html"
else
echo " http://www.openbsd.org/faq/upgrade${FILE_VER}.html"
fi
fi
echo New kernel installed. Please reboot!
if [ -e /sbin/oreboot ]; then
echo Possibly using /sbin/oreboot
fi
local _send_dmesg=`dirname $0`/send_dmesg
if [ -e "$_send_dmesg" ]; then
if [ -e $RELEASEDIR/.send_dmesg ]; then
$_send_dmesg
rm -f $RELEASEDIR/.send_dmesg
elif [ X"$CUR_VER" != X"$NEW_VER" ]; then
touch $RELEASEDIR/.send_dmesg
fi
fi