230 lines
7.2 KiB
Bash
Executable file
230 lines
7.2 KiB
Bash
Executable file
#!/bin/sh
|
|
# Copyright (c) 2017, 2021 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
|
|
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
|
|
ports_only=true
|
|
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 latest release.sig.sh from the master and its matching sha256sum file.
|
|
tix-fetch $fetch_options \
|
|
--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"
|
|
|
|
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 \
|
|
--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 sort -- "$collection/tix/installed.list")
|
|
# 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 \
|
|
--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 \
|
|
--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"
|
|
|
|
if $upgrade_system; then
|
|
# Extract the base system into the sysroot.
|
|
rm -rf -- "$cachedir/sysroot"
|
|
mkdir -p -- "$cachedir/sysroot"
|
|
for initrd in system overlay; do
|
|
initrd_path="$cachedir/boot/$initrd.initrd"
|
|
if [ -e "$initrd_path.xz" ]; then
|
|
echo "Extracting $initrd.initrd.xz..."
|
|
unxz -k "$initrd_path.xz"
|
|
initrdfs "$initrd_path" extract -C "$cachedir/sysroot" /
|
|
rm -f "$initrd_path.xz"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# TODO: These install all the ports in "$cachedir/repository" but the directory
|
|
# might not have been cleared, it could contain unverified ports.
|
|
if $upgrade_system; then
|
|
# Do a full system upgrade using the sysroot and the new ports.
|
|
# TODO: If sysmerge -w, such as on ABI upgrades, the e2fsprogs package is not
|
|
# installed in the system root and the new initrd might not contain a
|
|
# /sbin/fsck.ext2 and the system can become bricked if it needs a fsck
|
|
# on boot.
|
|
# TODO: There's no support here for doing a sysmerge on a given sysroot.
|
|
if $upgrade_ports; then
|
|
# TODO: Get the architecture from somewhere else than /etc/machine?
|
|
tix-collection "$cachedir/sysroot" create \
|
|
--platform="$(cat -- "$sysroot/etc/machine")-sortix" \
|
|
--prefix= --generation=2
|
|
tix-install --collection="$cachedir/sysroot" -- "$cachedir/repository/"*
|
|
full=--full
|
|
else
|
|
# TODO: Is this case supported?
|
|
full=
|
|
fi
|
|
sysmerge $full $wait "$cachedir/sysroot"
|
|
elif $upgrade_ports; then
|
|
# Upgrade to each of the new ports.
|
|
# TODO: tix-install --reinstall is unsupported due to lack of support for
|
|
# files moving between manifests or being deleted.
|
|
tix-install --reinstall -- "$cachedir/repository/"*
|
|
fi
|
|
|
|
rm -rf -- "$cachedir/boot"
|
|
rm -rf -- "$cachedir/repository"
|
|
rm -rf -- "$cachedir/sysroot"
|
|
|
|
#tmp=
|
|
#trap '[ -n "$tmp" ] && rm -rf "$tmp"' EXIT HUP INT QUIT TERM
|
|
#tmp=$(mktemp -dt upgrade.XXXXXX)
|
|
#mkdir -p "$tmp/tmp"
|
|
#export TMPDIR="$tmp/tmp"
|
|
#(cd "$tmp" && tix-fetch --release -o sortix.iso)
|
|
#mkdir -p "$tmp/sortix.iso.d"
|
|
#echo "Extracting sortix.iso..."
|
|
#xorriso -osirrox on -indev "$tmp/sortix.iso" -extract / "$tmp/sortix.iso.d" > /dev/null 2> /dev/null
|
|
#rm -f "$tmp/sortix.iso"
|