Add installtest script for testing installing and upgrading.
This commit is contained in:
parent
b6f088a52a
commit
34e1318880
1 changed files with 457 additions and 0 deletions
457
build-aux/installtest.sh
Executable file
457
build-aux/installtest.sh
Executable file
|
@ -0,0 +1,457 @@
|
|||
#!/bin/sh
|
||||
# Copyright (c) 2022, 2023, 2024, 2025 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.
|
||||
#
|
||||
# installtest.sh
|
||||
# Test an .iso release can be installed and upgraded.
|
||||
|
||||
set -e
|
||||
|
||||
all=false
|
||||
unset bios
|
||||
unset display
|
||||
display="-display none"
|
||||
unset enable_kvm
|
||||
harddisk_size=4G
|
||||
firmware=bios
|
||||
unset host
|
||||
unset hostname
|
||||
hostname=installtest
|
||||
install=false
|
||||
minimal=false
|
||||
unset input
|
||||
unset iso
|
||||
iso_upgrade=false
|
||||
unset output
|
||||
partitioning=gpt
|
||||
unset port
|
||||
unset qemu
|
||||
unset release
|
||||
unset release_key
|
||||
unset release_url
|
||||
source_upgrade=false
|
||||
unset version
|
||||
unset vm_root
|
||||
|
||||
dashdash=
|
||||
previous_option=
|
||||
for argument do
|
||||
if [ -n "$previous_option" ]; then
|
||||
eval $previous_option=\$argument
|
||||
previous_option=
|
||||
continue
|
||||
fi
|
||||
|
||||
case $argument in
|
||||
*=?*) parameter=$(expr "X$argument" : '[^=]*=\(.*\)' || true) ;;
|
||||
*=) parameter= ;;
|
||||
*) parameter=yes ;;
|
||||
esac
|
||||
|
||||
case $dashdash$argument in
|
||||
--) dashdash=yes ;;
|
||||
--all) all=true ;;
|
||||
--bios) previous_option=bios ;;
|
||||
--bios=*) bios=$parameter ;;
|
||||
--display) previous_option=display ;;
|
||||
--display=*) display=$parameter ;;
|
||||
--enable-kvm) enable_kvm=-enable-kvm ;;
|
||||
--firmware) previous_option=firmware ;;
|
||||
--firmware=*) firmware=$parameter ;;
|
||||
--harddisk-size) previous_option=harddisk_size ;;
|
||||
--harddisk-size=*) harddisk_size=$parameter ;;
|
||||
--host) previous_option=host ;;
|
||||
--host=*) host=$parameter ;;
|
||||
--hostname) previous_option=hostname ;;
|
||||
--hostname=*) hostname=$parameter ;;
|
||||
--input) previous_option=input ;;
|
||||
--input=*) input=$parameter ;;
|
||||
--install) install=true ;;
|
||||
--iso) previous_option=iso ;;
|
||||
--iso=*) iso=$parameter ;;
|
||||
--iso-upgrade) iso_upgrade=true ;;
|
||||
--minimal) minimal=true ;;
|
||||
--output) previous_option=output ;;
|
||||
--output=*) output=$parameter ;;
|
||||
--partitioning) previous_option=partitioning ;;
|
||||
--partitioning=*) partitioning=$parameter ;;
|
||||
--port) previous_option=port ;;
|
||||
--port=*) port=$parameter ;;
|
||||
--qemu) previous_option=qemu ;;
|
||||
--qemu=*) qemu=$parameter ;;
|
||||
--release) previous_option=release ;;
|
||||
--release=*) release=$parameter ;;
|
||||
--release-key) previous_option=release_key ;;
|
||||
--release-key=*) release_key=$parameter ;;
|
||||
--release-url) previous_option=release_url ;;
|
||||
--release-url=*) release_url=$parameter ;;
|
||||
--source-upgrade) source_upgrade=true ;;
|
||||
--version) previous_option=version ;;
|
||||
--version=*) version=$parameter ;;
|
||||
--vm-root) previous_option=vm_root ;;
|
||||
--vm-root=*) vm_root=$parameter ;;
|
||||
-*) echo "$0: unrecognized option $argument" >&2
|
||||
exit 1 ;;
|
||||
*)
|
||||
echo "$0: unexpected extra operand '$argument'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "$previous_option" ]; then
|
||||
echo "$0: option '$argument' requires an argument" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$host" ]; then
|
||||
echo "$0: error: No --host was specified" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$iso" ]; then
|
||||
echo "$0: error: No --iso was specified" >&2
|
||||
exit 1
|
||||
fi
|
||||
iso=$(realpath -- "$iso")
|
||||
|
||||
if [ -z "$port" ]; then
|
||||
echo "$0: error: No --port was specified" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$bios" in "" | /*) ;; *) bios="$PWD/$bios" ;; esac
|
||||
case "$iso" in "" | /*) ;; *) iso="$PWD/$iso" ;; esac
|
||||
case "$input" in "" | /*) ;; *) input="$PWD/$input" ;; esac
|
||||
case "$output" in "" | /*) ;; *) output="$PWD/$input" ;; esac
|
||||
|
||||
if $all; then
|
||||
mkdir -p "$input"
|
||||
mkdir -p "$output"
|
||||
|
||||
set -x
|
||||
|
||||
if [ "$version" = "$release" ]; then
|
||||
prefix="$version"
|
||||
else
|
||||
prefix="$version-$release"
|
||||
fi
|
||||
|
||||
new_stable=${version%-*}
|
||||
new_stable_regexp=^$(echo "$new_stable" | sed -E 's/\./\\./g')$
|
||||
version_regexp=^$(echo "$version" | sed -E 's/\./\\./g')$
|
||||
old_stable=$( (find "$input" -name '*.release' -exec cat '{}' ';' |
|
||||
grep -Ev -- - |
|
||||
grep -Ev "$new_stable_regexp";
|
||||
echo "$version") |
|
||||
sort -Vu | grep -E "$version_regexp" -B1 | tail -2 | head -1)
|
||||
|
||||
# Test installation.
|
||||
"$0" ${enable_kvm+--enable-kvm} --host="$host" --port="$port" --iso="$iso" \
|
||||
${display+--display="$display"} --bios="$bios" --firmware=bios \
|
||||
--install --partitioning=gpt --output="$output/$prefix-$host.hdd"
|
||||
|
||||
# Test minimal installation.
|
||||
"$0" ${enable_kvm+--enable-kvm} --host="$host" --port="$port" --iso="$iso" \
|
||||
${display+--display="$display"} --bios="$bios" --firmware=bios \
|
||||
--install --partitioning=gpt --minimal \
|
||||
--output="$output/$prefix-$host-minimal.hdd"
|
||||
|
||||
# Test upgrading an the previous stable to the current release.
|
||||
if [ -e "$input/$old_stable-$host.hdd" ]; then
|
||||
old_stable_input="$input/$old_stable-$host.hdd"
|
||||
else
|
||||
old_stable_input="$output/$prefix-$host.hdd"
|
||||
fi
|
||||
"$0" ${enable_kvm+--enable-kvm} --host="$host" --port="$port" --iso="$iso" \
|
||||
${display+--display="$display"} --bios="$bios" --iso-upgrade \
|
||||
--input="$old_stable_input"
|
||||
|
||||
# Test upgrading from source.
|
||||
if [ -e "$input/$prefix-$host.hdd" ]; then
|
||||
previous_input="$input/$prefix-$host.hdd"
|
||||
else
|
||||
previous_input="$output/$prefix-$host.hdd"
|
||||
fi
|
||||
"$0" ${enable_kvm+--enable-kvm} --host="$host" --port="$port" --iso="$iso" \
|
||||
${display+--display="$display"} --bios="$bios" --source-upgrade \
|
||||
--release-key="$release_key" --release-url="$release_url" \
|
||||
--input="$previous_input"
|
||||
|
||||
echo "$version" > "$output/$prefix.release"
|
||||
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! $install && ! $iso_upgrade && ! $source_upgrade; then
|
||||
install=true
|
||||
fi
|
||||
|
||||
if $minimal; then
|
||||
memory=300
|
||||
elif $source_upgrade; then
|
||||
memory=512
|
||||
else
|
||||
memory=1280
|
||||
fi
|
||||
|
||||
if [ -z "$qemu" ]; then
|
||||
case "$host" in
|
||||
i[3456]86-*) qemu=qemu-system-i386;;
|
||||
x86_64-*) qemu=qemu-system-x86_64;;
|
||||
*) echo "$0: error: Unable to detect qemu program for: $HOST" >&2
|
||||
exit 1
|
||||
esac
|
||||
fi
|
||||
|
||||
unset tmpdir
|
||||
# Reclaim a persistent VM directory (if any) and kill any leaked processes.
|
||||
if [ -n "$vm_root" ]; then
|
||||
unset tmpdir
|
||||
export TMPDIR="$vm_root/$hostname"
|
||||
mkdir -p -- "$TMPDIR"
|
||||
if [ -e "$TMPDIR/pid" ]; then
|
||||
kill -KILL "$(cat "$TMPDIR/pid")" || true
|
||||
fi
|
||||
rm -rf -- "$TMPDIR"/*
|
||||
# Otherwise use a temporary directory that will be deleted upon completion.
|
||||
else
|
||||
export TMPDIR=$(mktemp -d -t "$hostname.vm.XXXXXXXXX")
|
||||
tmpdir="$TMPDIR"
|
||||
fi
|
||||
|
||||
# On exit, power off the virtual machine and clean up the working directory.
|
||||
unset vmpid
|
||||
cleanup_tmpdir() {
|
||||
if [ -n "$vmpid" ]; then
|
||||
kill -KILL $vmpid || true
|
||||
fi
|
||||
rm -f "$TMPDIR/pid"
|
||||
if [ -n "$tmpdir" ]; then
|
||||
rm -rf -- "$tmpdir"
|
||||
elif [ -n "$TMPDIR" ]; then
|
||||
rm -rf -- "$TMPDIR"/*
|
||||
fi
|
||||
}
|
||||
trap cleanup_tmpdir EXIT HUP INT QUIT
|
||||
cd "$TMPDIR"
|
||||
|
||||
set -x
|
||||
|
||||
# Create the installation harddisk
|
||||
if [ -n "$input" ]; then
|
||||
cp "$input" sortix.hdd
|
||||
cp "$input.firmware" sortix.hdd.firmware
|
||||
firmware=$(cat sortix.hdd.firmware)
|
||||
# TODO: After releasing Sortix 1.1, remove this hack for Sortix 1.0 compat.
|
||||
if ! $iso_upgrade; then
|
||||
cp "$input.known_hosts" sortix.hdd.known_hosts
|
||||
cp "$input.id_rsa" sortix.hdd.id_rsa
|
||||
cp "$input.id_rsa.pub" sortix.hdd.id_rsa.pub
|
||||
fi
|
||||
else
|
||||
if ! $install; then
|
||||
echo "$0: error: --input must be used when --install is not used"
|
||||
exit 1
|
||||
fi
|
||||
qemu-img create -f qcow2 sortix.hdd $harddisk_size
|
||||
echo "$firmware" > sortix.hdd.firmware
|
||||
fi
|
||||
if [ "$firmware" != efi ]; then
|
||||
unset bios
|
||||
fi
|
||||
|
||||
# Configure the ssh authentication and enable sshd.
|
||||
if $install || $iso_upgrade; then
|
||||
ssh-keygen -f id_rsa -N ''
|
||||
rm -rf liveconfig bootconfig
|
||||
tix-iso-liveconfig \
|
||||
--hostname="$hostname" \
|
||||
--root-ssh-authorized-keys=id_rsa.pub \
|
||||
--sshd-keygen \
|
||||
--sshd-key-known-hosts-file=sortix.iso.known_hosts \
|
||||
--sshd-key-known-hosts-hosts='localhost 127.0.0.1' \
|
||||
liveconfig
|
||||
mkdir -p liveconfig/etc liveconfig/etc/init
|
||||
cat > liveconfig/etc/init/local << EOF
|
||||
require sshd optional
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Enable automatic installation.
|
||||
if $install; then
|
||||
cat >> liveconfig/etc/autoinstall.conf << EOF
|
||||
accept_defaults=yes
|
||||
countdown=0
|
||||
grub=yes
|
||||
EOF
|
||||
if [ $partitioning = mbr ]; then
|
||||
echo "disked++=mktable mbr" >> liveconfig/etc/autoinstall.conf
|
||||
elif [ $partitioning = gpt ]; then
|
||||
echo "disked++=mktable gpt" >> liveconfig/etc/autoinstall.conf
|
||||
fi
|
||||
if [ $partitioning = gpt -a $firmware = bios ]; then
|
||||
echo "disked++=mkpart 1 0% 1M biosboot" >> liveconfig/etc/autoinstall.conf
|
||||
fi
|
||||
cat >> liveconfig/etc/autoinstall.conf << EOF
|
||||
disked++=mkpart 1 0% 100% ext2 /
|
||||
hostname=$HOSTNAME
|
||||
enable_sshd=yes
|
||||
password_hash_root=x
|
||||
finally!++=sed -Ei -- "s/src = yes/src = no/" etc/upgrade.conf
|
||||
finally!++=chroot -d . sh -c 'echo GRUB_TIMEOUT=0 >> etc/grub && update-grub'
|
||||
finally!++=echo exit
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Enable automatic upgrading.
|
||||
if $iso_upgrade; then
|
||||
cat >> liveconfig/etc/autoupgrade.conf << EOF
|
||||
accept_defaults=yes
|
||||
countdown=0
|
||||
# TODO: After releasing Sortix 1.1, remove support for the old disk image
|
||||
# without sshd support.
|
||||
finally!++=cp -t etc /etc/ssh*
|
||||
finally!++=cp -RT /root/.ssh root/.ssh
|
||||
finally!++=echo require sshd optional >> etc/init/local
|
||||
finally!++=echo exit
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Customize the bootloader configuration.
|
||||
if $install || $iso_upgrade; then
|
||||
tix-iso-bootconfig \
|
||||
--random-seed \
|
||||
--timeout=0 \
|
||||
--disable-gui \
|
||||
--liveconfig=liveconfig \
|
||||
bootconfig
|
||||
mkdir -p bootconfig/boot/grub
|
||||
if "$minimal"; then
|
||||
cat >> bootconfig/boot/grub/hooks.cfg << EOF
|
||||
select_ports_set_minimal
|
||||
port_ssh=true
|
||||
EOF
|
||||
fi
|
||||
tix-iso-add "$iso" bootconfig -o sortix.iso
|
||||
fi
|
||||
|
||||
# Spawn the virtual machine in the background.
|
||||
qemu() {
|
||||
exec $qemu \
|
||||
$enable_kvm \
|
||||
-no-reboot \
|
||||
${bios+-bios "$bios"} \
|
||||
-name "$hostname" \
|
||||
-nodefaults \
|
||||
$display \
|
||||
-m $memory \
|
||||
-vga std \
|
||||
-hda sortix.hdd \
|
||||
-device e1000,netdev=net0 \
|
||||
-netdev user,id=net0,hostfwd=tcp:127.0.0.1:$port-:22 \
|
||||
"$@"
|
||||
}
|
||||
if $install || $iso_upgrade; then
|
||||
qemu -cdrom sortix.iso -boot d &
|
||||
else
|
||||
qemu &
|
||||
fi
|
||||
vmpid=$!
|
||||
echo $vmpid > pid
|
||||
|
||||
# Wait for the virtual machine to boot to sshd.
|
||||
key=id_rsa
|
||||
known_hosts=sortix.iso.known_hosts
|
||||
do_ssh() {
|
||||
ssh \
|
||||
-i $key \
|
||||
-oUserKnownHostsFile=$known_hosts \
|
||||
-oConnectionAttempts=30 \
|
||||
-p $port \
|
||||
root@localhost \
|
||||
"$@"
|
||||
}
|
||||
wait_ssh() {
|
||||
retries=30
|
||||
while true; do
|
||||
if ! do_ssh 'uname -a'; then
|
||||
if [ $retries = 1 ]; then
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
if ! kill -WINCH "$vmpid"; then
|
||||
unset vmpid
|
||||
rm -f "$TMPDIR/pid"
|
||||
exit 1
|
||||
fi
|
||||
retries=$(expr $retries - 1)
|
||||
continue
|
||||
fi
|
||||
break
|
||||
done
|
||||
}
|
||||
|
||||
# Test if the release can be installed correctly.
|
||||
|
||||
if $source_upgrade; then
|
||||
key=sortix.hdd.id_rsa
|
||||
known_hosts=sortix.hdd.known_hosts
|
||||
fi
|
||||
|
||||
wait_ssh
|
||||
if $install; then
|
||||
do_ssh "sysinstall"
|
||||
elif $iso_upgrade; then
|
||||
do_ssh "sysupgrade"
|
||||
elif $source_upgrade; then
|
||||
xorriso -indev "$iso" -osirrox on -extract boot/src.tar.xz src.tar.xz
|
||||
do_ssh "rm -rf /src && tar -xJ -C /dev" < src.tar.xz
|
||||
rm -f src.tar.xz
|
||||
do_ssh "cd /dev/src && make PACKAGES= sysmerge"
|
||||
fi
|
||||
do_ssh "poweroff" || true
|
||||
|
||||
wait $vmpid
|
||||
unset vmpid
|
||||
rm pid
|
||||
|
||||
# Test if the installation boots correctly.
|
||||
|
||||
if $install || $iso_upgrade; then
|
||||
cp sortix.iso.known_hosts sortix.hdd.known_hosts
|
||||
cp id_rsa sortix.hdd.id_rsa
|
||||
cp id_rsa.pub sortix.hdd.id_rsa.pub
|
||||
fi
|
||||
key=sortix.hdd.id_rsa
|
||||
known_hosts=sortix.hdd.known_hosts
|
||||
|
||||
qemu &
|
||||
vmpid=$!
|
||||
echo $vmpid > pid
|
||||
|
||||
wait_ssh
|
||||
do_ssh "poweroff" || true
|
||||
|
||||
wait $vmpid
|
||||
unset vmpid
|
||||
rm pid
|
||||
|
||||
if [ -n "$output" ]; then
|
||||
cp sortix.hdd "$output"
|
||||
cp sortix.hdd.firmware "$output.firmware"
|
||||
cp sortix.hdd.known_hosts "$output.known_hosts"
|
||||
cp sortix.hdd.id_rsa "$output.id_rsa"
|
||||
cp sortix.hdd.id_rsa.pub "$output.id_rsa.pub"
|
||||
fi
|
Loading…
Add table
Reference in a new issue