From 5c5d5c2aff382ad67398c521323f5139e5da80fc Mon Sep 17 00:00:00 2001 From: downtownallday Date: Sun, 26 Jun 2022 22:16:04 -0400 Subject: [PATCH] Add a major upgrade test - bionic to jammy --- tests/bin/restore_backup.sh | 110 +++++++++++++++++++++ tests/system-setup/from-backup.sh | 54 ++++++++++ tests/vagrant/majorupgrade/Vagrantfile | 46 +++++++++ tests/vagrant/majorupgrade/majorupgrade.sh | 39 ++++++++ 4 files changed, 249 insertions(+) create mode 100755 tests/bin/restore_backup.sh create mode 100755 tests/system-setup/from-backup.sh create mode 100644 tests/vagrant/majorupgrade/Vagrantfile create mode 100755 tests/vagrant/majorupgrade/majorupgrade.sh diff --git a/tests/bin/restore_backup.sh b/tests/bin/restore_backup.sh new file mode 100755 index 00000000..e60d40a6 --- /dev/null +++ b/tests/bin/restore_backup.sh @@ -0,0 +1,110 @@ +#!/bin/bash + +usage() { + echo "" + echo "Restore a Mail-In-A-Box user-data directory from a LOCAL backup" + echo "" + echo "usage: $0 [path-to-restore-to]" + echo " storage-user:" + echo " the user account that owns the miab files. eg 'user-data'" + echo " path-to-encrypted-dir:" + echo " a directory containing a copy of duplicity files to restore. These were in" + echo " /home/user-data/backup/encrypted on the system." + echo "" + echo " path-secret-key.txt:" + echo " a copy of the encryption key file 'secret-key.txt' that was kept in" + echo " /home/user-data/backup/secret-key.txt." + echo "" + echo " path-to-restore-to:" + echo " the directory where the restored files are placed. the default location is" + echo " /home/. FILES IN THIS DIRECTORY WILL BE REPLACED. IF THIS IS A MOUNT POINT ENTER A SUBDIRECTORY OF THE MOUNT POINT THEN MANUALLY MOVE THE FILES BACK ONE LEVEL BECAUSE DUPLICITY AUTOMATICALLY UNMOUNTS IT!" + echo "" + echo "If you're using encryption-at-rest, make sure it's mounted before restoring" + echo "eg: run ehdd/mount.sh" + echo "" + exit 1 +} + +if [ $# -lt 3 ]; then + usage +fi + +if [ $EUID -ne 0 ]; then + echo "Must be run as root" 1>&2 + exit 1 +fi + +storage_user="$1" +backup_files_dir="$(realpath "$2")" +secret_key_file="$3" +restore_to_dir="$(realpath "${4:-/home/$storage_user}")" + + +PASSPHRASE="$(cat "$secret_key_file")" +if [ $? -ne 0 ]; then + echo "unable to access $secret_key_file" 1>&2 + exit 1 +fi +export PASSPHRASE + +if [ ! -d "$backup_files_dir" ]; then + echo "Does not exist or not a directory: $backup_files_dir" 1>&2 + exit 1 +fi + +echo "Shutting down services" +ehdd/shutdown.sh || exit 1 + +if [ ! -x /usr/bin/duplicity ]; then + apt-get install -y -qq duplicity +fi + +if ! id openldap 2>/dev/null; then + # ensure there's an openldap user or duplicity assigns odd permissions + useradd --shell /bin/false -r -M -U -c "OpenLDAP Server Account" -d /var/lib/ldap openldap +fi + +if ! id "$storage_user" 2>/dev/null; then + # ensure the storage user exists + useradd -m $storage_user + chmod o+x /home/$storage_user +fi + +echo "Restoring with duplicity" +opts="" +if [ -e "$restore_to_dir" ]; then + opts="--force" +fi +duplicity restore $opts "file://$backup_files_dir" "$restore_to_dir" 2>&1 | ( + code=0 + while read line; do + echo "$line" + case "$line" in + Error\ * ) + code=1 + ;; + esac + done; exit $code) + +codes="${PIPESTATUS[0]}${PIPESTATUS[1]}" +[ "$codes" -ne "00" ] && exit 1 + + +# +# check that filesystem uid's/gid's mapped to actual users/groups +# +files_with_nouser="$(find "$restore_to_dir" -nouser -nogroup)" +if [ "$files_with_nouser" != "" ]; then + echo "" + echo "WARNING: some restored file/directory ownerships are unmatched" + echo "They are:" + echo "$files_with_nouser" +fi + + +echo "" +echo "Restore successful" +echo "" + +exit 0 + diff --git a/tests/system-setup/from-backup.sh b/tests/system-setup/from-backup.sh new file mode 100755 index 00000000..837e7b22 --- /dev/null +++ b/tests/system-setup/from-backup.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# +# setup system using backup data +# + +# ensure working directory +if [ ! -d "tests/system-setup" ]; then + echo "This script must be run from the MiaB root directory" + exit 1 +fi + +# load helper scripts +. "tests/lib/all.sh" "tests/lib" || die "Could not load lib scripts" +. "tests/system-setup/setup-defaults.sh" || die "Could not load setup-defaults" +. "tests/system-setup/setup-funcs.sh" || die "Could not load setup-funcs" + +# ensure running as root +if [ "$EUID" != "0" ]; then + die "This script must be run as root (sudo)" +fi + + +init() { + H1 "INIT" + init_test_system + init_miab_testing "$@" || die "Initialization failed" +} + + +# initialize test system +init "$@" + + +if [ $# -lt 3 ]; then + die "usage: $0 storage-user /path/to/encrypted /path/to/secret_key /path/to/restore-dir" +fi +storage_user="$1" # eg. "user-data" +duplicity_files="$2" # /path/to/encrypted +secret_key="$3" # /path/to/secret_key.txt +restore_to="$4" # eg. /home/user-data +shift; shift; shift; shift; + +tests/bin/restore_backup.sh \ + "$storage_user" \ + "$duplicity_files" \ + "$secret_key" \ + "$restore_to" \ + || die "Restore failed" + + +# run setup +miab_ldap_install "$@" + diff --git a/tests/vagrant/majorupgrade/Vagrantfile b/tests/vagrant/majorupgrade/Vagrantfile new file mode 100644 index 00000000..bee9319e --- /dev/null +++ b/tests/vagrant/majorupgrade/Vagrantfile @@ -0,0 +1,46 @@ +load '../funcs.rb' + +# major upgrade Ubuntu 18.04 (bionic) -> Ubuntu 22.04 (jammy) + +Vagrant.configure("2") do |config| + + config.vm.synced_folder "../../..", "/mailinabox", id: "mailinabox", automount: false + config.vm.network "public_network", bridge: "#$default_network_interface" + + + config.vm.define "major-upgrade-oldvm" do |m1| + use_preloaded_box m1, "ubuntu/bionic64", ".." + m1.vm.provision :shell, :inline => <<-SH +# setup vanilla system, populated with some data +cd /mailinabox +export PRIMARY_HOSTNAME=majorupgrade.local +export FEATURE_MUNIN=false +source tests/system-setup/setup-defaults.sh +tests/system-setup/vanilla.sh \ + --checkout-repo="$MIABLDAP_GIT" \ + --checkout-treeish="$FINAL_RELEASE_TAG_BIONIC64" \ + --checkout-targetdir="$HOME/miabldap-bionic" \ + --populate=basic \ + --populate=totpuser \ + --capture-state=/tmp/state/oldvm \ + || exit 1 +SH + end + + config.vm.define "major-upgrade-newvm" do |m2| + use_preloaded_box m2, "ubuntu/jammy64", ".." + m2.vm.provision :shell, :inline => <<-SH +cd /mailinabox +export PRIMARY_HOSTNAME=majorupgrade.local +export FEATURE_MUNIN=false +tests/system-setup/from-backup.sh \ + "#{ENV['storage_user']}" \ + "#{ENV['duplicity_files']}" \ + "#{ENV['secret_key']}" \ + "#{ENV['restore_to']}" \ + --capture-state=/tmp/state/newvm \ + || exit 1 +SH + end + +end diff --git a/tests/vagrant/majorupgrade/majorupgrade.sh b/tests/vagrant/majorupgrade/majorupgrade.sh new file mode 100755 index 00000000..fbcbdf8b --- /dev/null +++ b/tests/vagrant/majorupgrade/majorupgrade.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# run from this script's directory +cd $(dirname "$0") + +vagrant destroy -f + +artifact_dir_local="$(dirname "$0")/../../out/majorupgrade" +artifact_dir_vm="/mailinabox/tests/out/majorupgrade" +oldvm="major-upgrade-oldvm" +newvm="major-upgrade-newvm" + +# bring up oldvm, install, populate, and backup +# installed source code is in $HOME/miabldap-bionic (see Vagrantfile). $HOME is /root +vagrant up $oldvm || exit 1 +vagrant ssh $oldvm -- "sudo -H bash -c 'cd \$HOME/miabldap-bionic; management/backup.py' && echo 'backup successful'" || exit 2 + +# copy artifacts from oldvm to host +rm -rf "$artifact_dir_local" +mkdir -p "$artifact_dir_local" +vagrant ssh $oldvm -- "cd \"$artifact_dir_vm\" || exit 1; sudo -H cp -R /tmp/state/oldvm state || exit 2; sudo -H cp -R /home/user-data/backup backup || exit 3" || exit $? + +# destroy oldvm - bring up newvm +vagrant destroy $oldvm -f + +export storage_user="user-data" +export duplicity_files="$artifact_dir_vm/backup/encrypted" +export secret_key="$artifact_dir_vm/backup/secret_key.txt" +export restore_to="/home/user-data" + +vagrant up $newvm || exit 1 + +# compare states +vagrant ssh $newvm -- "cd /mailinabox; sudo -H bash -c 'source tests/lib/all.sh; installed_state_compare $artifact_dir_vm/state /tmp/state/newvm'" || exit 2 + +# run tests +vagrant ssh $newvm -- "cd /mailinabox; sudo -H tests/runner.sh upgrade-basic upgrade-totpuser default" || exit 3 + +echo 'Success'