mirror of
https://github.com/gosticks/plane.git
synced 2025-10-16 12:45:33 +00:00
* fix: update Dockerfile and docker-compose for version v0.28.0 and improve curl commands in install script * fix: update docker-compose to use 'stable' tag for all services * fix: improve curl command options in install script for better reliability
714 lines
22 KiB
Bash
Executable File
714 lines
22 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
BRANCH=${BRANCH:-master}
|
||
SCRIPT_DIR=$PWD
|
||
SERVICE_FOLDER=plane-app
|
||
PLANE_INSTALL_DIR=$PWD/$SERVICE_FOLDER
|
||
export APP_RELEASE=stable
|
||
export DOCKERHUB_USER=artifacts.plane.so/makeplane
|
||
export PULL_POLICY=${PULL_POLICY:-if_not_present}
|
||
export GH_REPO=makeplane/plane
|
||
export RELEASE_DOWNLOAD_URL="https://github.com/$GH_REPO/releases/download"
|
||
export FALLBACK_DOWNLOAD_URL="https://raw.githubusercontent.com/$GH_REPO/$BRANCH/deployments/cli/community"
|
||
|
||
CPU_ARCH=$(uname -m)
|
||
OS_NAME=$(uname)
|
||
UPPER_CPU_ARCH=$(tr '[:lower:]' '[:upper:]' <<< "$CPU_ARCH")
|
||
|
||
mkdir -p $PLANE_INSTALL_DIR/archive
|
||
DOCKER_FILE_PATH=$PLANE_INSTALL_DIR/docker-compose.yaml
|
||
DOCKER_ENV_PATH=$PLANE_INSTALL_DIR/plane.env
|
||
|
||
function print_header() {
|
||
clear
|
||
|
||
cat <<"EOF"
|
||
--------------------------------------------
|
||
____ _ /////////
|
||
| _ \| | __ _ _ __ ___ /////////
|
||
| |_) | |/ _` | '_ \ / _ \ ///// /////
|
||
| __/| | (_| | | | | __/ ///// /////
|
||
|_| |_|\__,_|_| |_|\___| ////
|
||
////
|
||
--------------------------------------------
|
||
Project management tool from the future
|
||
--------------------------------------------
|
||
EOF
|
||
}
|
||
|
||
function spinner() {
|
||
local pid=$1
|
||
local delay=.5
|
||
local spinstr='|/-\'
|
||
|
||
if ! ps -p "$pid" > /dev/null; then
|
||
echo "Invalid PID: $pid"
|
||
return 1
|
||
fi
|
||
while ps -p "$pid" > /dev/null; do
|
||
local temp=${spinstr#?}
|
||
printf " [%c] " "$spinstr" >&2
|
||
local spinstr=$temp${spinstr%"$temp"}
|
||
sleep $delay
|
||
printf "\b\b\b\b\b\b" >&2
|
||
done
|
||
printf " \b\b\b\b" >&2
|
||
}
|
||
|
||
function checkLatestRelease(){
|
||
echo "Checking for the latest release..." >&2
|
||
local latest_release=$(curl -sSL https://api.github.com/repos/$GH_REPO/releases/latest | grep -o '"tag_name": "[^"]*"' | sed 's/"tag_name": "//;s/"//g')
|
||
if [ -z "$latest_release" ]; then
|
||
echo "Failed to check for the latest release. Exiting..." >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo $latest_release
|
||
}
|
||
|
||
function initialize(){
|
||
printf "Please wait while we check the availability of Docker images for the selected release ($APP_RELEASE) with ${UPPER_CPU_ARCH} support." >&2
|
||
|
||
if [ "$CUSTOM_BUILD" == "true" ]; then
|
||
echo "" >&2
|
||
echo "" >&2
|
||
echo "${UPPER_CPU_ARCH} images are not available for selected release ($APP_RELEASE)." >&2
|
||
echo "build"
|
||
return 1
|
||
fi
|
||
|
||
local IMAGE_NAME=makeplane/plane-proxy
|
||
local IMAGE_TAG=${APP_RELEASE}
|
||
docker manifest inspect "${IMAGE_NAME}:${IMAGE_TAG}" | grep -q "\"architecture\": \"${CPU_ARCH}\"" &
|
||
local pid=$!
|
||
spinner "$pid"
|
||
|
||
echo "" >&2
|
||
|
||
wait "$pid"
|
||
|
||
if [ $? -eq 0 ]; then
|
||
echo "Plane supports ${CPU_ARCH}" >&2
|
||
echo "available"
|
||
return 0
|
||
else
|
||
echo "" >&2
|
||
echo "" >&2
|
||
echo "${UPPER_CPU_ARCH} images are not available for selected release ($APP_RELEASE)." >&2
|
||
echo "" >&2
|
||
echo "build"
|
||
return 1
|
||
fi
|
||
}
|
||
function getEnvValue() {
|
||
local key=$1
|
||
local file=$2
|
||
|
||
if [ -z "$key" ] || [ -z "$file" ]; then
|
||
echo "Invalid arguments supplied"
|
||
exit 1
|
||
fi
|
||
|
||
if [ -f "$file" ]; then
|
||
grep -q "^$key=" "$file"
|
||
if [ $? -eq 0 ]; then
|
||
local value
|
||
value=$(grep "^$key=" "$file" | cut -d'=' -f2)
|
||
echo "$value"
|
||
else
|
||
echo ""
|
||
fi
|
||
fi
|
||
}
|
||
function updateEnvFile() {
|
||
local key=$1
|
||
local value=$2
|
||
local file=$3
|
||
|
||
if [ -z "$key" ] || [ -z "$value" ] || [ -z "$file" ]; then
|
||
echo "Invalid arguments supplied"
|
||
exit 1
|
||
fi
|
||
|
||
if [ -f "$file" ]; then
|
||
# check if key exists in the file
|
||
grep -q "^$key=" "$file"
|
||
if [ $? -ne 0 ]; then
|
||
echo "$key=$value" >> "$file"
|
||
return
|
||
else
|
||
if [ "$OS_NAME" == "Darwin" ]; then
|
||
value=$(echo "$value" | sed 's/|/\\|/g')
|
||
sed -i '' "s|^$key=.*|$key=$value|g" "$file"
|
||
else
|
||
sed -i "s/^$key=.*/$key=$value/g" "$file"
|
||
fi
|
||
fi
|
||
else
|
||
echo "File not found: $file"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
function updateCustomVariables(){
|
||
echo "Updating custom variables..." >&2
|
||
updateEnvFile "DOCKERHUB_USER" "$DOCKERHUB_USER" "$DOCKER_ENV_PATH"
|
||
updateEnvFile "APP_RELEASE" "$APP_RELEASE" "$DOCKER_ENV_PATH"
|
||
updateEnvFile "PULL_POLICY" "$PULL_POLICY" "$DOCKER_ENV_PATH"
|
||
updateEnvFile "CUSTOM_BUILD" "$CUSTOM_BUILD" "$DOCKER_ENV_PATH"
|
||
echo "Custom variables updated successfully" >&2
|
||
}
|
||
|
||
function syncEnvFile(){
|
||
echo "Syncing environment variables..." >&2
|
||
if [ -f "$PLANE_INSTALL_DIR/plane.env.bak" ]; then
|
||
updateCustomVariables
|
||
|
||
# READ keys of plane.env and update the values from plane.env.bak
|
||
while IFS= read -r line
|
||
do
|
||
# ignore is the line is empty or starts with #
|
||
if [ -z "$line" ] || [[ $line == \#* ]]; then
|
||
continue
|
||
fi
|
||
key=$(echo "$line" | cut -d'=' -f1)
|
||
value=$(getEnvValue "$key" "$PLANE_INSTALL_DIR/plane.env.bak")
|
||
if [ -n "$value" ]; then
|
||
updateEnvFile "$key" "$value" "$DOCKER_ENV_PATH"
|
||
fi
|
||
done < "$DOCKER_ENV_PATH"
|
||
fi
|
||
echo "Environment variables synced successfully" >&2
|
||
}
|
||
|
||
function buildYourOwnImage(){
|
||
echo "Building images locally..."
|
||
|
||
export DOCKERHUB_USER="myplane"
|
||
export APP_RELEASE="local"
|
||
export PULL_POLICY="never"
|
||
CUSTOM_BUILD="true"
|
||
|
||
# checkout the code to ~/tmp/plane folder and build the images
|
||
local PLANE_TEMP_CODE_DIR=~/tmp/plane
|
||
rm -rf $PLANE_TEMP_CODE_DIR
|
||
mkdir -p $PLANE_TEMP_CODE_DIR
|
||
REPO=https://github.com/$GH_REPO.git
|
||
git clone "$REPO" "$PLANE_TEMP_CODE_DIR" --branch "$BRANCH" --single-branch --depth 1
|
||
|
||
cp "$PLANE_TEMP_CODE_DIR/deployments/cli/community/build.yml" "$PLANE_TEMP_CODE_DIR/build.yml"
|
||
|
||
cd "$PLANE_TEMP_CODE_DIR" || exit
|
||
|
||
/bin/bash -c "$COMPOSE_CMD -f build.yml build --no-cache" >&2
|
||
if [ $? -ne 0 ]; then
|
||
echo "Build failed. Exiting..."
|
||
exit 1
|
||
fi
|
||
echo "Build completed successfully"
|
||
echo ""
|
||
echo "You can now start the services by running the command: ./setup.sh start"
|
||
echo ""
|
||
}
|
||
|
||
function install() {
|
||
echo "Begin Installing Plane"
|
||
echo ""
|
||
|
||
if [ "$APP_RELEASE" == "stable" ]; then
|
||
export APP_RELEASE=$(checkLatestRelease)
|
||
fi
|
||
|
||
local build_image=$(initialize)
|
||
|
||
if [ "$build_image" == "build" ]; then
|
||
# ask for confirmation to continue building the images
|
||
echo "Do you want to continue with building the Docker images locally?"
|
||
read -p "Continue? [y/N]: " confirm
|
||
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
||
echo "Exiting..."
|
||
exit 0
|
||
fi
|
||
fi
|
||
|
||
if [ "$build_image" == "build" ]; then
|
||
download "true"
|
||
else
|
||
download "false"
|
||
fi
|
||
}
|
||
|
||
function download() {
|
||
local LOCAL_BUILD=$1
|
||
cd $SCRIPT_DIR
|
||
TS=$(date +%s)
|
||
if [ -f "$PLANE_INSTALL_DIR/docker-compose.yaml" ]
|
||
then
|
||
mv $PLANE_INSTALL_DIR/docker-compose.yaml $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yaml
|
||
fi
|
||
|
||
RESPONSE=$(curl -sSL -H 'Cache-Control: no-cache, no-store' -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/docker-compose.yml?$(date +%s)")
|
||
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
||
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
||
|
||
if [ "$STATUS" -eq 200 ]; then
|
||
echo "$BODY" > $PLANE_INSTALL_DIR/docker-compose.yaml
|
||
else
|
||
# Fallback to download from the raw github url
|
||
RESPONSE=$(curl -sSL -H 'Cache-Control: no-cache, no-store' -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/docker-compose.yml?$(date +%s)")
|
||
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
||
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
||
|
||
if [ "$STATUS" -eq 200 ]; then
|
||
echo "$BODY" > $PLANE_INSTALL_DIR/docker-compose.yaml
|
||
else
|
||
echo "Failed to download docker-compose.yml. HTTP Status: $STATUS"
|
||
echo "URL: $RELEASE_DOWNLOAD_URL/$APP_RELEASE/docker-compose.yml"
|
||
mv $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yaml $PLANE_INSTALL_DIR/docker-compose.yaml
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
RESPONSE=$(curl -sSL -H 'Cache-Control: no-cache, no-store' -w "HTTPSTATUS:%{http_code}" "$RELEASE_DOWNLOAD_URL/$APP_RELEASE/variables.env?$(date +%s)")
|
||
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
||
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
||
|
||
if [ "$STATUS" -eq 200 ]; then
|
||
echo "$BODY" > $PLANE_INSTALL_DIR/variables-upgrade.env
|
||
else
|
||
# Fallback to download from the raw github url
|
||
RESPONSE=$(curl -sSL -H 'Cache-Control: no-cache, no-store' -w "HTTPSTATUS:%{http_code}" "$FALLBACK_DOWNLOAD_URL/variables.env?$(date +%s)")
|
||
BODY=$(echo "$RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
|
||
STATUS=$(echo "$RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
|
||
|
||
if [ "$STATUS" -eq 200 ]; then
|
||
echo "$BODY" > $PLANE_INSTALL_DIR/variables-upgrade.env
|
||
else
|
||
echo "Failed to download variables.env. HTTP Status: $STATUS"
|
||
echo "URL: $RELEASE_DOWNLOAD_URL/$APP_RELEASE/variables.env"
|
||
mv $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yaml $PLANE_INSTALL_DIR/docker-compose.yaml
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
if [ -f "$DOCKER_ENV_PATH" ];
|
||
then
|
||
cp "$DOCKER_ENV_PATH" "$PLANE_INSTALL_DIR/archive/$TS.env"
|
||
cp "$DOCKER_ENV_PATH" "$PLANE_INSTALL_DIR/plane.env.bak"
|
||
fi
|
||
|
||
mv $PLANE_INSTALL_DIR/variables-upgrade.env $DOCKER_ENV_PATH
|
||
|
||
syncEnvFile
|
||
|
||
if [ "$LOCAL_BUILD" == "true" ]; then
|
||
export DOCKERHUB_USER="myplane"
|
||
export APP_RELEASE="local"
|
||
export PULL_POLICY="never"
|
||
CUSTOM_BUILD="true"
|
||
|
||
buildYourOwnImage
|
||
|
||
if [ $? -ne 0 ]; then
|
||
echo ""
|
||
echo "Build failed. Exiting..."
|
||
exit 1
|
||
fi
|
||
updateCustomVariables
|
||
else
|
||
CUSTOM_BUILD="false"
|
||
updateCustomVariables
|
||
/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH --env-file=$DOCKER_ENV_PATH pull --policy always"
|
||
|
||
if [ $? -ne 0 ]; then
|
||
echo ""
|
||
echo "Failed to pull the images. Exiting..."
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
echo ""
|
||
echo "Most recent version of Plane is now available for you to use"
|
||
echo ""
|
||
echo "In case of 'Upgrade', please check the 'plane.env 'file for any new variables and update them accordingly"
|
||
echo ""
|
||
}
|
||
function startServices() {
|
||
/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH --env-file=$DOCKER_ENV_PATH up -d --pull if_not_present --quiet-pull"
|
||
|
||
local migrator_container_id=$(docker container ls -aq -f "name=$SERVICE_FOLDER-migrator")
|
||
if [ -n "$migrator_container_id" ]; then
|
||
local idx=0
|
||
while docker inspect --format='{{.State.Status}}' $migrator_container_id | grep -q "running"; do
|
||
local message=">> Waiting for Data Migration to finish"
|
||
local dots=$(printf '%*s' $idx | tr ' ' '.')
|
||
echo -ne "\r$message$dots"
|
||
((idx++))
|
||
sleep 1
|
||
done
|
||
fi
|
||
printf "\r\033[K"
|
||
echo ""
|
||
echo " Data Migration completed successfully ✅"
|
||
|
||
# if migrator exit status is not 0, show error message and exit
|
||
if [ -n "$migrator_container_id" ]; then
|
||
local migrator_exit_code=$(docker inspect --format='{{.State.ExitCode}}' $migrator_container_id)
|
||
if [ $migrator_exit_code -ne 0 ]; then
|
||
echo "Plane Server failed to start ❌"
|
||
# stopServices
|
||
echo
|
||
echo "Please check the logs for the 'migrator' service and resolve the issue(s)."
|
||
echo "Stop the services by running the command: ./setup.sh stop"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
local api_container_id=$(docker container ls -q -f "name=$SERVICE_FOLDER-api")
|
||
|
||
# Verify container exists
|
||
if [ -z "$api_container_id" ]; then
|
||
echo " Error: API container not found. Please check if services are running."
|
||
exit 1
|
||
fi
|
||
|
||
local idx2=0
|
||
local api_ready=true # assume success, flip on timeout
|
||
local max_wait_time=300 # 5 minutes timeout
|
||
local start_time=$(date +%s)
|
||
|
||
echo " Waiting for API Service to be ready..."
|
||
while ! docker exec "$api_container_id" python3 -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/', timeout=3)" > /dev/null 2>&1; do
|
||
local current_time=$(date +%s)
|
||
local elapsed_time=$((current_time - start_time))
|
||
|
||
if [ $elapsed_time -gt $max_wait_time ]; then
|
||
echo ""
|
||
echo " API Service health check timed out after 5 minutes"
|
||
echo " Checking if API container is still running..."
|
||
if docker ps | grep -q "$SERVICE_FOLDER-api"; then
|
||
echo " API container is running but did not pass the health-check. Continuing without marking it ready."
|
||
api_ready=false
|
||
break
|
||
else
|
||
echo " API container is not running. Please check logs."
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
local message=">> Waiting for API Service to Start (${elapsed_time}s)"
|
||
local dots=$(printf '%*s' $idx2 | tr ' ' '.')
|
||
echo -ne "\r$message$dots"
|
||
((idx2++))
|
||
sleep 1
|
||
done
|
||
printf "\r\033[K"
|
||
if [ "$api_ready" = true ]; then
|
||
echo " API Service started successfully ✅"
|
||
else
|
||
echo " ⚠️ API Service did not respond to health-check – please verify manually."
|
||
fi
|
||
source "${DOCKER_ENV_PATH}"
|
||
echo " Plane Server started successfully ✅"
|
||
echo ""
|
||
echo " You can access the application at $WEB_URL"
|
||
echo ""
|
||
|
||
}
|
||
function stopServices() {
|
||
/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH --env-file=$DOCKER_ENV_PATH down"
|
||
}
|
||
function restartServices() {
|
||
stopServices
|
||
startServices
|
||
}
|
||
function upgrade() {
|
||
local latest_release=$(checkLatestRelease)
|
||
|
||
echo ""
|
||
echo "Current release: $APP_RELEASE"
|
||
|
||
if [ "$latest_release" == "$APP_RELEASE" ]; then
|
||
echo ""
|
||
echo "You are already using the latest release"
|
||
exit 0
|
||
fi
|
||
|
||
echo "Latest release: $latest_release"
|
||
echo ""
|
||
|
||
# Check for confirmation to upgrade
|
||
echo "Do you want to upgrade to the latest release ($latest_release)?"
|
||
read -p "Continue? [y/N]: " confirm
|
||
|
||
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
||
echo "Exiting..."
|
||
exit 0
|
||
fi
|
||
|
||
export APP_RELEASE=$latest_release
|
||
|
||
echo "Upgrading Plane to the latest release..."
|
||
echo ""
|
||
|
||
echo "***** STOPPING SERVICES ****"
|
||
stopServices
|
||
|
||
echo
|
||
echo "***** DOWNLOADING STABLE VERSION ****"
|
||
install
|
||
|
||
echo "***** PLEASE VALIDATE AND START SERVICES ****"
|
||
}
|
||
function viewSpecificLogs(){
|
||
local SERVICE_NAME=$1
|
||
|
||
if /bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH ps | grep -q '$SERVICE_NAME'"; then
|
||
echo "Service '$SERVICE_NAME' is running."
|
||
else
|
||
echo "Service '$SERVICE_NAME' is not running."
|
||
fi
|
||
|
||
/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH logs -f $SERVICE_NAME"
|
||
}
|
||
function viewLogs(){
|
||
|
||
ARG_SERVICE_NAME=$2
|
||
|
||
if [ -z "$ARG_SERVICE_NAME" ];
|
||
then
|
||
echo
|
||
echo "Select a Service you want to view the logs for:"
|
||
echo " 1) Web"
|
||
echo " 2) Space"
|
||
echo " 3) API"
|
||
echo " 4) Worker"
|
||
echo " 5) Beat-Worker"
|
||
echo " 6) Migrator"
|
||
echo " 7) Proxy"
|
||
echo " 8) Redis"
|
||
echo " 9) Postgres"
|
||
echo " 10) Minio"
|
||
echo " 11) RabbitMQ"
|
||
echo " 0) Back to Main Menu"
|
||
echo
|
||
read -p "Service: " DOCKER_SERVICE_NAME
|
||
|
||
until (( DOCKER_SERVICE_NAME >= 0 && DOCKER_SERVICE_NAME <= 11 )); do
|
||
echo "Invalid selection. Please enter a number between 0 and 11."
|
||
read -p "Service: " DOCKER_SERVICE_NAME
|
||
done
|
||
|
||
if [ -z "$DOCKER_SERVICE_NAME" ];
|
||
then
|
||
echo "INVALID SERVICE NAME SUPPLIED"
|
||
else
|
||
case $DOCKER_SERVICE_NAME in
|
||
1) viewSpecificLogs "web";;
|
||
2) viewSpecificLogs "space";;
|
||
3) viewSpecificLogs "api";;
|
||
4) viewSpecificLogs "worker";;
|
||
5) viewSpecificLogs "beat-worker";;
|
||
6) viewSpecificLogs "migrator";;
|
||
7) viewSpecificLogs "proxy";;
|
||
8) viewSpecificLogs "plane-redis";;
|
||
9) viewSpecificLogs "plane-db";;
|
||
10) viewSpecificLogs "plane-minio";;
|
||
11) viewSpecificLogs "plane-mq";;
|
||
0) askForAction;;
|
||
*) echo "INVALID SERVICE NAME SUPPLIED";;
|
||
esac
|
||
fi
|
||
elif [ -n "$ARG_SERVICE_NAME" ];
|
||
then
|
||
ARG_SERVICE_NAME=$(echo "$ARG_SERVICE_NAME" | tr '[:upper:]' '[:lower:]')
|
||
case $ARG_SERVICE_NAME in
|
||
web) viewSpecificLogs "web";;
|
||
space) viewSpecificLogs "space";;
|
||
api) viewSpecificLogs "api";;
|
||
worker) viewSpecificLogs "worker";;
|
||
beat-worker) viewSpecificLogs "beat-worker";;
|
||
migrator) viewSpecificLogs "migrator";;
|
||
proxy) viewSpecificLogs "proxy";;
|
||
redis) viewSpecificLogs "plane-redis";;
|
||
postgres) viewSpecificLogs "plane-db";;
|
||
minio) viewSpecificLogs "plane-minio";;
|
||
rabbitmq) viewSpecificLogs "plane-mq";;
|
||
*) echo "INVALID SERVICE NAME SUPPLIED";;
|
||
esac
|
||
else
|
||
echo "INVALID SERVICE NAME SUPPLIED"
|
||
fi
|
||
}
|
||
function backup_container_dir() {
|
||
local BACKUP_FOLDER=$1
|
||
local CONTAINER_NAME=$2
|
||
local CONTAINER_DATA_DIR=$3
|
||
local SERVICE_FOLDER=$4
|
||
|
||
echo "Backing up $CONTAINER_NAME data..."
|
||
local CONTAINER_ID=$(/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH ps -q $CONTAINER_NAME")
|
||
if [ -z "$CONTAINER_ID" ]; then
|
||
echo "Error: $CONTAINER_NAME container not found. Make sure the services are running."
|
||
return 1
|
||
fi
|
||
|
||
# Create a temporary directory for the backup
|
||
mkdir -p "$BACKUP_FOLDER/$SERVICE_FOLDER"
|
||
|
||
# Copy the data directory from the running container
|
||
echo "Copying $CONTAINER_NAME data directory..."
|
||
docker cp -q "$CONTAINER_ID:$CONTAINER_DATA_DIR/." "$BACKUP_FOLDER/$SERVICE_FOLDER/"
|
||
local cp_status=$?
|
||
|
||
if [ $cp_status -ne 0 ]; then
|
||
echo "Error: Failed to copy $SERVICE_FOLDER data"
|
||
rm -rf $BACKUP_FOLDER/$SERVICE_FOLDER
|
||
return 1
|
||
fi
|
||
|
||
# Create tar.gz of the data
|
||
cd "$BACKUP_FOLDER"
|
||
tar -czf "${SERVICE_FOLDER}.tar.gz" "$SERVICE_FOLDER/"
|
||
local tar_status=$?
|
||
if [ $tar_status -eq 0 ]; then
|
||
rm -rf "$SERVICE_FOLDER/"
|
||
fi
|
||
cd - > /dev/null
|
||
|
||
if [ $tar_status -ne 0 ]; then
|
||
echo "Error: Failed to create tar archive"
|
||
return 1
|
||
fi
|
||
|
||
echo "Successfully backed up $SERVICE_FOLDER data"
|
||
}
|
||
|
||
function backupData() {
|
||
local datetime=$(date +"%Y%m%d-%H%M")
|
||
local BACKUP_FOLDER=$PLANE_INSTALL_DIR/backup/$datetime
|
||
mkdir -p "$BACKUP_FOLDER"
|
||
|
||
# Check if docker-compose.yml exists
|
||
if [ ! -f "$DOCKER_FILE_PATH" ]; then
|
||
echo "Error: docker-compose.yml not found at $DOCKER_FILE_PATH"
|
||
exit 1
|
||
fi
|
||
|
||
backup_container_dir "$BACKUP_FOLDER" "plane-db" "/var/lib/postgresql/data" "pgdata" || exit 1
|
||
backup_container_dir "$BACKUP_FOLDER" "plane-minio" "/export" "uploads" || exit 1
|
||
backup_container_dir "$BACKUP_FOLDER" "plane-mq" "/var/lib/rabbitmq" "rabbitmq_data" || exit 1
|
||
backup_container_dir "$BACKUP_FOLDER" "plane-redis" "/data" "redisdata" || exit 1
|
||
|
||
echo ""
|
||
echo "Backup completed successfully. Backup files are stored in $BACKUP_FOLDER"
|
||
echo ""
|
||
}
|
||
function askForAction() {
|
||
local DEFAULT_ACTION=$1
|
||
|
||
if [ -z "$DEFAULT_ACTION" ];
|
||
then
|
||
echo
|
||
echo "Select a Action you want to perform:"
|
||
echo " 1) Install"
|
||
echo " 2) Start"
|
||
echo " 3) Stop"
|
||
echo " 4) Restart"
|
||
echo " 5) Upgrade"
|
||
echo " 6) View Logs"
|
||
echo " 7) Backup Data"
|
||
echo " 8) Exit"
|
||
echo
|
||
read -p "Action [2]: " ACTION
|
||
until [[ -z "$ACTION" || "$ACTION" =~ ^[1-8]$ ]]; do
|
||
echo "$ACTION: invalid selection."
|
||
read -p "Action [2]: " ACTION
|
||
done
|
||
|
||
if [ -z "$ACTION" ];
|
||
then
|
||
ACTION=2
|
||
fi
|
||
echo
|
||
fi
|
||
|
||
if [ "$ACTION" == "1" ] || [ "$DEFAULT_ACTION" == "install" ];
|
||
then
|
||
install
|
||
# askForAction
|
||
elif [ "$ACTION" == "2" ] || [ "$DEFAULT_ACTION" == "start" ];
|
||
then
|
||
startServices
|
||
# askForAction
|
||
elif [ "$ACTION" == "3" ] || [ "$DEFAULT_ACTION" == "stop" ];
|
||
then
|
||
stopServices
|
||
# askForAction
|
||
elif [ "$ACTION" == "4" ] || [ "$DEFAULT_ACTION" == "restart" ];
|
||
then
|
||
restartServices
|
||
# askForAction
|
||
elif [ "$ACTION" == "5" ] || [ "$DEFAULT_ACTION" == "upgrade" ];
|
||
then
|
||
upgrade
|
||
# askForAction
|
||
elif [ "$ACTION" == "6" ] || [ "$DEFAULT_ACTION" == "logs" ];
|
||
then
|
||
viewLogs "$@"
|
||
askForAction
|
||
elif [ "$ACTION" == "7" ] || [ "$DEFAULT_ACTION" == "backup" ];
|
||
then
|
||
backupData
|
||
elif [ "$ACTION" == "8" ]
|
||
then
|
||
exit 0
|
||
else
|
||
echo "INVALID ACTION SUPPLIED"
|
||
fi
|
||
}
|
||
|
||
# if docker-compose is installed
|
||
if command -v docker-compose &> /dev/null
|
||
then
|
||
COMPOSE_CMD="docker-compose"
|
||
else
|
||
COMPOSE_CMD="docker compose"
|
||
fi
|
||
|
||
if [ "$CPU_ARCH" == "x86_64" ] || [ "$CPU_ARCH" == "amd64" ]; then
|
||
CPU_ARCH="amd64"
|
||
elif [ "$CPU_ARCH" == "aarch64" ] || [ "$CPU_ARCH" == "arm64" ]; then
|
||
CPU_ARCH="arm64"
|
||
fi
|
||
|
||
if [ -f "$DOCKER_ENV_PATH" ]; then
|
||
DOCKERHUB_USER=$(getEnvValue "DOCKERHUB_USER" "$DOCKER_ENV_PATH")
|
||
APP_RELEASE=$(getEnvValue "APP_RELEASE" "$DOCKER_ENV_PATH")
|
||
PULL_POLICY=$(getEnvValue "PULL_POLICY" "$DOCKER_ENV_PATH")
|
||
CUSTOM_BUILD=$(getEnvValue "CUSTOM_BUILD" "$DOCKER_ENV_PATH")
|
||
|
||
if [ -z "$DOCKERHUB_USER" ]; then
|
||
DOCKERHUB_USER=artifacts.plane.so/makeplane
|
||
updateEnvFile "DOCKERHUB_USER" "$DOCKERHUB_USER" "$DOCKER_ENV_PATH"
|
||
fi
|
||
|
||
if [ -z "$APP_RELEASE" ]; then
|
||
APP_RELEASE=stable
|
||
updateEnvFile "APP_RELEASE" "$APP_RELEASE" "$DOCKER_ENV_PATH"
|
||
fi
|
||
|
||
if [ -z "$PULL_POLICY" ]; then
|
||
PULL_POLICY=if_not_present
|
||
updateEnvFile "PULL_POLICY" "$PULL_POLICY" "$DOCKER_ENV_PATH"
|
||
fi
|
||
|
||
if [ -z "$CUSTOM_BUILD" ]; then
|
||
CUSTOM_BUILD=false
|
||
updateEnvFile "CUSTOM_BUILD" "$CUSTOM_BUILD" "$DOCKER_ENV_PATH"
|
||
fi
|
||
fi
|
||
|
||
print_header
|
||
askForAction "$@"
|