88 lines
3.2 KiB
Bash
Executable File
88 lines
3.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
WORK=$(mktemp -d)
|
|
trap 'rm -rf "$WORK"' EXIT
|
|
|
|
fail() {
|
|
printf 'Purge fixture failed: %s\n' "$1" >&2
|
|
exit 1
|
|
}
|
|
|
|
sed '$d' "$ROOT/deploy/purge.sh" > "$WORK/purge-functions.sh"
|
|
# shellcheck disable=SC1090,SC1091
|
|
source "$WORK/purge-functions.sh"
|
|
|
|
install() {
|
|
local -a arguments=()
|
|
while [ "$#" -gt 0 ]; do
|
|
case "$1" in
|
|
-o|-g) shift 2 ;;
|
|
*) arguments+=("$1"); shift ;;
|
|
esac
|
|
done
|
|
command install "${arguments[@]}"
|
|
}
|
|
|
|
APP_ROOT="$WORK/opt/kaidi"
|
|
BAOTA_ROOT="$WORK/www/kaidi"
|
|
CONFIG_ROOT="$WORK/etc/kaidi"
|
|
STATE_ROOT="$WORK/var/lib/kaidi"
|
|
UPDATE_STATE_ROOT="$WORK/var/lib/kaidi-update"
|
|
LOG_ROOT="$WORK/var/log/kaidi"
|
|
FIRST_LOGIN_FILE="$WORK/root/kaidi-first-login.txt"
|
|
# shellcheck disable=SC2034 # Referenced by the sourced purge helper.
|
|
BACKUP_ROOT="$WORK/recovery"
|
|
BACKUP_ARCHIVE=
|
|
|
|
mkdir -p \
|
|
"$APP_ROOT" \
|
|
"$BAOTA_ROOT" \
|
|
"$CONFIG_ROOT" \
|
|
"$STATE_ROOT/files" \
|
|
"$UPDATE_STATE_ROOT/backups" \
|
|
"$UPDATE_STATE_ROOT/failed" \
|
|
"$UPDATE_STATE_ROOT/transactions" \
|
|
"$LOG_ROOT" \
|
|
"$(dirname "$FIRST_LOGIN_FILE")" \
|
|
"$WORK/external-mysql" \
|
|
"$WORK/reverse-proxy"
|
|
printf 'DB_PASSWORD="secret"\n' > "$CONFIG_ROOT/kaidi.env"
|
|
printf 'document\n' > "$STATE_ROOT/files/document.txt"
|
|
printf 'dump\n' > "$UPDATE_STATE_ROOT/backups/mysql.sql"
|
|
printf 'setup code\n' > "$FIRST_LOGIN_FILE"
|
|
printf 'database sentinel\n' > "$WORK/external-mysql/keep"
|
|
printf 'proxy sentinel\n' > "$WORK/reverse-proxy/keep"
|
|
|
|
create_recovery_backup
|
|
[ -s "$BACKUP_ARCHIVE" ] || fail 'root-only recovery archive was not created'
|
|
[ "$(stat -c '%a' "$BACKUP_ARCHIVE" 2>/dev/null || stat -f '%Lp' "$BACKUP_ARCHIVE")" = 600 ] \
|
|
|| fail 'recovery archive mode is not 0600'
|
|
archive_list=$(tar -tzf "$BACKUP_ARCHIVE")
|
|
grep -Fq "${CONFIG_ROOT#/}/kaidi.env" <<< "$archive_list" \
|
|
|| fail 'configuration was omitted from the recovery archive'
|
|
grep -Fq "${STATE_ROOT#/}/files/document.txt" <<< "$archive_list" \
|
|
|| fail 'file storage was omitted from the recovery archive'
|
|
grep -Fq "${UPDATE_STATE_ROOT#/}/backups/mysql.sql" <<< "$archive_list" \
|
|
|| fail 'database backup was omitted from the recovery archive'
|
|
|
|
remove_managed_paths
|
|
for path in "$APP_ROOT" "$BAOTA_ROOT" "$CONFIG_ROOT" "$STATE_ROOT" "$UPDATE_STATE_ROOT" "$LOG_ROOT"; do
|
|
[ ! -e "$path" ] || fail "managed path was not removed: $path"
|
|
done
|
|
[ ! -e "$FIRST_LOGIN_FILE" ] || fail 'first-login file was not removed'
|
|
[ -f "$WORK/external-mysql/keep" ] || fail 'external database state was removed'
|
|
[ -f "$WORK/reverse-proxy/keep" ] || fail 'reverse-proxy state was removed'
|
|
[ -s "$BACKUP_ARCHIVE" ] || fail 'recovery archive was removed with the installation'
|
|
|
|
[ "$(tail -n 1 "$ROOT/deploy/purge.sh")" = 'main "$@"' ] \
|
|
|| fail 'purge actions can execute before a complete curl stream is parsed'
|
|
# shellcheck disable=SC2016 # Match the literal guard in the purge source.
|
|
grep -Fq 'KAIDI_PURGE_CONFIRM=$REQUIRED_CONFIRMATION' "$ROOT/deploy/purge.sh" \
|
|
|| fail 'destructive removal no longer requires explicit confirmation'
|
|
grep -Fq 'External MySQL data and reverse-proxy configuration will not be modified' "$ROOT/deploy/purge.sh" \
|
|
|| fail 'purge boundary is no longer explicit'
|
|
|
|
printf 'Local purge and recovery fixture passed\n'
|