@@ -45,31 +45,202 @@ backup/
4545
4646## Restore data on Airgapped instance
4747
48- 1 . Download the latest version of ` restore-airgapped.sh `
48+ 1 . On the server running the Commercial Airgapped Edition, create a file named ` restore-airgapped.sh ` with the following content:
4949
5050 ``` bash
51- curl -fsSL https://github.com/makeplane/plane/releases/latest/download/restore-airgapped.sh -o restore-airgapped.sh
52- chmod +x restore-airgapped.sh
51+ #! /bin/bash
52+ set -euo pipefail
53+
54+ function print_header() {
55+ clear
56+
57+ cat << "EOF "
58+ ##+. ##+ .##-
59+ ######+.######-.######.
60+ #######. -### +#####+.
61+ #######. + +######.
62+ #######. .#######
63+ #######. .#######
64+ ####### + .#######
65+ .+#####+ ###- .#######
66+ .######.-#####+.+######
67+ -##. -## .+##
68+ EOF
69+ }
70+
71+ function restoreData() {
72+
73+ echo ""
74+ echo "****************************************************"
75+ echo "We are about to restore your data from the backup files."
76+ echo "****************************************************"
77+ echo ""
78+
79+ # set the backup folder path
80+ BACKUP_FOLDER=${1}
81+
82+ if [ -z "$BACKUP_FOLDER" ]; then
83+ BACKUP_FOLDER="$PWD/backup"
84+ read -p "Enter the backup folder path [$BACKUP_FOLDER]: " BACKUP_FOLDER
85+ if [ -z "$BACKUP_FOLDER" ]; then
86+ BACKUP_FOLDER="$PWD/backup"
87+ fi
88+ fi
89+
90+ # check if the backup folder exists
91+ if [ ! -d "$BACKUP_FOLDER" ]; then
92+ echo "Error: Backup folder not found at $BACKUP_FOLDER"
93+ exit 1
94+ fi
95+
96+ # check if there are any .tar.gz files in the backup folder
97+ if ! ls "$BACKUP_FOLDER"/*.tar.gz 1> /dev/null 2>&1; then
98+ echo "Error: Backup folder does not contain .tar.gz files"
99+ exit 1
100+ fi
101+
102+ echo ""
103+ echo "Using backup folder: $BACKUP_FOLDER"
104+ echo ""
105+
106+ # ask for current install path
107+ AIRGAPPED_INSTALL_PATH="$HOME/planeairgapped"
108+ read -p "Enter the airgapped instance install path [$AIRGAPPED_INSTALL_PATH]: " AIRGAPPED_INSTALL_PATH
109+ if [ -z "$AIRGAPPED_INSTALL_PATH" ]; then
110+ AIRGAPPED_INSTALL_PATH="$HOME/planeairgapped"
111+ fi
112+
113+ # check if the airgapped instance install path exists
114+ if [ ! -d "$AIRGAPPED_INSTALL_PATH" ]; then
115+ echo "Error: Airgapped instance install path not found at $AIRGAPPED_INSTALL_PATH"
116+ exit 1
117+ fi
118+
119+ echo ""
120+ echo "Using airgapped instance install path: $AIRGAPPED_INSTALL_PATH"
121+ echo ""
122+
123+ # check if the docker-compose.yaml exists
124+ if [ ! -f "$AIRGAPPED_INSTALL_PATH/docker-compose.yml" ]; then
125+ echo "Error: docker-compose.yml not found at $AIRGAPPED_INSTALL_PATH/docker-compose.yml"
126+ exit 1
127+ fi
128+
129+ local dockerServiceStatus
130+ if command -v jq &> /dev/null; then
131+ dockerServiceStatus=$($COMPOSE_CMD ls --filter name=plane-airgapped --format=json | jq -r .[0].Status)
132+ else
133+ dockerServiceStatus=$($COMPOSE_CMD ls --filter name=plane-airgapped | grep -o "running" | head -n 1)
134+ fi
135+
136+ if [[ $dockerServiceStatus == "running" ]]; then
137+ echo "Plane Airgapped is running. Please STOP the Plane Airgapped before restoring data."
138+ exit 1
139+ fi
140+
141+ CURRENT_USER_ID=$(id -u)
142+ CURRENT_GROUP_ID=$(id -g)
143+
144+ # if the data folder not exists, create it
145+ if [ ! -d "$AIRGAPPED_INSTALL_PATH/data" ]; then
146+ mkdir -p "$AIRGAPPED_INSTALL_PATH/data"
147+ chown -R $CURRENT_USER_ID:$CURRENT_GROUP_ID "$AIRGAPPED_INSTALL_PATH/data"
148+ fi
149+
150+ # Extract all backup tar files
151+ for BACKUP_FILE in "$BACKUP_FOLDER"/*.tar.gz; do
152+ if [ -e "$BACKUP_FILE" ]; then
153+ BASE_FILE_NAME=$(basename "$BACKUP_FILE" ".tar.gz")
154+ echo "Extracting $BASE_FILE_NAME"
155+ tar -xzvf "$BACKUP_FILE" -C "$AIRGAPPED_INSTALL_PATH/data/"
156+ if [ $? -ne 0 ]; then
157+ echo "Error: Failed to extract $BACKUP_FILE"
158+ exit 1
159+ fi
160+ else
161+ echo "No .tar.gz files found in the current directory."
162+ echo ""
163+ echo "Please provide the path to the backup file."
164+ echo ""
165+ echo "Usage: $0 /path/to/backup"
166+ exit 1
167+ fi
168+ done
169+
170+ DATA_DIR="$AIRGAPPED_INSTALL_PATH/data"
171+
172+ # Rename extracted directories to match docker-compose volume paths
173+ # Backup tars: pgdata, redisdata, uploads, rabbitmq_data
174+ # Docker-compose expects: db, redis, minio/uploads, mq
175+
176+ if [ -d "$DATA_DIR/pgdata" ]; then
177+ rm -rf "$DATA_DIR/db"
178+ mv "$DATA_DIR/pgdata" "$DATA_DIR/db"
179+ echo "Renamed pgdata -> db"
180+ fi
181+
182+ if [ -d "$DATA_DIR/redisdata" ]; then
183+ rm -rf "$DATA_DIR/redis"
184+ mv "$DATA_DIR/redisdata" "$DATA_DIR/redis"
185+ echo "Renamed redisdata -> redis"
186+ fi
187+
188+ if [ -d "$DATA_DIR/uploads" ]; then
189+ mkdir -p "$DATA_DIR/minio"
190+ rm -rf "$DATA_DIR/minio/uploads"
191+ mv "$DATA_DIR/uploads" "$DATA_DIR/minio/uploads"
192+ echo "Renamed uploads -> minio/uploads"
193+ fi
194+
195+ if [ -d "$DATA_DIR/rabbitmq_data" ]; then
196+ rm -rf "$DATA_DIR/mq"
197+ mv "$DATA_DIR/rabbitmq_data" "$DATA_DIR/mq"
198+ echo "Renamed rabbitmq_data -> mq"
199+ fi
200+
201+ # Fix ownership on all restored data
202+ chown -R $CURRENT_USER_ID:$CURRENT_GROUP_ID "$DATA_DIR"
203+
204+ echo ""
205+ echo "Restore completed successfully."
206+ echo ""
207+ }
208+
209+ # if docker-compose is installed
210+ if command -v docker-compose &> /dev/null
211+ then
212+ COMPOSE_CMD="docker-compose"
213+ else
214+ COMPOSE_CMD="docker compose"
215+ fi
216+
217+ print_header
218+ restoreData "$@"
53219 ```
54220
55221 This allows you to restore the Community Edition data to the Commercial Airgapped instance.
56222
57- 2 . Copy the ` restore-airgapped.sh ` script into your backup folder.
223+ 2. Make the script executable:
224+
225+ ```bash
226+ chmod +x restore-airgapped.sh
227+ ```
58228
59- 3 . Move your entire backup folder to the server running the Commercial Airgapped Edition.
229+ 3. Move your entire backup folder to the server running the Commercial Airgapped Edition using whatever secure method works in your environment .
60230
612314. Open terminal, and execute the following command:
62232
63233 ```bash
64234 sudo bash restore-airgapped.sh ./20250605-0938
65235 ```
66236
67- This will prompt you to enter the Commercial Airgapped Edition installation folder using whatever secure method works in your environment .
237+ The script will prompt you to enter the Commercial Airgapped Edition installation folder path .
68238
692395. After the data restore is finished, start the instance.
70240
71241 ```bash
72242 cd <airgapped-instance-folder>
243+ sudo docker compose -f docker-compose.yml down
73244 sudo docker compose -f docker-compose.yml --env-file plane.env up -d
74245 ```
75246
0 commit comments