end-to-end/lib/lib.sh

324 lines
8.9 KiB
Bash

#!/bin/bash
# Copyright 2024 The Forgejo Authors
# SPDX-License-Identifier: MIT
LIB_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if ${VERBOSE:-false} ; then
set -ex
PS4='${BASH_SOURCE[0]}:$LINENO: ${FUNCNAME[0]}: '
else
set -e
fi
set -o pipefail
export DEBIAN_FRONTEND=noninteractive
if test $(id -u) != 0 ; then
SUDO=sudo
fi
IP=$(hostname -I | cut -f1 -d' ')
#
# Forgejo releases for which a branch exists (7.0/forgejo etc.)
#
RELEASE_NUMBERS="7.0 8.0"
PREFIX===============
HOST_PORT=$IP:3000
export DIR=/tmp/forgejo-end-to-end
DIR_BINARIES=/srv/forgejo-binaries
export DOT_FORGEJO_CURL=$DIR/forgejo-curl
export DOT=$DOT_FORGEJO_CURL # for backward compatibility with forgejo-curl.sh 1.0.0
: ${FORGEJO_USER:=root}
: ${FORGEJO_PASSWORD:=admin1234}
RELEASE_NUMBERS_AND_DEV="$(for r in $RELEASE_NUMBERS ; do echo -n "$r $r-dev " ; done)"
ORGANIZATIONS=$(cat $LIB_DIR/ORGANIZATIONS)
function log_info() {
echo "$PREFIX $@"
}
function dependencies() {
if ! test -f /usr/local/bin/forgejo-curl.sh ; then
$SUDO curl --fail -sS https://code.forgejo.org/forgejo/forgejo-curl/raw/branch/main/forgejo-curl.sh -o /usr/local/bin/forgejo-curl.sh
$SUDO chmod +x /usr/local/bin/forgejo-curl.sh
fi
if ! which make curl daemon git-lfs jq sqlite3 > /dev/null ; then
$SUDO apt-get update -qq
$SUDO apt-get install -y -qq make curl daemon git-lfs jq sqlite3 gettext-base
fi
if ! test -f /usr/local/bin/mc || ! test -f /usr/local/bin/minio ; 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 ; 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
local forgejo=$DIR_BINARIES/forgejo-$dev-dev
if test -f $forgejo ; then
log_info $dev already exists
else
$LIB_DIR/build.sh $dev $DIR_BINARIES
log_info $dev built from sources
fi
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_BINARIES/forgejo-$version ; then
mkdir -p $DIR_BINARIES
for owner in $ORGANIZATIONS ; do
full_version=$(full_version $version $owner)
if test "$full_version" = "" ; then
continue
fi
if wget -O $DIR_BINARIES/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_BINARIES/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_BINARIES/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-end-to-end
}
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_BINARIES/forgejo-$version --config $work_path/app.ini --work-path $work_path
if ! retry grep --no-messages --quiet 'Starting server on' $work_path/log/forgejo.log ; then
grep '' $DIR/*.log
grep '' $work_path/log/*.log 2> /dev/null
return 1
fi
echo "$DIR_BINARIES/forgejo-$version --config $work_path/app.ini --work-path $work_path" '"$@"' > $DIR/forgejocli
chmod +x $DIR/forgejocli
create_user_and_login $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 >& /dev/null
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 <<EOF
metadata_dir = "$DIR/garage/meta"
data_dir = "$DIR/garage/data"
db_engine = "lmdb"
replication_mode = "none"
rpc_bind_addr = "127.0.0.1:3901"
rpc_public_addr = "127.0.0.1:3901"
rpc_secret = "$(openssl rand -hex 32)"
[s3_api]
s3_region = "us-east-1"
api_bind_addr = "127.0.0.1:9000"
root_domain = ".s3.garage.localhost"
[s3_web]
bind_addr = "127.0.0.1:3902"
root_domain = ".web.garage.localhost"
index = "index.html"
[k2v_api]
api_bind_addr = "127.0.0.1:3904"
[admin]
api_bind_addr = "127.0.0.1:3903"
admin_token = "$(openssl rand -base64 32)"
EOF
daemon --chdir=$DIR --unsafe \
--env="PATH=$PATH" \
--env=RUST_LOG=garage_api=debug \
--pidfile=$DIR/garage-pid --errlog=$DIR/garage-err.log --output=$DIR/garage-out.log -- /usr/local/bin/garage -c $DIR/garage/garage.toml server
retry garage -c $DIR/garage/garage.toml status
garage -c $DIR/garage/garage.toml layout assign -z dc1 -c 1 $(garage -c $DIR/garage/garage.toml status | tail -1 | grep -o '[0-9a-z]*' | head -1)
ver=$(garage -c $DIR/garage/garage.toml layout show | grep -oP '(?<=Current cluster layout version: )\d+')
garage -c $DIR/garage/garage.toml layout apply --version $((ver+1))
garage -c $DIR/garage/garage.toml key info test || garage -c $DIR/garage/garage.toml key import -n test 123456 12345678
garage -c $DIR/garage/garage.toml key allow --create-bucket test
retry mc alias set testS3 http://127.0.0.1:9000 123456 12345678
}
function start_s3() {
local s3_backend=$1
start_$s3_backend
}
function start() {
local version=$1
local s3_backend=${2:-minio}
start_s3 $s3_backend
start_forgejo $version
}
function reset_forgejo() {
local config=$1
local work_path=$DIR/forgejo-work-path
rm -fr $work_path
mkdir -p $work_path
IP=$IP WORK_PATH=$work_path envsubst < $config > $work_path/app.ini
}
function reset_minio() {
rm -fr $DIR/minio
}
function reset_garage() {
rm -fr $DIR/garage
}
function create_user_and_login() {
local version=$1
local email="$FORGEJO_USER@example.com"
if ! $DIR/forgejocli admin user list | grep --quiet "$email" ; then
$DIR/forgejocli admin user create --admin --username "$FORGEJO_USER" --password "$FORGEJO_PASSWORD" --email $email
fi
forgejo-curl.sh logout
local scopes='--scopes ["all"]'
if echo $version | grep --quiet 1.18 ; then
scopes=""
fi
forgejo-curl.sh --user "$FORGEJO_USER" --password "$FORGEJO_PASSWORD" $scopes login http://${HOST_PORT}
}
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 show_logs() {
(
cd $DIR
set +e
grep --text '' *.log
grep --text '' forgejo-work-path/log/*.log
grep --text '' *.out
)
}
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" &
local pid=$!
if ! VERBOSE=true $SELF $fun "$@" >& $DIR/$fun.out ; then
kill $pid
cat $DIR/$fun.out
echo Failure running $fun
return 1
fi
kill $pid
echo Success running $fun
}