apps/seafile/smoke-test.sh
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env bash
set -Eeuo pipefail
app_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
project="${COMPOSE_PROJECT_NAME:-smoke-seafile-${GITHUB_RUN_ID:-local}-${GITHUB_RUN_ATTEMPT:-1}-$$}"
secret="${project//[^A-Za-z0-9]/}"
backup_dir="$(mktemp -d)"
export SEAFILE_PORT=0
# The setup script rejects "localhost" as a hostname, so the smoke run uses a
# domain-shaped name and reaches the container through the published port.
export SEAFILE_SERVER_HOSTNAME=seafile.smoke.example
export SEAFILE_SERVER_PROTOCOL=http
export SEAFILE_ADMIN_EMAIL=smoke@example.com
export SEAFILE_ADMIN_PASSWORD="SmokeAdmin${secret}"
export SEAFILE_DB_ROOT_PASSWORD="SmokeRoot${secret}"
export SEAFILE_DB_USER=smoke_seafile
export SEAFILE_DB_PASSWORD="SmokeSeafile${secret}"
export SEAFILE_JWT_PRIVATE_KEY="SmokeJwtPrivateKey${secret}0123456789abcdef"
export SEAFILE_CACHE_PASSWORD="SmokeCache${secret}"
export SEAFILE_DATA_VOLUME="${project}-data"
export SEAFILE_DB_VOLUME="${project}-database"
export COMPOSE_PROJECT_NAME="$project"
export SEAFILE_BACKUP_DIR="$backup_dir"
export FOSSARY_ENV_FILE=/dev/null
compose=(docker compose --project-name "$project" --env-file "$app_dir/.env.example" --file "$app_dir/compose.yaml")
cleanup() {
status=$?
trap - EXIT INT TERM
set +e
"${compose[@]}" ps --all
"${compose[@]}" logs --no-color --timestamps --tail=300
"${compose[@]}" down --volumes --remove-orphans --timeout 120
rm -rf "$backup_dir"
exit "$status"
}
# Every failed check names itself: `grep --quiet` and `test` say nothing, and all
# the CI log would keep of them is an exit code.
trap 'echo "Check failed on line $LINENO: $BASH_COMMAND" >&2' ERR
trap cleanup EXIT
trap 'exit 130' INT TERM
"${compose[@]}" config --quiet
"${compose[@]}" pull
# The first start creates three databases and runs the Seahub setup, which takes
# minutes rather than seconds.
"${compose[@]}" up --detach --wait --wait-timeout 900
published="$("${compose[@]}" port seafile 80)"
case "$published" in
127.0.0.1:[0-9]*) ;;
*) echo "Unexpected published address: $published" >&2; exit 1 ;;
esac
# The login page proves Seahub, the database, and the cache all answer.
curl --fail --silent --show-error \
--retry 20 --retry-all-errors --retry-delay 5 \
--connect-timeout 3 --max-time 60 \
"http://${published}/accounts/login/" | grep --quiet "Seafile"
# The file server is a separate Go process behind the same nginx; a 400 without
# a token is the expected answer and proves it is running.
status="$(curl --silent --output /dev/null --write-out '%{http_code}' \
--connect-timeout 3 --max-time 30 "http://${published}/seafhttp/")"
case "$status" in
400|401|403|404) ;;
*) echo "Unexpected /seafhttp/ status: $status" >&2; exit 1 ;;
esac
# Restore must preserve both the file block volume and the MariaDB databases.
container_id="$("${compose[@]}" ps --quiet seafile)"
docker exec "$container_id" touch /shared/fossary-restore-check
"${compose[@]}" exec -T db mariadb --user=root --password="${SEAFILE_DB_ROOT_PASSWORD}" \
--execute='CREATE TABLE ccnet_db.fossary_restore_check (id integer);'
bash "$app_dir/backup.sh"
archives=("$backup_dir"/seafile-*.tar)
test -f "${archives[0]}"
docker exec "$container_id" rm /shared/fossary-restore-check
"${compose[@]}" exec -T db mariadb --user=root --password="${SEAFILE_DB_ROOT_PASSWORD}" \
--execute='DROP TABLE ccnet_db.fossary_restore_check;'
bash "$app_dir/restore.sh" "${archives[0]}"
container_id="$("${compose[@]}" ps --quiet seafile)"
docker exec "$container_id" test -f /shared/fossary-restore-check
"${compose[@]}" exec -T db mariadb --user=root --password="${SEAFILE_DB_ROOT_PASSWORD}" \
--batch --skip-column-names --execute="SHOW TABLES FROM ccnet_db LIKE 'fossary_restore_check';" | \
grep --fixed-strings --line-regexp --quiet fossary_restore_check
echo "Seafile smoke test passed on $published"