Skip to content
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 87 additions & 45 deletions deployments/cli/community/restore-airgapped.sh
Original file line number Diff line number Diff line change
@@ -1,23 +1,45 @@
#!/bin/bash
+set -euo pipefail
set -euo pipefail

function print_header() {
clear

cat <<"EOF"
--------------------------------------------
____ _ /////////
| _ \| | __ _ _ __ ___ /////////
| |_) | |/ _` | '_ \ / _ \ ///// /////
| __/| | (_| | | | | __/ ///// /////
|_| |_|\__,_|_| |_|\___| ////
////
--------------------------------------------
Project management tool from the future
--------------------------------------------
##+. ##+ .##-
######+.######-.######.
#######. -### +#####+.
#######. + +######.
#######. .#######
#######. .#######
####### + .#######
.+#####+ ###- .#######
.######.-#####+.+######
-##. -## .+##
EOF
}

# Replace $2 (dest) with $1 (src), keeping the old dest recoverable until the
# swap succeeds. Rolls the old data back if the move fails.
function replaceDir() {
local src="$1" dest="$2" label="$3"
local old="${dest}.old.$$"

if [ -d "$dest" ]; then
mv "$dest" "$old"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
fi

if mv "$src" "$dest"; then
rm -rf "$old"
echo "Renamed $label"
else
echo "Error: Failed to install $label; restoring previous data"
if [ -d "$old" ]; then
mv "$old" "$dest"
fi
exit 1
fi
}

function restoreData() {

echo ""
Expand All @@ -27,7 +49,7 @@ function restoreData() {
echo ""

# set the backup folder path
BACKUP_FOLDER=${1}
BACKUP_FOLDER="${1:-}"

if [ -z "$BACKUP_FOLDER" ]; then
BACKUP_FOLDER="$PWD/backup"
Expand All @@ -46,6 +68,8 @@ function restoreData() {
# check if there are any .tar.gz files in the backup folder
if ! ls "$BACKUP_FOLDER"/*.tar.gz 1> /dev/null 2>&1; then
echo "Error: Backup folder does not contain .tar.gz files"
echo ""
echo "Usage: $0 /path/to/backup"
exit 1
fi

Expand Down Expand Up @@ -76,57 +100,75 @@ function restoreData() {
exit 1
fi

local dockerServiceStatus
local dockerServiceStatus compose_output
if command -v jq &> /dev/null; then
dockerServiceStatus=$($COMPOSE_CMD ls --filter name=plane-airgapped --format=json | jq -r .[0].Status)
if ! compose_output=$($COMPOSE_CMD ls --filter name=plane-airgapped --format=json); then
echo "Error: Failed to query Docker Compose services"
exit 1
fi
dockerServiceStatus=$(printf '%s\n' "$compose_output" | jq -r '.[0].Status // empty')
else
Comment thread
akshat5302 marked this conversation as resolved.
dockerServiceStatus=$($COMPOSE_CMD ls --filter name=plane-airgapped | grep -o "running" | head -n 1)
if ! compose_output=$($COMPOSE_CMD ls --filter name=plane-airgapped); then
echo "Error: Failed to query Docker Compose services"
exit 1
fi
dockerServiceStatus=$(printf '%s\n' "$compose_output" | grep -o "running" | head -n 1 || true)
fi

if [[ $dockerServiceStatus == "running" ]]; then
if [[ "$dockerServiceStatus" == running* ]]; then
echo "Plane Airgapped is running. Please STOP the Plane Airgapped before restoring data."
exit 1
fi

CURRENT_USER_ID=$(id -u)
CURRENT_GROUP_ID=$(id -g)

DATA_DIR="$AIRGAPPED_INSTALL_PATH/data"

# if the data folder not exists, create it
if [ ! -d "$AIRGAPPED_INSTALL_PATH/data" ]; then
mkdir -p "$AIRGAPPED_INSTALL_PATH/data"
chown -R $CURRENT_USER_ID:$CURRENT_GROUP_ID "$AIRGAPPED_INSTALL_PATH/data"
if [ ! -d "$DATA_DIR" ]; then
mkdir -p "$DATA_DIR"
chown -R $CURRENT_USER_ID:$CURRENT_GROUP_ID "$DATA_DIR"
fi

for BACKUP_FILE in "$BACKUP_FOLDER/*.tar.gz"; do
if [ -e "$BACKUP_FILE" ]; then

# get the basefilename without the extension
BASE_FILE_NAME=$(basename "$BACKUP_FILE" ".tar.gz")

# extract the restoreFile to the airgapped instance install path
echo "Restoring $BASE_FILE_NAME"
rm -rf "$AIRGAPPED_INSTALL_PATH/data/$BASE_FILE_NAME" || true

tar -xvzf "$BACKUP_FILE" -C "$AIRGAPPED_INSTALL_PATH/data/"
if [ $? -ne 0 ]; then
echo "Error: Failed to extract $BACKUP_FILE"
exit 1
fi
chown -R $CURRENT_USER_ID:$CURRENT_GROUP_ID "$AIRGAPPED_INSTALL_PATH/data/$BASE_FILE_NAME"
if [ $? -ne 0 ]; then
echo "Error: Failed to change ownership of $AIRGAPPED_INSTALL_PATH/data/$BASE_FILE_NAME"
exit 1
fi
else
echo "No .tar.gz files found in the current directory."
echo ""
echo "Please provide the path to the backup file."
echo ""
echo "Usage: $0 /path/to/backup"
# Remove stale extracted source directories from a previous run so tar
# does not merge new files into old data
rm -rf "$DATA_DIR/pgdata" "$DATA_DIR/redisdata" "$DATA_DIR/uploads" "$DATA_DIR/rabbitmq_data"

# Extract all backup tar files
for BACKUP_FILE in "$BACKUP_FOLDER"/*.tar.gz; do
Comment thread
akshat5302 marked this conversation as resolved.
BASE_FILE_NAME=$(basename "$BACKUP_FILE" ".tar.gz")
echo "Extracting $BASE_FILE_NAME"
if ! tar -xzvf "$BACKUP_FILE" -C "$DATA_DIR/"; then
echo "Error: Failed to extract $BACKUP_FILE"
exit 1
fi
done

# Rename extracted directories to match docker-compose volume paths
# Backup tars: pgdata, redisdata, uploads, rabbitmq_data
# Docker-compose expects: db, redis, minio/uploads, mq

if [ -d "$DATA_DIR/pgdata" ]; then
replaceDir "$DATA_DIR/pgdata" "$DATA_DIR/db" "pgdata -> db"
fi

if [ -d "$DATA_DIR/redisdata" ]; then
replaceDir "$DATA_DIR/redisdata" "$DATA_DIR/redis" "redisdata -> redis"
fi

if [ -d "$DATA_DIR/uploads" ]; then
mkdir -p "$DATA_DIR/minio"
replaceDir "$DATA_DIR/uploads" "$DATA_DIR/minio/uploads" "uploads -> minio/uploads"
fi

if [ -d "$DATA_DIR/rabbitmq_data" ]; then
replaceDir "$DATA_DIR/rabbitmq_data" "$DATA_DIR/mq" "rabbitmq_data -> mq"
fi

# Fix ownership on all restored data
chown -R $CURRENT_USER_ID:$CURRENT_GROUP_ID "$DATA_DIR"

echo ""
echo "Restore completed successfully."
echo ""
Expand Down
Loading