sortix-mirror/tix/tix-upgrade
Jonas 'Sortie' Termansen 1adf011044 Add tix-upgrade(8).
2023-07-16 16:03:00 +02:00

213 lines
6.3 KiB
Bash
Executable file

#!/bin/sh
# Copyright (c) 2017, 2021, 2023 Jonas 'Sortie' Termansen.
#
# 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.
#
# tix-upgrade
# Upgrade operating system and ports.
set -e
cachedir=""
clean=false
collection=""
download_only=false
fetch_options=
ports_only=false
sysroot=""
upgrade_ports=false
upgrade_system=false
wait=""
dashdash=
previous_option=
for argument do
if test -n "$previous_option"; then
eval $previous_option=\$argument
previous_option=
shift
continue
fi
case $argument in
*=?*) parameter=$(expr "X$argument" : '[^=]*=\(.*\)' || true) ;;
*=) parameter= ;;
*) parameter=yes ;;
esac
case $dashdash$argument in
--) dashdash=yes ;;
-w) wait=-w ;;
--cachedir=*) cachedir=$parameter ;;
--cachedir) previous_option=cachedir ;;
--clean) clean=true ;;
--collection=*) collection=$parameter ;;
--collection) previous_option=collection ;;
--download-only) download_only=true ;;
--insecure-downgrade-to-http) fetch_options="$fetch_options $argument" ;;
--insecure-no-check-certificate) fetch_options="$fetch_options $argument" ;;
--ports) upgrade_ports=true ;;
--system) upgrade_system=true ;;
--sysroot) previous_option=sysroot ;;
--sysroot=*) sysroot=$parameter ;;
--wait) wait=--wait ;;
-*) echo "$0: unrecognized option $argument" >&2
exit 1 ;;
*) break ;;
esac
shift
done
if test -n "$previous_option"; then
echo "$0: option '$argument' requires an argument" >&2
exit 1
fi
# TODO: Reject additional operands.
if [ -z "$collection" ]; then
collection="$sysroot"
fi
if [ -n "$collection" ]; then
collection=$(cd "$collection" && pwd)
fi
if ! $upgrade_ports && ! $upgrade_system; then
# TODO: Ability to set default in /etc/upgrade.conf.
upgrade_ports=true
upgrade_system=true
fi
# Update only ports if this isn't a whole system installation.
if [ ! -e "$collection/tix/manifest/system" ]; then
upgrade_system=false
fi
if [ -z "$cachedir" ]; then
cachedir="$collection/var/cache/tix"
fi
if $clean; then
echo "Removing cache directory: $cachedir"
rm -rf -- "$cachedir"
fi
mkdir -p -- "$cachedir"
mkdir -p -- "$cachedir/new"
# Fetch the latest official release.sig.sh and its matching sha256sum file.
tix-fetch $fetch_options \
--collection="$collection" \
--output-release-sig-file="$cachedir/new/release.sh.sig" \
--output-sha256sum="$cachedir/new/sha256sum"
# If release.sig.sh or sha256sum changed, clean the cache directory of downloads
# that were currently in progress as they might not have the right checksums.
# TODO: This requires diff(1) in the base system! Avoid that. Get a cmp(1)!
if ! diff -- "$cachedir/release.sh.sig" \
"$cachedir/new/release.sh.sig" 1>/dev/null 2>/dev/null ||
! diff -- "$cachedir/sha256sum" \
"$cachedir/new/sha256sum" 1>/dev/null 2>/dev/null; then
rm -rf -- "$cachedir/boot"
rm -rf -- "$cachedir/repository"
rm -rf -- "$cachedir/sysroot"
fi
# Store the new release.sig.sh and sha256sum files so we can resume the download
# if cancelled and these files still match.
mv -- "$cachedir/new/release.sh.sig" "$cachedir/release.sh.sig"
mv -- "$cachedir/new/sha256sum" "$cachedir/sha256sum"
rm -rf -- "$cachedir/new"
mkdir -p "$cachedir/boot"
mkdir -p "$cachedir/repository"
# TODO: Support upgrading across releases, renamed channels, etc.
if $upgrade_system; then
# Fetch the base system initrds from the mirror.
# TODO: What about the system source code in /src?
# TODO: Get the overlay initrd if it exists.
tix-fetch $fetch_options \
--collection="$collection" \
--input-release-sig-file="$cachedir/release.sh.sig" \
--input-sha256sum="$cachedir/sha256sum" \
-c --initrd -O "$cachedir/boot" -- system
fi
if $upgrade_ports; then
# Fetch each port from the mirror.
ports=$(LC_ALL=C ls -- "$collection/tix/tixinfo")
# TODO: Handle new mandatory / recommended ports.
# TODO: Handle renamed ports.
# TODO: This fails if the port does not exist upstream.
mkdir -p "$cachedir/repository"
for port in $ports; do
# The port has a hash if if it exists upstream.
sha256=$(tix-fetch $fetch_options \
--collection="$collection" \
--input-release-sig-file="$cachedir/release.sh.sig" \
--input-sha256sum="$cachedir/sha256sum" \
--sha256 --port -- $port)
# If the port exists upstream, get the latest version.
if [ -n "$sha256" ]; then
tix-fetch $fetch_options \
--collection="$collection" \
--input-release-sig-file="$cachedir/release.sh.sig" \
--input-sha256sum="$cachedir/sha256sum" \
-c --port -O "$cachedir/repository" -- $port
fi
done
fi
# Stop if only downloading.
if $download_only; then
exit
fi
rm -rf -- "$cachedir/sysroot"
mkdir -p -- "$cachedir/sysroot"
# Extract the base system into the sysroot.
if $upgrade_system; then
echo "Extracting system.tar.xz..."
tar -C "$cachedir/sysroot" -xJf "$cachedir/boot/system.tar.xz"
rm -f "$cachedir/boot/system.tar.xz"
fi
# Extract the ports into the sysroot.
full=
if $upgrade_ports; then
full=--full
for port in $ports; do
echo "Extracting $port.tix.tar.xz..."
tar -C "$cachedir/sysroot" -xJf "$cachedir/repository/$port.tix.tar.xz"
rm -f "$cachedir/repository/$port.tix.tar.xz"
done
fi
case "$upgrade_system$upgrade_ports" in
truefalse) what_to_upgrade=--system;;
falsetrue) what_to_upgrade=--ports;;
*) what_to_upgrade=;;
esac
# Merge the new sysroot onto the installation.
sysmerge -t "$collection" $what_to_upgrade $full $wait "$cachedir/sysroot"
rm -rf -- "$cachedir/boot"
rm -rf -- "$cachedir/repository"
rm -rf -- "$cachedir/sysroot"