edgebsd

#!/bin/sh
#Copyright (c) 2014-2024 Pierre Pronchery <khorben@EdgeBSD.org>
#
#This code is derived from software contributed to the EdgeBSD Project
#by Pierre Pronchery <khorben@EdgeBSD.org>
#
#Redistribution and use in source and binary forms, with or without
#modification, are permitted provided that the following conditions
#are met:
#1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
#THIS SOFTWARE IS PROVIDED BY THE EDGEBSD PROJECT AND CONTRIBUTORS
#``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
#TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
#BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
#INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
#CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#POSSIBILITY OF SUCH DAMAGE.
#environment
umask 022
#variables
PROGNAME="edgebsd-update"
#executables
CAT="/bin/cat"
CMP="/usr/bin/cmp"
CP="/bin/cp -af"
DEBUG="_debug"
DUMPFS="/usr/sbin/dumpfs"
FTP="/usr/bin/ftp"
GREP="grep"
GZIP="/usr/bin/gzip -9"
INSTALL="/usr/bin/install"
INSTALLBOOT="/usr/sbin/installboot"
MKDIR="/bin/mkdir -p"
MKTEMP="/usr/bin/mktemp"
MOUNT="/sbin/mount"
MV="/bin/mv -f"
NETPGP="/usr/bin/netpgp"
NETPGPKEYS="/usr/bin/netpgpkeys"
PAXCTL="/usr/sbin/paxctl"
PKGIN="/usr/pkg/bin/pkgin"
POSTINSTALL="/usr/sbin/postinstall"
PRINTF="printf"
PROGRESS="/usr/bin/progress"
REBOOT="/sbin/reboot"
RM="/bin/rm -f"
RMDIR="/bin/rmdir"
ROOTDEV=
SYSCTL="/sbin/sysctl"
TAR="/rescue/tar"
TR="tr"
UMOUNT="/sbin/umount"
UNAME="/usr/bin/uname"
ZCAT="/usr/bin/zcat"
#settings
BOOTLOADER=0
BOOTXX="/usr/mdec/"
DESTDIR=
DEVNULL="/dev/null"
EDGEBSD_ARCH=$($UNAME -m)
EDGEBSD_ARCH_FULL="$EDGEBSD_ARCH"
case "$EDGEBSD_ARCH_FULL" in
evbarm)
EDGEBSD_ARCH_FULL="$EDGEBSD_ARCH_FULL-$($UNAME -p)"
;;
esac
EDGEBSD_KERNEL=
EDGEBSD_MIRROR="https://ftp.EdgeBSD.org"
EDGEBSD_PATH=
EDGEBSD_VENDOR="EdgeBSD"
ETCMTREE="/etc/mtree"
INIT=0
KERNEL=0
[ -n "$TMPDIR" ] || TMPDIR="/tmp"
MKTEMP_TEMPLATE="$TMPDIR/$PROGNAME-XXXXXX"
MODULES=0
NOOP=0
PACKAGES=0
RELEASE=
SETEXT=
SETS=
SYSCONFDIR="@SYSCONFDIR@"
UPDATE_ETC=0
USRMDECBOOT="/usr/mdec/boot"
USRMDECBOOTXX="/usr/mdec/bootxx"
USRMDECPREKERN="/usr/mdec/prekern"
VERBOSE=1
VERIFY=1
VERIFY_USERID="root@EdgeBSD.org"
#load local settings
[ -f "$SYSCONFDIR/$EDGEBSD_VENDOR/$PROGNAME.conf" ] &&
. "$SYSCONFDIR/$EDGEBSD_VENDOR/$PROGNAME.conf"
[ -f "$HOME/.config/$EDGEBSD_VENDOR/$PROGNAME.conf" ] &&
. "$HOME/.config/$EDGEBSD_VENDOR/$PROGNAME.conf"
#functions
#edgebsd_update
_edgebsd_update()
{
#detect the release
_detect_release "$RELEASE"
case "$EDGEBSD_RELEASE/$EDGEBSD_ARCH" in
EdgeBSD-9/alpha|EdgeBSD-9/amd64|EdgeBSD-9/sparc64|\
NetBSD-9.*/alpha|NetBSD-9.*/amd64|NetBSD-9.*/sparc64|\
EdgeBSD-10/alpha|EdgeBSD-10/amd64|EdgeBSD-10/sparc64|\
NetBSD-10.*/alpha|NetBSD-10.*/amd64|NetBSD-10.*/sparc64)
[ -n "$SETEXT" ] || SETEXT=".tar.xz"
;;
EdgeBSD-6/*|EdgeBSD-7/*|EdgeBSD-8/*|EdgeBSD-9/*|EdgeBSD-10/*|\
NetBSD-2.*|NetBSD-3.*|NetBSD-4.*|NetBSD-5.*|\
NetBSD-6.*/*|NetBSD-7.*/*|NetBSD-8.*/*|NetBSD-9.*/*)
[ -n "$SETEXT" ] || SETEXT=".tgz"
;;
*)
_error "$RELEASE: Unsupported $EDGEBSD_VENDOR release"
return $?
;;
esac
if [ "$EDGEBSD_VENDOR" = "EdgeBSD" ]; then
if [ $VERIFY -ne 0 ]; then
#import the GPG key
_info "Importing the GPG key..."
#XXX does not work
_import_gpg_key || return 2
fi
fi
#detect the sets to update
[ -n "$SETS" ] || SETS=$(_detect_sets)
if [ $MODULES -ne 0 ]; then
has_stand=0
for i in $SETS; do
[ "$i" = "stand" ] && has_stand=1
done
[ $has_stand -eq 0 ] && SETS="$SETS stand"
fi
if [ -z "$EDGEBSD_PATH" ]; then
EDGEBSD_PATH="$EDGEBSD_MIRROR/pub/$EDGEBSD_VENDOR/$EDGEBSD_RELEASE/$EDGEBSD_ARCH_FULL/binary/sets"
else
EDGEBSD_MIRROR="/nonexistent"
fi
#detect and download the kernel
[ -n "$EDGEBSD_KERNEL" ] || EDGEBSD_KERNEL=$(_detect_kernel)
_download_kernel
if [ $? -ne 0 ]; then
_error "$EDGEBSD_KERNEL: Could not download the kernel"
return $?
fi
_download_kernel_signature
if [ $? -ne 0 ]; then
_error "$EDGEBSD_KERNEL: Could not download the kernel signature"
return $?
fi
_download_sets
if [ $? -ne 0 ]; then
_error "Could not download the sets"
return $?
fi
#update the kernel
clean_kernel=0
_update_kernel
ret=$?
if [ $ret -eq 3 ]; then
#rebooting is requested
if [ $INIT -ne 0 ]; then
#remove the kernel set
_clean_kernel
#reboot after kernel update
_info "Rebooting after kernel update..."
$DEBUG $REBOOT
if [ $? -ne 0 ]; then
_error "Could not reboot after kernel update"
return $?
fi
fi
elif [ $ret -eq 0 ]; then
[ $INIT -ne 0 -o -n "${EDGEBSD_MIRROR%%/*}" ] && clean_kernel=1
else
_error "Could not update the kernel"
fi
#update the sets
clean_sets=0
clean_sets_keep="etc"
if [ $ret -eq 0 ]; then
_update_sets
ret=$?
if [ $ret -eq 0 ]; then
[ $INIT -ne 0 -o -n "${EDGEBSD_MIRROR%%/*}" ] && clean_sets=1
else
_error "Could not update the sets"
fi
fi
#update the configuration
if [ $ret -eq 0 ]; then
_update_configuration
ret=$?
if [ $ret -eq 0 ]; then
clean_sets_keep=
else
_error "Could not update the configuration"
fi
fi
#update the packages
if [ $ret -eq 0 ]; then
_update_packages
ret=$?
[ $ret -eq 0 ] || _error "Could not update the packages"
fi
#update the bootloader
if [ $ret -eq 0 ]; then
_update_bootloader
ret=$?
[ $ret -eq 0 ] || _error "Could not update the bootloader"
fi
#cleanup
[ $clean_kernel -eq 1 ] && _clean_kernel
[ $clean_sets -eq 1 ] && _clean_sets "$clean_sets_keep"
if [ $ret -eq 0 ]; then
_info "Update successful."
else
_info "Some errors occurred."
fi
#reboot after update
if [ $ret -eq 0 ]; then
_update_reboot
ret=$?
if [ $ret -ne 0 ]; then
_error "Could not reboot after update"
return $?
fi
fi
return $ret
}
#architecture-specific
_arch_amd64_update_bootloader()
{
_arch_i386_update_bootloader
}
_arch_amd64_update_kernel()
{
_arch_i386_update_kernel
}
_arch_evbarm_update_bootloader()
{
#XXX assumes the Raspberry PI and DESTDIR=/
#TODO replace the firmware content if available
return 0
}
_arch_evbarm_update_kernel()
{
ret=0
kernelfiles="./bcm283?-rpi-* ./netbsd.img"
kernelimg="kernel7.img"
mounted=0
#XXX assumes the Raspberry PI and DESTDIR=/
if [ ! -f "$DESTDIR/boot/$kernelimg" ]; then
if ! $DEBUG $MOUNT "$DESTDIR/boot"; then
_error "$EDGEBSD_KERNEL: Could not mount the boot partition"
return $?
fi
mounted=1
fi
file="kern-${EDGEBSD_KERNEL}${SETEXT}"
[ -z "${EDGEBSD_MIRROR##/*}" ] && file="$EDGEBSD_PATH/$file"
if [ ! -f "$file" ]; then
if [ $INIT -ne 0 ]; then
_info "$EDGEBSD_KERNEL: Skipping kernel update (update file missing)"
return 0
fi
_error "$EDGEBSD_KERNEL: Update file missing"
return $?
fi
if [ $VERIFY -ne 0 ]; then
_info "Verifying kernel ${EDGEBSD_KERNEL}..."
_verify "$file"
if [ $? -ne 0 ]; then
_error "$EDGEBSD_KERNEL: Could not verify the kernel"
return $?
fi
fi
#extract the new kernel
_arch_generic_extract_kernel "${EDGEBSD_KERNEL}" "/boot" $kernelfiles
ret=$?
[ $ret -eq 0 ] || return $ret
#compare the kernel files
$DEBUG $CMP "$DESTDIR/boot/netbsd.img" "$DESTDIR/boot/$kernelimg" \
> "$DEVNULL"
if [ $? -eq 0 ]; then
_info "$EDGEBSD_KERNEL: Skipping kernel update (already installed)"
return 0
fi
#backup the current kernel
_arch_generic_backup_kernel "$kernelimg" "/boot"
ret=$?
[ $ret -eq 0 ] || return $ret
#install the new kernel
_info "Installing kernel ${EDGEBSD_KERNEL}..."
#rename the new kernel
_info "Renaming kernel ${EDGEBSD_KERNEL}..."
$DEBUG $MV -f -- "$DESTDIR/boot/netbsd.img" "$DESTDIR/boot/$kernelimg"
if [ $? -ne 0 ]; then
_error "$EDGEBSD_KERNEL: Could not rename the kernel"
return $?
fi
ret=$?
[ $mounted -eq 0 ] || $DEBUG $UMOUNT "$DESTDIR/boot"
[ $? -ne 0 ] && _error "$EDGEBSD_KERNEL: Could not unmount the boot partition"
#request a reboot
[ $ret -eq 0 ] && return 3
return $ret
}
_arch_generic_backup_kernel()
{
kernel="$1"
dest="$2"
[ ! -f "$DESTDIR$dest/$kernel" ] && return 0
_info "Creating a kernel backup..."
$DEBUG $CP -- "$DESTDIR$dest/$kernel" "$DESTDIR$dest/o$kernel"
if [ $? -ne 0 ]; then
_error "$EDGEBSD_KERNEL: Could not backup the kernel"
return $?
fi
return 0
}
_arch_generic_extract_kernel()
{
kernel="$1"
dest="$2"
shift 2
_info "Extracting kernel ${kernel}..."
_progress -f "$file" -p "$($PRINTF "%-7s " "$kernel")" \
$TAR -xzpf - -C "$DESTDIR$dest" "$@"
if [ $? -ne 0 ]; then
_error "$EDGEBSD_KERNEL: Could not extract the kernel"
return $?
fi
return 0
}
_arch_generic_update_bootloader()
{
if [ -f "$DESTDIR$USRMDECBOOT" ]; then
if [ -f "$DESTDIR/altroot/boot" ]; then
_update_file 0444 "$DESTDIR$USRMDECBOOT" \
"$DESTDIR/altroot/boot" || return 2
fi
if [ -f "$DESTDIR/boot" ]; then
_update_file 0444 "$DESTDIR$USRMDECBOOT" \
"$DESTDIR/boot" || return 2
fi
fi
if [ -f "$DESTDIR$USRMDECPREKERN" ]; then
if [ -f "$DESTDIR/altroot/prekern" ]; then
_update_file 0444 "$DESTDIR$USRMDECPREKERN" \
"$DESTDIR/altroot/prekern" || return 2
fi
if [ -f "$DESTDIR/prekern" ]; then
_update_file 0444 "$DESTDIR$USRMDECPREKERN" \
"$DESTDIR/prekern" || return 2
fi
fi
return 0
}
_arch_generic_update_kernel()
{
file="kern-${EDGEBSD_KERNEL}${SETEXT}"
[ -z "${EDGEBSD_MIRROR##/*}" ] && file="$EDGEBSD_PATH/$file"
if [ ! -f "$file" ]; then
if [ $INIT -ne 0 ]; then
_info "$EDGEBSD_KERNEL: Skipping kernel update (update file missing)"
return 0
fi
_error "$EDGEBSD_KERNEL: Update file missing"
return $?
fi
if [ $VERIFY -ne 0 ]; then
_info "Verifying kernel ${EDGEBSD_KERNEL}..."
_verify "$file"
if [ $? -ne 0 ]; then
_error "$EDGEBSD_KERNEL: Could not verify the kernel"
return $?
fi
fi
#detect the kernel file booted
bootedfile=$($SYSCTL -n "machdep.booted_kernel" 2> "$DEVNULL")
[ $? -eq 0 -a -n "$bootedfile" ] || bootedfile="/netbsd.gz"
bootedfile=${bootedfile#/}
#detect if a backup was booted
if [ "${bootedfile#o}" != "$bootedfile" ]; then
bootedfile="${bootedfile#o}"
elif [ -f "$DESTDIR/altroot/$bootedfile" ]; then
_arch_generic_backup_kernel "$bootedfile" "/altroot"
ret=$?
[ $ret -eq 0 ] || return $ret
elif [ -f "$DESTDIR/$bootedfile" ]; then
_arch_generic_backup_kernel "$bootedfile"
ret=$?
[ $ret -eq 0 ] || return $ret
fi
#install the new kernel
tmpdir=$($MKTEMP -d "$MKTEMP_TEMPLATE")
[ $? -eq 0 ] || return 2
_info "Installing kernel ${EDGEBSD_KERNEL}..."
_progress -f "$file" -p "$($PRINTF "%-7s " "$EDGEBSD_KERNEL")" \
$TAR -xzpf - -C "$tmpdir"
if [ $? -ne 0 ]; then
_error "$EDGEBSD_KERNEL: Could not install the kernel"
$DEBUG $RM -- "$tmpdir/netbsd"
NOOP=0 $DEBUG $RMDIR -- "$tmpdir"
return $?
fi
if [ "${bootedfile%.gz}" != "$bootedfile" ]; then
#compress the kernel
_info "Compressing kernel ${EDGEBSD_KERNEL}..."
$DEBUG $GZIP -f -- "$tmpdir/netbsd" &&
$DEBUG $MV -- "$tmpdir/netbsd.gz" "$tmpdir/netbsd"
if [ $? -ne 0 ]; then
_error "$EDGEBSD_KERNEL: Could not compress the kernel"
$DEBUG $RM -- "$tmpdir/netbsd" "$tmpdir/netbsd.gz"
NOOP=0 $DEBUG $RMDIR -- "$tmpdir"
return $?
fi
fi
if [ -f "$DESTDIR/altroot/$bootedfile" ]; then
$DEBUG $MV -- "$tmpdir/netbsd" "$DESTDIR/altroot/$bootedfile"
else
$DEBUG $MV -- "$tmpdir/netbsd" "$DESTDIR/$bootedfile"
fi
if [ $? -ne 0 ]; then
_error "$EDGEBSD_KERNEL: Could not update the kernel"
$DEBUG $RM -- "$tmpdir/netbsd"
NOOP=0 $DEBUG $RMDIR -- "$tmpdir"
return $?
fi
NOOP=0 $DEBUG $RMDIR -- "$tmpdir"
#request a reboot
return 3
}
_arch_i386_update_bootloader()
{
_arch_generic_update_bootloader || return 2
#detect the boot method
bootmethod=$($SYSCTL -n "machdep.bootmethod" 2> "$DEVNULL")
if [ $? -ne 0 -o -z "$bootmethod" ]; then
_error "Could not detect the boot method (assuming BIOS)"
bootmethod="BIOS"
fi
case "$bootmethod" in
UEFI)
#TODO update the EFI boot file
return 0
;;
BIOS)
_arch_i386_update_bootloader_bios
return $?
;;
*)
_error "$bootmethod: Unsupported boot method"
return $?
;;
esac
}
_arch_i386_update_bootloader_bios()
{
#XXX require the root device to be set
if [ -z "$ROOTDEV" ]; then
_error "Could not update the bootloader (root device not set)"
return 0
fi
#detect the underlying filesystem
filesystem=$($DUMPFS "$ROOTDEV" | $GREP '^format ')
if [ $? -ne 0 -o -z "$filesystem" ]; then
_error "$DESTDIR/: Could not detect the filesystem"
return $?
fi
filesystem=${filesystem#* }
case "$filesystem" in
FFSv1|FFSv2)
filesystem=$(echo "$filesystem" | _tolower)
;;
esac
if [ ! -f "${USRMDECBOOTXX}_$filesystem" ]; then
_error "$filesystem: Unsupported filesystem for boot partition"
return $?
fi
$DEBUG $INSTALLBOOT "$ROOTDEV" "${USRMDECBOOTXX}_$filesystem"
if [ $? -eq 0 ]; then
_error "$ROOTDEV: Could not install the bootloader"
return $?
fi
return 0
}
_arch_i386_update_kernel()
{
_arch_generic_update_kernel
}
_arch_sparc_update_bootloader()
{
_arch_generic_update_bootloader
}
_arch_sparc_update_kernel()
{
_arch_generic_update_kernel
}
_arch_sparc64_update_bootloader()
{
_arch_sparc_update_bootloader
}
_arch_sparc64_update_kernel()
{
_arch_sparc_update_kernel
}
#clean_kernel
_clean_kernel()
{
if [ $KERNEL -ne 0 ]; then
file="kern-${EDGEBSD_KERNEL}${SETEXT}"
[ -z "${EDGEBSD_MIRROR##/*}" ] && file="$EDGEBSD_PATH/$file"
#XXX ignore errors
if [ -f "$file" ]; then
_info "Removing downloaded kernel ${EDGEBSD_KERNEL}..."
$DEBUG $RM -- "$file"
fi
if [ $VERIFY -ne 0 -a -f "$file.sig" ]; then
_info "Removing downloaded signature for kernel ${EDGEBSD_KERNEL}..."
$DEBUG $RM -- "$file.sig"
fi
fi
}
#clean_sets
_clean_sets()
{
keep="$1"
for set in $SETS; do
[ -n "$keep" -a "$keep" = "$set" ] && continue
file="$set${SETEXT}"
[ -z "${EDGEBSD_MIRROR##/*}" ] && file="$EDGEBSD_PATH/$file"
#XXX ignore errors
if [ -f "$file" ]; then
_info "Removing downloaded set ${set}..."
$DEBUG $RM -- "$file"
fi
if [ $VERIFY -ne 0 -a -f "$file.sig" ]; then
_info "Removing downloaded signature for set ${set}..."
$DEBUG $RM -- "$file.sig"
fi
done
}
#debug
_debug()
{
[ $VERBOSE -ge 3 ] && echo "$@" 1>&2
[ $NOOP -ne 0 ] || "$@"
}
#detect_kernel
_detect_kernel()
{
kernel=$($UNAME -v)
kernel="${kernel##*(}"
echo "${kernel%)*}"
}
#detect_release
_detect_release()
{
if [ -n "$1" ]; then
EDGEBSD_RELEASE="$EDGEBSD_VENDOR-$1"
elif [ -z "$EDGEBSD_RELEASE" ]; then
EDGEBSD_RELEASE=$($UNAME -r)
case "$EDGEBSD_VENDOR" in
NetBSD)
EDGEBSD_RELEASE="${EDGEBSD_RELEASE%_*}"
;;
*)
EDGEBSD_RELEASE="${EDGEBSD_RELEASE%.*}"
;;
esac
EDGEBSD_RELEASE="$EDGEBSD_VENDOR-$EDGEBSD_RELEASE"
fi
}
#detect_sets
_detect_sets()
{
for i in "$DESTDIR$ETCMTREE/set."*; do
[ -f "$i" ] || continue
set="${i#$DESTDIR$ETCMTREE/set.}"
[ -z "$set" ] || echo "$set"
done
}
#download
_download()
{
file="$1"
NOOP=0 $DEBUG $FTP "$EDGEBSD_PATH/$file"
res=$?
[ $res -eq 0 ] || $DEBUG $RM -- "$file"
return $res
}
#download_kernel
_download_kernel()
{
#download the kernel
if [ $KERNEL -ne 0 -a -n "${EDGEBSD_MIRROR##/*}" ]; then
if [ ! -f "kern-${EDGEBSD_KERNEL}${SETEXT}" ]; then
_info "Downloading kernel ${EDGEBSD_KERNEL}..."
_download "kern-${EDGEBSD_KERNEL}${SETEXT}"
return $?
fi
fi
return 0
}
#download_kernel_signature
_download_kernel_signature()
{
#download the kernel signature
if [ $KERNEL -ne 0 -a -n "${EDGEBSD_MIRROR##/*}" ]; then
if [ $VERIFY -ne 0 -a ! -f "kern-${EDGEBSD_KERNEL}${SETEXT}.sig" ]; then
_info "Downloading signature for kernel ${EDGEBSD_KERNEL}..."
_download "kern-${EDGEBSD_KERNEL}${SETEXT}.sig"
return $?
fi
fi
return 0
}
#download_sets
_download_sets()
{
res=0
#download the relevant sets
for set in $SETS; do
[ -z "${EDGEBSD_MIRROR##/*}" ] && continue
[ -f "${set}${SETEXT}" ] && continue
_info "Downloading set ${set}..."
_download "${set}${SETEXT}"
res=$?
[ $res -eq 0 ] || break
[ $VERIFY -eq 0 ] && continue
_info "Downloading signature for set ${set}..."
_download "${set}${SETEXT}.sig"
res=$?
[ $res -eq 0 ] || break
done
if [ $res -ne 0 -a -n "${EDGEBSD_MIRROR##/*}" ]; then
for set in $SETS; do
$DEBUG $RM -- "${set}${SETEXT}"
[ $VERIFY -eq 0 ] && continue
$DEBUG $RM -- "${set}${SETEXT}.sig"
done
fi
return $res
}
#error
_error()
{
echo "$PROGNAME: $@" 1>&2
return 2
}
#import_gpg_key
_import_gpg_key()
{
ret=0
tmpfile=$($MKTEMP "$MKTEMP_TEMPLATE")
[ $? -eq 0 ] || return 2
_import_gpg_key_echo > "$tmpfile" &&
$DEBUG $NETPGPKEYS --import-key "$tmpfile" > "$DEVNULL" || ret=2
$RM -- "$tmpfile"
return $ret
}
#import_gpg_key_echo
_import_gpg_key_echo()
{
echo "-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1
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
mEH+2rR/ZC0mmQ==
=dmei
-----END PGP PUBLIC KEY BLOCK-----"
}
#info
_info()
{
[ $VERBOSE -lt 2 ] || echo "$PROGNAME: $@"
}
#progress
_progress()
{(
cat="$CAT"
options=
filename=
prefix=
while getopts "ef:p:z" name; do
case "$name" in
e)
options="-e $options"
;;
f)
#XXX must be last
options="$options -f"
filename="$OPTARG"
;;
p)
prefix="$OPTARG"
;;
z)
options="-z $options"
cat="$ZCAT"
;;
*)
_progress_usage
return $?
;;
esac
done
shift $((OPTIND - 1))
if [ $# -lt 1 ]; then
return 1
fi
#only use progress(1) if in interactive and verbose mode
if [ \( -n "$PS1" -o $INIT -ne 0 \) -a $VERBOSE -ge 1 ]; then
$DEBUG $PROGRESS -p "$prefix" $options "$filename" -- "$@"
else
$DEBUG $cat -- "$filename" | "$@"
fi
)}
_progress_usage()
{
echo "Usage: progress [-ez][-f filename][-p prefix] cmd [args...]" 1>&2
return 1
}
#tolower
_tolower()
{
$TR A-Z a-z
}
#update_bootloader
_update_bootloader()
{
#update the bootloader
if [ $BOOTLOADER -ne 0 ]; then
_info "Updating the bootloader..."
case "$EDGEBSD_ARCH" in
amd64|evbarm|i386|sparc|sparc64)
"_arch_${EDGEBSD_ARCH}_update_bootloader"
return $?
;;
*)
return 2
;;
esac
fi
return 0
}
#update_configuration
_update_configuration()
{
res=0
#update the configuration
if [ $UPDATE_ETC -eq 1 ]; then
set="etc"
file="${set}${SETEXT}"
[ -z "${EDGEBSD_MIRROR##/*}" ] && file="$EDGEBSD_PATH/$file"
if [ $VERIFY -ne 0 ]; then
_info "Verifying set ${set}..."
_verify "$file"
res=$?
[ $res -eq 0 ] || return $res
fi
_info "Updating the configuration..."
$DEBUG $POSTINSTALL -s "$file" -d "$DESTDIR/" fix > "$DEVNULL"
res=$?
fi
return $res
}
#update_file
_update_file()
{
mode="$1"
src="$2"
dst="$3"
$DEBUG $CMP "$src" "$dst" > "$DEVNULL"
[ $? -eq 0 ] || $DEBUG $INSTALL -m "$mode" "$src" "$dst"
}
#update_kernel
_update_kernel()
{
#update the kernel
if [ $KERNEL -ne 0 ]; then
_info "Updating the kernel..."
case "$EDGEBSD_ARCH" in
amd64|evbarm|i386|sparc|sparc64)
"_arch_${EDGEBSD_ARCH}_update_kernel"
return $?
;;
esac
return 2
fi
return 0
}
#update_packages
_update_packages()
{
#update the packages
if [ $PACKAGES -ne 0 ]; then
_info "Updating the packages..."
if [ -n "$DESTDIR" ]; then
$DEBUG $PKGIN -y -c "$DESTDIR" full-upgrade
else
$DEBUG $PKGIN -y full-upgrade
fi
return $?
fi
return 0
}
#update_reboot
_update_reboot()
{
if [ $INIT -ne 0 ]; then
if [ $UPDATE_ETC -eq 1 -a -z "$clean_sets_keep" ]; then
_info "Rebooting after set update..."
$DEBUG $REBOOT
return $?
else
_error "Partial update (not rebooting)"
fi
fi
return 0
}
#update_sets
_update_sets()
{(
ret=0
reset_cursor=0
#verify the sets available if requested
if [ $VERIFY -ne 0 ]; then
_info "Verifying the sets..."
for set in $SETS; do
file="${set}${SETEXT}"
[ -z "${EDGEBSD_MIRROR##/*}" ] && file="$EDGEBSD_PATH/$file"
#missing sets are caught later
[ -f "$file" ] || continue
_info "Verifying set ${set}..."
#XXX TOCTOU
_verify "$file"
res=$?
[ $res -eq 0 ] || ret=$res
done
[ $ret -eq 0 ] || return $ret
fi
#update the relevant sets
_info "Updating the sets..."
$MKDIR -- "$DESTDIR/"
if [ $? -ne 0 ]; then
_error "$DESTDIR: Could not create the destination directory"
return $?
fi
for set in $SETS; do
file="${set}${SETEXT}"
[ -z "${EDGEBSD_MIRROR##/*}" ] && file="$EDGEBSD_PATH/$file"
if [ ! -f "$file" ]; then
if [ $INIT -ne 0 ]; then
_info "$set: Skipping set update (update file missing)"
continue
fi
_error "$set: Set file missing"
ret=$?
break
fi
if [ "$set" = "etc" ]; then
UPDATE_ETC=1
#skip the "etc" set if already installed
[ -f "$DESTDIR$ETCMTREE/set.$set" ] && continue
fi
_progress -f "$file" -p "$($PRINTF "%-7s " "${set}")" \
$TAR -xzpf - -C "$DESTDIR/"
res=$?
reset_cursor=1
if [ $res -ne 0 ]; then
ret=$res
break
fi
#also extract the modules to /altroot if relevant
if [ "$set" = "modules" -a -d "$DESTDIR/altroot/stand" ]; then
_progress -f "$file" -p "$($PRINTF "%-7s " "${set}")" \
$TAR -xzpf - -C "$DESTDIR/altroot"
res=$?
if [ $res -ne 0 ]; then
ret=$res
break
fi
fi
done
#XXX ensure the cursor position is always set correctly
[ $reset_cursor -ne 0 ] && echo
return $ret
)}
#usage
_usage()
{
echo "Usage: $PROGNAME [-BbIKkmnpqSsv][-D destdir][-M mirror][-P path][-r release]" 1>&2
echo " -B Do not update the bootloader" 1>&2
echo " -b Update the bootloader" 1>&2
echo " -D Specify a different directory where to update" 1>&2
echo " -I Perform a boot-time update" 1>&2
echo " -K Do not update the kernel" 1>&2
echo " -k Update the kernel" 1>&2
echo " -M Specify a different mirror when downloading" 1>&2
echo " -m Update the kernel modules" 1>&2
echo " -n Download the sets but do not actually update" 1>&2
echo " -P Full path to the sets" 1>&2
echo " -p Update the packages" 1>&2
echo " -q Enable quiet mode" 1>&2
echo " -r Set the release" 1>&2
echo " -S Do not verify signatures" 1>&2
echo " -s Verify signatures (default)" 1>&2
echo " -v Be more verbose" 1>&2
return 1
}
#verify
_verify()
{
file="$1"
$NETPGP --verify --userid "$VERIFY_USERID" "${file}.sig"
}
#main
#parse arguments
while getopts "D:O:M:P:BbIKkmnpqr:Ssv" name; do
case "$name" in
D)
DESTDIR="$OPTARG"
;;
O)
export "${OPTARG%%=*}"="${OPTARG#*=}"
;;
P)
EDGEBSD_PATH="$OPTARG"
;;
B)
BOOTLOADER=0
;;
b)
BOOTLOADER=1
;;
I)
BOOTLOADER=1
KERNEL=1
INIT=1
;;
K)
KERNEL=0
;;
k)
KERNEL=1
;;
M)
EDGEBSD_MIRROR="$OPTARG"
;;
m)
MODULES=1
;;
n)
NOOP=1
;;
p)
PACKAGES=1
;;
q)
FTP="/usr/bin/ftp -V"
VERBOSE=0
;;
r)
RELEASE="$OPTARG"
;;
S)
VERIFY=0
;;
s)
VERIFY=1
;;
v)
VERBOSE=$((VERBOSE + 1))
[ $VERBOSE -ge 1 ] && FTP="/usr/bin/ftp"
[ $VERBOSE -ge 2 ] && FTP="/usr/bin/ftp -v"
;;
*)
_usage
exit $?
;;
esac
done
shift $((OPTIND - 1))
if [ $# -ne 0 ]; then
_usage
exit $?
fi
_edgebsd_update