#!/bin/bash # SPDX-License-Identifier: MIT # # Debug loop from the source tree: # # ./forgejo/upgrades/test-upgrade.sh dependencies # ./forgejo/upgrades/test-upgrade.sh build_all # VERBOSE=true ./forgejo/upgrades/test-upgrade.sh test_downgrade_1.20.2_fails # # Everything happens in /tmp/forgejo-upgrades # # # Forgejo releases for which a branch exists (7.0/forgejo etc.) # RELEASE_NUMBERS="7.0" PREFIX=============== HOST_PORT=0.0.0.0:3000 STORAGE_PATHS="attachments avatars lfs packages repo-archive repo-avatars" STORAGE_FUN="attachments avatars lfs packages repo_archive repo_avatars" DIR=/tmp/forgejo-upgrades if ${VERBOSE:-false} ; then set -ex PS4='${BASH_SOURCE[0]}:$LINENO: ${FUNCNAME[0]}: ' else set -e fi SELF_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" : ${FORGEJO_USER:=root} : ${FORGEJO_REPO:=fixture} : ${FORGEJO_PASSWORD:=admin1234} RELEASE_NUMBERS_AND_DEV="$(for r in $RELEASE_NUMBERS ; do echo -n $r $r-dev ; done)" source $SELF_DIR/fixtures.sh function maybe_sudo() { if test $(id -u) != 0 ; then SUDO=sudo fi } function log_info() { echo "$PREFIX $@" } function dependencies() { maybe_sudo if ! which curl daemon jq git-lfs > /dev/null ; then export DEBIAN_FRONTEND=noninteractive $SUDO apt-get update -qq $SUDO apt-get install -y -qq curl daemon git-lfs jq sqlite3 gettext-base fi if ! test -f /usr/local/bin/mc || ! test -f /usr/local/bin/minio > /dev/null ; then $SUDO curl --fail -sS https://dl.min.io/client/mc/release/linux-amd64/mc -o /usr/local/bin/mc $SUDO curl --fail -sS https://dl.min.io/server/minio/release/linux-amd64/minio -o /usr/local/bin/minio fi if ! test -x /usr/local/bin/mc || ! test -x /usr/local/bin/minio > /dev/null ; then $SUDO chmod +x /usr/local/bin/mc $SUDO chmod +x /usr/local/bin/minio fi if ! test -f /usr/local/bin/garage > /dev/null ; then $SUDO curl --fail -sS https://garagehq.deuxfleurs.fr/_releases/v0.8.2/x86_64-unknown-linux-musl/garage -o /usr/local/bin/garage fi if ! test -x /usr/local/bin/garage > /dev/null ; then $SUDO chmod +x /usr/local/bin/garage fi } function build_all() { for dev in $RELEASE_NUMBERS ; do log_info $dev-dev $SELF_DIR/../build.sh $dev $DIR done } function retry() { rm -f $DIR/wait-for.out success=false for delay in 1 1 5 5 15 ; do if "$@" >> $DIR/wait-for.out 2>&1 ; then success=true break fi cat $DIR/wait-for.out echo waiting $delay sleep $delay done if test $success = false ; then cat $DIR/wait-for.out return 1 fi } function full_version() { local version=$1 local owner=$2 if [[ $version =~ ^[0-9]+\.[0-9]+$ ]] ; then full_version=$(curl -sS https://codeberg.org/api/v1/repos/$owner/forgejo/releases | jq -r '.[] | .tag_name | select(startswith("v'$version'"))' | sort -r | head -1) echo ${full_version#v} else echo $version fi } function download() { local version=$1 if ! test -f $DIR/forgejo-$version ; then mkdir -p $DIR for owner in forgejo forgejo-experimental forgejo-integration ; do full_version=$(full_version $version $owner) if test "$full_version" = "" ; then continue fi if wget -O $DIR/forgejo-$version --quiet https://codeberg.org/$owner/forgejo/releases/download/v$full_version/forgejo-$full_version-linux-amd64 ; then break fi done if test -s $DIR/forgejo-$version ; then if test "$version" != "$full_version" ; then log_info "downloaded $full_version for $version" fi else echo unable to download Forgejo $version return 1 fi chmod +x $DIR/forgejo-$version fi } function cleanup_logs() { local work_path=$DIR/forgejo-work-path rm -f $DIR/*.log rm -f $work_path/log/*.log } function clobber() { rm -fr /tmp/forgejo-upgrades } function start_forgejo() { local version=$1 download $version local work_path=$DIR/forgejo-work-path daemon --chdir=$DIR --unsafe --env="TERM=$TERM" --env="HOME=$HOME" --env="PATH=$PATH" --pidfile=$DIR/forgejo-pid --errlog=$DIR/forgejo-err.log --output=$DIR/forgejo-out.log -- $DIR/forgejo-$version --config $work_path/app.ini --work-path $work_path if ! retry grep 'Starting server on' $work_path/log/forgejo.log ; then grep '' $DIR/*.log grep '' $work_path/log/*.log 2> /dev/null return 1 fi create_user $version } function start_minio() { mkdir -p $DIR/minio daemon --chdir=$DIR --unsafe \ --env="PATH=$PATH" \ --env=MINIO_ROOT_USER=123456 \ --env=MINIO_ROOT_PASSWORD=12345678 \ --env=MINIO_VOLUMES=$DIR/minio \ --pidfile=$DIR/minio-pid --errlog=$DIR/minio-err.log --output=$DIR/minio-out.log -- /usr/local/bin/minio server retry mc alias set testS3 http://127.0.0.1:9000 123456 12345678 } function start_garage() { mkdir -p $DIR/garage/{data,meta} cat > $DIR/garage/garage.toml < $work_path/forgejo-token ( echo -n 'Authorization: token ' ; cat $work_path/forgejo-token ) > $work_path/forgejo-header ( echo "#!/bin/sh" ; echo 'curl -f -sS -H "Content-Type: application/json" -H @'$work_path/forgejo-header' "$@"' ) > $work_path/forgejo-api && chmod +x $work_path/forgejo-api $work_path/forgejo-api http://${HOST_PORT}/api/v1/version # # forgejo-client is to use with web endpoints # # # login and obtain a CSRF, all stored in the cookie file # ( echo "#!/bin/sh" ; echo 'curl --cookie-jar '$DIR/cookies' --cookie '$DIR/cookies' -f -sS "$@"' ) > $work_path/forgejo-client-update-cookies && chmod +x $work_path/forgejo-client-update-cookies $work_path/forgejo-client-update-cookies http://${HOST_PORT}/user/login -o /dev/null $work_path/forgejo-client-update-cookies --verbose -X POST --data user_name=${FORGEJO_USER} --data password=${FORGEJO_PASSWORD} http://${HOST_PORT}/user/login >& $DIR/login.html $work_path/forgejo-client-update-cookies http://${HOST_PORT}/user/login -o /dev/null local csrf=$(sed -n -e '/csrf/s/.*csrf\t//p' $DIR/cookies) # # use the cookie file but do not modify it # ( echo "#!/bin/sh" ; echo 'curl --cookie '$DIR/cookies' -H "X-Csrf-Token: '$csrf'" -f -sS "$@"' ) > $work_path/forgejo-client && chmod +x $work_path/forgejo-client } function stop_daemon() { local daemon=$1 if test -f $DIR/$daemon-pid ; then local pid=$(cat $DIR/$daemon-pid) kill -TERM $pid pidwait $pid || true for delay in 1 1 2 2 5 5 ; do if ! test -f $DIR/$daemon-pid ; then break fi sleep $delay done ! test -f $DIR/$daemon-pid fi } function stop() { stop_daemon forgejo stop_daemon minio stop_daemon garage cleanup_logs } function reset_forgejo() { local config=$1 local work_path=$DIR/forgejo-work-path rm -fr $work_path mkdir -p $work_path WORK_PATH=$work_path envsubst < $SELF_DIR/$config-app.ini > $work_path/app.ini } function reset_minio() { rm -fr $DIR/minio } function reset_garage() { rm -fr $DIR/garage } function reset() { local config=$1 reset_forgejo $config reset_minio reset_garage } function verify_storage() { local work_path=$DIR/forgejo-work-path for path in ${STORAGE_PATHS} ; do test -d $work_path/data/$path done } function cleanup_storage() { local work_path=$DIR/forgejo-work-path for path in ${STORAGE_PATHS} ; do rm -fr $work_path/data/$path done } function test_storage_stable_s3() { local work_path=$DIR/forgejo-work-path local s3_backend=${1:-minio} log_info "See also https://codeberg.org/forgejo/forgejo/issues/1338" for version in 1.18 1.19 1.20.2-0 1.20.3-0 1.20 1.21 $RELEASE_NUMBERS_AND_DEV ; do log_info "Forgejo $version & $s3_backend" stop reset stable-s3 start $version $s3_backend fixture_create for fun in ${STORAGE_FUN} ; do fixture_${fun}_assert_s3 done done } function test_successful_upgrades() { for config in default specific ; do log_info "using $config app.ini" reset $config for version in 1.18 1.19 1.20.2-0 1.20.3-0 1.20 1.21 $RELEASE_NUMBERS_AND_DEV ; do log_info "run $version" cleanup_storage start $version verify_storage stop done done } function test_forgejo_database_version() { local expected_version=$1 local work_path=$DIR/forgejo-work-path actual_version=$(sqlite3 $work_path/forgejo.db "select version from forgejo_version") test "$expected_version" = "$actual_version" } function run() { local fun=$1 shift echo Start running $fun mkdir -p $DIR > $DIR/$fun.out tail --follow $DIR/$fun.out | sed --unbuffered -n -e "/^$PREFIX/s/^$PREFIX //p" & pid=$! if ! VERBOSE=true ${BASH_SOURCE[0]} $fun "$@" >& $DIR/$fun.out ; then kill $pid cat $DIR/$fun.out echo Failure running $fun return 1 fi kill $pid echo Success running $fun } source $SELF_DIR/test-upgrade-1.20-storage.sh source $SELF_DIR/test-upgrade-forgejo-database-v3.sh function test_upgrades() { run stop run dependencies run build_all run test_successful_upgrades run test_storage_stable_s3 minio run test_storage_stable_s3 garage test_upgrade_1_20_storage run test_forgejo_database_v3_upgrades } "$@"