Files
appfactory-tools/scripts/restore-appfactory.sh
T

169 lines
4.7 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
APPFACTORY_ROOT="/opt/appfactory"
BACKUP_FILE="${1:-}"
TARGET_USER="${2:-${SUDO_USER:-$USER}}"
fail() {
echo "[restore][FAIL] $*" >&2
exit 1
}
ok() {
echo "[restore][OK] $*"
}
log() {
echo "[restore] $*"
}
usage() {
cat <<USAGE
Usage:
sudo ./restore-appfactory.sh /path/to/appfactory-backup-YYYYMMDD-HHMMSS.tar.gz [target_user]
Example:
sudo ./restore-appfactory.sh ./appfactory-backup-20260608-095020.tar.gz karel
USAGE
}
if [ -z "$BACKUP_FILE" ]; then
usage
fail "Backup file argument is required"
fi
if [ ! -f "$BACKUP_FILE" ]; then
fail "Backup file not found: $BACKUP_FILE"
fi
if [ "$(id -u)" -ne 0 ]; then
fail "Run as root via sudo"
fi
if ! id "$TARGET_USER" >/dev/null 2>&1; then
fail "Target user does not exist: $TARGET_USER"
fi
command -v tar >/dev/null 2>&1 || fail "tar missing"
command -v docker >/dev/null 2>&1 || fail "docker missing"
APPFACTORY_UID="$(id -u "$TARGET_USER")"
APPFACTORY_GID="$(id -g "$TARGET_USER")"
[ -S /var/run/docker.sock ] || fail "Docker socket missing: /var/run/docker.sock"
APPFACTORY_DOCKER_GID="$(stat -c '%g' /var/run/docker.sock)"
log "Backup: $BACKUP_FILE"
log "Target user: $TARGET_USER"
log "APPFACTORY_UID=$APPFACTORY_UID"
log "APPFACTORY_GID=$APPFACTORY_GID"
log "APPFACTORY_DOCKER_GID=$APPFACTORY_DOCKER_GID"
log "Stopping existing AppFactory containers if present"
mapfile -t APPFACTORY_CONTAINERS < <(
docker ps -a --format '{{.Names}}' \
| grep -E '^(appfactory-|.*-service$|test-|microsoft-365-service)' \
|| true
)
if [ "${#APPFACTORY_CONTAINERS[@]}" -eq 0 ]; then
ok "No existing AppFactory containers found"
else
for container in "${APPFACTORY_CONTAINERS[@]}"; do
[ -n "$container" ] || continue
docker rm -f "$container" >/dev/null 2>&1 || true
ok "Removed container: $container"
done
fi
log "Removing existing AppFactory root"
rm -rf "$APPFACTORY_ROOT"
log "Recreating AppFactory root"
mkdir -p "$APPFACTORY_ROOT"
log "Extracting backup"
cd /
tar -xzf "$BACKUP_FILE"
[ -d "$APPFACTORY_ROOT" ] || fail "Backup did not create $APPFACTORY_ROOT"
log "Ensuring required directories"
mkdir -p \
"$APPFACTORY_ROOT/apps" \
"$APPFACTORY_ROOT/backups" \
"$APPFACTORY_ROOT/config" \
"$APPFACTORY_ROOT/data" \
"$APPFACTORY_ROOT/deploy" \
"$APPFACTORY_ROOT/gateway" \
"$APPFACTORY_ROOT/services" \
"$APPFACTORY_ROOT/templates" \
"$APPFACTORY_ROOT/tools" \
"$APPFACTORY_ROOT/workspace"
ENV_FILE="$APPFACTORY_ROOT/config/appfactory.env"
[ -f "$ENV_FILE" ] || fail "Missing env file after restore: $ENV_FILE"
log "Updating runtime ids in appfactory.env"
set_env_value() {
local key="$1"
local value="$2"
if grep -q "^${key}=" "$ENV_FILE"; then
sed -i "s|^${key}=.*|${key}=${value}|" "$ENV_FILE"
else
echo "${key}=${value}" >> "$ENV_FILE"
fi
}
set_env_value "APPFACTORY_UID" "$APPFACTORY_UID"
set_env_value "APPFACTORY_GID" "$APPFACTORY_GID"
set_env_value "APPFACTORY_DOCKER_GID" "$APPFACTORY_DOCKER_GID"
grep -q '^APPFACTORY_ENABLE_HTTPS=' "$ENV_FILE" || echo 'APPFACTORY_ENABLE_HTTPS=false' >> "$ENV_FILE"
grep -q '^APPFACTORY_DOMAIN=' "$ENV_FILE" || echo 'APPFACTORY_DOMAIN=' >> "$ENV_FILE"
grep -q '^APPFACTORY_PORTAL_DOMAIN=' "$ENV_FILE" || echo 'APPFACTORY_PORTAL_DOMAIN=' >> "$ENV_FILE"
grep -q '^APPFACTORY_GITEA_DOMAIN=' "$ENV_FILE" || echo 'APPFACTORY_GITEA_DOMAIN=' >> "$ENV_FILE"
grep -q '^APPFACTORY_REGISTRY_DOMAIN=' "$ENV_FILE" || echo 'APPFACTORY_REGISTRY_DOMAIN=' >> "$ENV_FILE"
grep -q '^GOOGLE_CLIENT_ID=' "$ENV_FILE" || echo 'GOOGLE_CLIENT_ID=' >> "$ENV_FILE"
grep -q '^GOOGLE_CLIENT_SECRET=' "$ENV_FILE" || echo 'GOOGLE_CLIENT_SECRET=' >> "$ENV_FILE"
grep -q '^GOOGLE_REDIRECT_URI=' "$ENV_FILE" || echo 'GOOGLE_REDIRECT_URI=' >> "$ENV_FILE"
log "Fixing ownership"
chown -R "$APPFACTORY_UID:$APPFACTORY_GID" "$APPFACTORY_ROOT"
log "Fixing script permissions"
find "$APPFACTORY_ROOT/workspace/appfactory-tools" -type f -name '*.sh' -exec chmod +x {} \; 2>/dev/null || true
BOOTSTRAP="$APPFACTORY_ROOT/workspace/appfactory-tools/maintenance/bootstrap-v2.sh"
PREFLIGHT="$APPFACTORY_ROOT/workspace/appfactory-tools/maintenance/preflight-check.sh"
GENERATE_CADDY="$APPFACTORY_ROOT/workspace/appfactory-tools/scripts/generate-caddyfile.sh"
[ -f "$BOOTSTRAP" ] || fail "Missing bootstrap script: $BOOTSTRAP"
[ -f "$PREFLIGHT" ] || fail "Missing preflight script: $PREFLIGHT"
chmod +x "$BOOTSTRAP" "$PREFLIGHT"
[ -f "$GENERATE_CADDY" ] && chmod +x "$GENERATE_CADDY"
log "Running bootstrap repair"
sudo -u "$TARGET_USER" "$BOOTSTRAP" repair
if [ -f "$GENERATE_CADDY" ]; then
log "Generating Caddyfile"
sudo -u "$TARGET_USER" "$GENERATE_CADDY" || true
fi
log "Running bootstrap deploy"
sudo -u "$TARGET_USER" "$BOOTSTRAP" deploy
log "Running final preflight"
sudo -u "$TARGET_USER" "$PREFLIGHT"
echo
echo "APPFACTORY RESTORE: READY"