#!/bin/bash

set -e -o pipefail


### Functions

fatal_msg () {
    printf '💀💀💀 error: %s 💀💀💀\n' "$1" 1>&2
}

usage () {
    cat <<'EOF' 1>&2
Test that ch-image can upgrade storage directories generated by old versions,
i.e., unpack each old storage directory from a tarball, then try to upgrade it
and run the test suite.

Usage:

  $ old-storage.sh SCOPE WORKDIR TAR1 [TAR2 ...]

WORKDIR is where ch-image storage are unpacked. It must be empty and have
enough space for one storage directory.

TARn are old storage directories arechived as tarballs. These must have
certain properties:

  1. Named storage-$VERSION.$ARCH.tar.gz, e.g. “storage-0.27.x86_64.tar.gz”.
     (Note: $ARCH is not currently validated but may be in the future.)

  2. Is a tarbomb, e.g.:

       $ tar tf storage-0.26.x86_64.tar.gz | head -3
       ./
       ./dlcache/
       ./dlcache/alpine:3.9.fat.json

  3. The result of:

       $ rm -Rf $(ch-image storage-path) && ch-test -b ch-image build

     or equivalent, though mostly rather than fully successful tests are fine.

     Note: Best practice is to generate the tarball at the time of release,
     because old test suites often don’t pass due to changing source images.
EOF
}

INFO () {
    printf '📣 %s\n' "$1"
}


### Parse arguments & setup

if [[ $1 = --help || $1 = -? ]]; then
    usage
    exit 0
fi
if [[ $# -lt 3 ]]; then
    usage
    exit 1
fi
scope=$1; shift
workdir=$1; shift

trap 'fatal_msg "command failed on line $LINENO"' ERR
PATH=$(cd "$(dirname "$0")" && pwd)/../bin:$PATH
export PATH


### Main loop

INFO "workdir: $workdir"
for oldtar in "$@"; do
    base=$(basename "$oldtar")
    base=${base%.*}  # rm .gz
    base=${base%.*}  # rm .tar
    base=${base%.*}  # rm architecture
    storage=${workdir}/${base}

    INFO "unpacking: $oldtar -> $storage"
    [[ -d $workdir ]]
    [[ ! -d $storage ]]
    mkdir "$storage"
    tar xf "$oldtar" -C "$storage"
    [[ -d $storage ]]
    export CH_IMAGE_STORAGE=$storage
    INFO "unpacked: $(du -sh "$storage" | cut -f1) bytes in $(du --inodes -sh "$storage" | cut -f1) inodes"

    INFO "upgrading"
    ch-image list

    INFO "testing"
    ch-test -b ch-image --pedantic=no -s "$scope" all

    INFO "deleting: $storage"
    rm -Rf --one-file-system "$storage"
    [[ ! -d $storage ]]

done
