forked from freeleaps/freeleaps-pub
3261 lines
102 KiB
Bash
3261 lines
102 KiB
Bash
#!/usr/bin/env bash
|
||
# Modifying it manually is not recommended
|
||
|
||
# :wrapper.bash3_bouncer
|
||
if [[ "${BASH_VERSINFO:-0}" -lt 3 ]]; then
|
||
printf "bash version 3 or higher is required\n" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# :command.master_script
|
||
|
||
# :command.version_command
|
||
version_command() {
|
||
echo "$version"
|
||
}
|
||
|
||
upper() {
|
||
echo "$1" | tr '[:lower:]' '[:upper:]'
|
||
}
|
||
|
||
lower() {
|
||
echo "$1" | tr '[:upper:]' '[:lower:]'
|
||
}
|
||
|
||
|
||
# Add a key-value pair to the args array
|
||
add_arg() {
|
||
local key="$1"
|
||
local value="$2"
|
||
args_keys+=("$key")
|
||
args_values+=("$value")
|
||
}
|
||
|
||
# Get the value of a key from the args array
|
||
|
||
get_arg() {
|
||
local key="$1"
|
||
local default="${2:-}"
|
||
local i
|
||
|
||
for i in "${!args_keys[@]}"; do
|
||
if [ "${args_keys[$i]}" = "$key" ]; then
|
||
echo "${args_values[$i]}"
|
||
return 0
|
||
fi
|
||
done
|
||
echo "$default"
|
||
return 1
|
||
}
|
||
|
||
|
||
# :command.usage
|
||
devbox_usage() {
|
||
printf "devbox - DevBox Command Line Tool\n\n"
|
||
|
||
printf "%s\n" "Usage:"
|
||
printf " devbox COMMAND\n"
|
||
printf " devbox [COMMAND] --help | -h\n"
|
||
printf " devbox --version | -v\n"
|
||
echo
|
||
# :command.usage_commands
|
||
printf "%s\n" "Commands:"
|
||
printf " %s Initialize the local development environment based on DevBox container.\n" "init"
|
||
echo
|
||
|
||
# :command.long_usage
|
||
if [[ -n "$long_usage" ]]; then
|
||
printf "%s\n" "Options:"
|
||
|
||
# :command.usage_fixed_flags
|
||
printf " %s\n" "--help, -h"
|
||
printf " Show this help\n"
|
||
echo
|
||
printf " %s\n" "--version, -v"
|
||
printf " Show version number\n"
|
||
echo
|
||
|
||
# :command.usage_environment_variables
|
||
printf "%s\n" "Environment Variables:"
|
||
|
||
# :environment_variable.usage
|
||
printf " %s\n" "FREELEAPS_USERNAME"
|
||
printf " Set the Freeleaps username for cloning the source repository.\n"
|
||
echo
|
||
|
||
# :environment_variable.usage
|
||
printf " %s\n" "FREELEAPS_PASSWORD"
|
||
printf " Set the Freeleaps password for cloning the source repository.\n"
|
||
echo
|
||
|
||
# :environment_variable.usage
|
||
printf " %s\n" "WORKING_HOME"
|
||
printf " Set the working home directory for DevBox.\n"
|
||
echo
|
||
|
||
fi
|
||
}
|
||
|
||
|
||
# :command.usage
|
||
devbox_init_usage() {
|
||
if [[ -n $long_usage ]]; then
|
||
printf "devbox init\n\n"
|
||
printf " Initialize the local development environment based on DevBox container.\n This command will pull the DevBox container image, create containers for \n various Freeleaps components, clone the source code repository, and \n persist relevant container/process information under WORKING_HOME.\n \n Sub-command \`init\` uses Docker (or another container runtime) to set \n up a local DevBox environment for Freeleaps development. \n It follows these major steps:\n 1. Validate flags and environment.\n 2. Pull DevBox base image and create container.\n 3. Pull each required component image, create containers.\n 4. Clone remote source repository using FREELEAPS_USERNAME/PASSWORD.\n 5. Start back-end and front-end services.\n 6. Persist container IDs, logs, etc. into WORKING_HOME.\n\n"
|
||
else
|
||
printf "devbox init - Initialize the local development environment based on DevBox container.\n\n"
|
||
fi
|
||
printf "Alias: i\n"
|
||
echo
|
||
|
||
printf "%s\n" "Usage:"
|
||
printf " devbox init [OPTIONS]\n"
|
||
printf " devbox init --help | -h\n"
|
||
echo
|
||
|
||
# :command.long_usage
|
||
if [[ -n "$long_usage" ]]; then
|
||
printf "%s\n" "Options:"
|
||
|
||
# :command.usage_flags
|
||
# :flag.usage os (auto, linux, darwin, wsl2)
|
||
printf " %s\n" "--os OS"
|
||
printf " Specifies the operating system (auto, linux, darwin, wsl2). Default is auto.\n"
|
||
printf " %s\n" "Default: auto"
|
||
echo
|
||
|
||
# :flag.usage arch
|
||
printf " %s\n" "--arch ARCH"
|
||
printf " Specifies the architecture (auto, amd64, arm64). Default is auto.\n"
|
||
printf " %s\n" "Default: auto"
|
||
echo
|
||
|
||
# :flag.usage devbox container name
|
||
printf " %s\n" "--devbox-container-name DEVBOX_CONTAINER_NAME"
|
||
printf " Specifies the DevBox container name. Default is devbox.\n"
|
||
printf " %s\n" "Default: devbox"
|
||
echo
|
||
|
||
# :flag.usage devbox container port
|
||
printf " %s\n" "--devbox-container-port DEVBOX_CONTAINER_PORT"
|
||
printf " Specifies the container port for DevBox SSH access. Default is 22222.\n"
|
||
printf " %s\n" "Default: 22222"
|
||
echo
|
||
|
||
# :flag.usage devbox image repo
|
||
printf " %s\n" "--devbox-image-repo DEVBOX_IMAGE_REPO"
|
||
printf " Specifies the DevBox container image repository. Default is\n docker.io/freeleaps.\n"
|
||
printf " %s\n" "Default: docker.io/freeleaps"
|
||
echo
|
||
|
||
# :flag.usage devbox frontend port
|
||
printf " %s\n" "--devbox-frontend-port DEVBOX_FRONTEND_PORT"
|
||
printf " Specifies the container port for DevBox frontend access. Default is 5173.\n"
|
||
printf " %s\n" "Default: 5173"
|
||
echo
|
||
|
||
# :flag.usage devbox backend port
|
||
printf " %s\n" "--devbox-backend-port DEVBOX_BACKEND_PORT"
|
||
printf " Specifies the container port for DevBox backend access. Default is 8002.\n"
|
||
printf " %s\n" "Default: 8002"
|
||
echo
|
||
|
||
# :flag.usage devbox image name
|
||
printf " %s\n" "--devbox-image-name DEVBOX_IMAGE_NAME"
|
||
printf " Specifies the DevBox container image name. Default is devbox.\n"
|
||
printf " %s\n" "Default: devbox"
|
||
echo
|
||
|
||
# :flag.usage devbox image tag
|
||
printf " %s\n" "--devbox-image-tag DEVBOX_IMAGE_TAG"
|
||
printf " Specifies the DevBox container image tag. Default is latest.\n"
|
||
printf " %s\n" "Default: latest"
|
||
echo
|
||
|
||
# :flag.usage working home
|
||
printf " %s\n" "--working-home WORKING_HOME"
|
||
printf " Specifies the working home of DevBox CLI. Default is ${HOME}/.devbox.\n"
|
||
echo
|
||
|
||
# :flag.usage freeleaps username
|
||
printf " %s\n" "--freeleaps-username FREELEAPS_USERNAME (required)"
|
||
printf " Specifies the Freeleaps.com repository username (Required).\n"
|
||
echo
|
||
|
||
# :flag.usage freeleaps password
|
||
printf " %s\n" "--freeleaps-password FREELEAPS_PASSWORD (required)"
|
||
printf " Specifies the Freeleaps.com password repository (Required).\n"
|
||
echo
|
||
|
||
# :flag.usage use local component
|
||
printf " %s\n" "--use-local-component USE_LOCAL_COMPONENT"
|
||
printf " Check if use local component or use online dev environment. (Default: false, use online service) (Optional)\n"
|
||
echo
|
||
|
||
# :flag.usage devsvc image repo
|
||
printf " %s\n" "--devsvc-image-repo DEVSVC_IMAGE_REPO"
|
||
printf " Specifies the repository for devsvc component. (Optional)\n"
|
||
echo
|
||
|
||
# :flag.usage devsvc image name
|
||
printf " %s\n" "--devsvc-image-name DEVSVC_IMAGE_NAME"
|
||
printf " Specifies the image name for devsvc component. (Optional)\n"
|
||
echo
|
||
|
||
# :flag.usage devsvc image tag
|
||
printf " %s\n" "--devsvc-image-tag DEVSVC_IMAGE_TAG"
|
||
printf " Specifies the image tag for devsvc component. (Optional, default=latest-)\n"
|
||
printf " %s\n" "Default: latest"
|
||
echo
|
||
|
||
# :flag.usage payment image repo
|
||
printf " %s\n" "--payment-image-repo PAYMENT_IMAGE_REPO"
|
||
printf " Specifies the repository for payment component. (Optional)\n"
|
||
echo
|
||
|
||
# :flag.usage payment image name
|
||
printf " %s\n" "--payment-image-name PAYMENT_IMAGE_NAME"
|
||
printf " Specifies the image name for payment component. (Optional)\n"
|
||
echo
|
||
|
||
# :flag.usage payment image tag
|
||
printf " %s\n" "--payment-image-tag PAYMENT_IMAGE_TAG"
|
||
printf " Specifies the image tag for payment component. (Optional, default=latest)\n"
|
||
printf " %s\n" "Default: latest"
|
||
echo
|
||
|
||
# :flag.usage content image repo
|
||
printf " %s\n" "--content-image-repo CONTENT_IMAGE_REPO"
|
||
printf " Specifies the repository for content component. (Optional)\n"
|
||
echo
|
||
|
||
# :flag.usage content image name
|
||
printf " %s\n" "--content-image-name CONTENT_IMAGE_NAME"
|
||
printf " Specifies the image name for content component. (Optional)\n"
|
||
echo
|
||
|
||
# :flag.usage content image tag
|
||
printf " %s\n" "--content-image-tag CONTENT_IMAGE_TAG"
|
||
printf " Specifies the image tag for content component. (Optional, default=latest)\n"
|
||
printf " %s\n" "Default: latest"
|
||
echo
|
||
|
||
# :flag.usage central storage image repo
|
||
printf " %s\n" "--central_storage-image-repo CENTRAL_STORAGE_IMAGE_REPO"
|
||
printf " Specifies the repository for central_storage component. (Optional)\n"
|
||
echo
|
||
|
||
# :flag.usage central storage image name
|
||
printf " %s\n" "--central_storage-image-name CENTRAL_STORAGE_IMAGE_NAME"
|
||
printf " Specifies the image name for central_storage component. (Optional)\n"
|
||
echo
|
||
|
||
# :flag.usage central storage image tag
|
||
printf " %s\n" "--central_storage-image-tag CENTRAL_STORAGE_IMAGE_TAG"
|
||
printf " Specifies the image tag for central_storage component. (Optional, default=latest)\n"
|
||
printf " %s\n" "Default: latest"
|
||
echo
|
||
|
||
# :flag.usage authentication image repo
|
||
printf " %s\n" "--authentication-image-repo AUTHENTICATION_IMAGE_REPO"
|
||
printf " Specifies the repository for authentication component. (Optional)\n"
|
||
echo
|
||
|
||
# :flag.usage authentication image name
|
||
printf " %s\n" "--authentication-image-name AUTHENTICATION_IMAGE_NAME"
|
||
printf " Specifies the image name for authentication component. (Optional)\n"
|
||
echo
|
||
|
||
# :flag.usage authentication image tag
|
||
printf " %s\n" "--authentication-image-tag AUTHENTICATION_IMAGE_TAG"
|
||
printf " Specifies the image tag for authentication component. (Optional, default=latest)\n"
|
||
printf " %s\n" "Default: latest"
|
||
echo
|
||
|
||
# :flag.usage force
|
||
printf " %s\n" "--force, -f"
|
||
printf " Force initialization even if resources already exist.\n"
|
||
echo
|
||
|
||
# :command.usage_fixed_flags
|
||
printf " %s\n" "--help, -h"
|
||
printf " Show this help\n"
|
||
echo
|
||
|
||
# :command.usage_examples
|
||
printf "%s\n" "Examples:"
|
||
printf " devbox init --os=linux --arch=arm64 --freeleaps-username alice\n --freeleaps-password secret\n"
|
||
printf " devbox init \ --devbox-container-name custom-devbox \ --devbox-container-port\n 22222 \ --freeleaps-username alice \ --freeleaps-password secret\n"
|
||
echo
|
||
|
||
fi
|
||
}
|
||
|
||
# :command.usage
|
||
devbox_deinit_usage() {
|
||
if [[ -n $long_usage ]]; then
|
||
printf "devbox deinit\n\n"
|
||
printf " De-initialize the local development environment based on DevBox container.\n This command will stop and remove all containers, clean up the working \n directory, and reset the environment to the initial state.\n \n Sub-command \`deinit\` uses Docker (or another container runtime) to clean \n up the local DevBox environment for Freeleaps development. \n It follows these major steps:\n 1. Stop and remove all containers.\n 2. Clean up the working directory.\n 3. Reset the environment to the initial state.\n\n"
|
||
else
|
||
printf "devbox deinit - De-initialize the local development environment based on DevBox container.\n\n"
|
||
fi
|
||
printf "Alias: d\n"
|
||
echo
|
||
|
||
printf "%s\n" "Usage:"
|
||
printf " devbox deinit [OPTIONS]\n"
|
||
printf " devbox deinit --help | -h\n"
|
||
echo
|
||
|
||
# :command.long_usage
|
||
if [[ -n "$long_usage" ]]; then
|
||
printf "%s\n" "Options:"
|
||
|
||
# :command.usage_flags
|
||
# :flag.usage
|
||
printf " %s\n" "--working-home WORKING_HOME"
|
||
printf " Specifies the working home of DevBox CLI. Default is ${HOME}/.devbox.\n"
|
||
printf " %s\n" "Default: ${HOME}/.devbox"
|
||
echo
|
||
|
||
# :flag.usage
|
||
printf " %s\n" "--clear-logs CLEAR_LOGS"
|
||
printf " Specifies whether clear log files or not. Default is true.\n"
|
||
printf " %s\n" "Default: true"
|
||
echo
|
||
|
||
# :flag.usage
|
||
printf " %s\n" "--clear-repo CLEAR_REPO"
|
||
printf " Specifies whether delete source repository or not. Default is false.\n"
|
||
printf " %s\n" "Default: false"
|
||
echo
|
||
|
||
# :command.usage_fixed_flags
|
||
printf " %s\n" "--help, -h"
|
||
printf " Show this help\n"
|
||
echo
|
||
|
||
# :command.usage_examples
|
||
printf "%s\n" "Examples:"
|
||
printf " devbox deinit\n"
|
||
printf " devbox deinit --working-home=/tmp/devbox --clear-logs=false --clear-repo=true\n"
|
||
echo
|
||
|
||
fi
|
||
}
|
||
|
||
# :command.usage
|
||
devbox_start_usage() {
|
||
if [[ -n $long_usage ]]; then
|
||
printf "devbox start\n\n"
|
||
printf " Start the local development environment based on DevBox container.\n This command will start all containers, services, and processes that \n are required for Freeleaps development.\n \n Sub-command \`start\` uses Docker (or another container runtime) to start \n the local DevBox environment for Freeleaps development. \n It follows these major steps:\n 1. Start all containers.\n 2. Start all services and processes.\n\n"
|
||
else
|
||
printf "devbox start - Start the local development environment based on DevBox container.\n\n"
|
||
fi
|
||
printf "Alias: s\n"
|
||
echo
|
||
|
||
printf "%s\n" "Usage:"
|
||
printf " devbox start [OPTIONS]\n"
|
||
printf " devbox start --help | -h\n"
|
||
echo
|
||
|
||
# :command.long_usage
|
||
if [[ -n "$long_usage" ]]; then
|
||
printf "%s\n" "Options:"
|
||
|
||
# :command.usage_flags
|
||
# :flag.usage
|
||
printf " %s\n" "--component COMPONENT"
|
||
printf " Specifies the name of the component to start (e.g., mongodb, rabbitmq,\n backend, frontend, devsvc, payment, content, central_storage,\n authentication).\n"
|
||
echo
|
||
|
||
# :command.usage_fixed_flags
|
||
printf " %s\n" "--help, -h"
|
||
printf " Show this help\n"
|
||
echo
|
||
|
||
# :command.usage_examples
|
||
printf "%s\n" "Examples:"
|
||
printf " devbox start\n"
|
||
printf " devbox start --component=backend\n"
|
||
echo
|
||
|
||
fi
|
||
}
|
||
|
||
# :command.usage
|
||
devbox_stop_usage() {
|
||
if [[ -n $long_usage ]]; then
|
||
printf "devbox stop\n\n"
|
||
printf " Stop the local development environment based on DevBox container.\n This command will stop all containers, services, and processes that \n are required for Freeleaps development.\n \n Sub-command \`stop\` uses Docker (or another container runtime) to stop \n the local DevBox environment for Freeleaps development. \n It follows these major steps:\n 1. Stop all containers.\n 2. Stop all services and processes.\n\n"
|
||
else
|
||
printf "devbox stop - Stop the local development environment based on DevBox container.\n\n"
|
||
fi
|
||
printf "Alias: p\n"
|
||
echo
|
||
|
||
printf "%s\n" "Usage:"
|
||
printf " devbox stop [OPTIONS]\n"
|
||
printf " devbox stop --help | -h\n"
|
||
echo
|
||
|
||
# :command.long_usage
|
||
if [[ -n "$long_usage" ]]; then
|
||
printf "%s\n" "Options:"
|
||
|
||
# :command.usage_flags
|
||
# :flag.usage
|
||
printf " %s\n" "--component COMPONENT"
|
||
printf " Specifies the name of the component to stop (e.g., mongodb, rabbitmq,\n backend, frontend, devsvc, payment, content, central_storage,\n authentication).\n"
|
||
echo
|
||
|
||
# :command.usage_fixed_flags
|
||
printf " %s\n" "--help, -h"
|
||
printf " Show this help\n"
|
||
echo
|
||
|
||
# :command.usage_examples
|
||
printf "%s\n" "Examples:"
|
||
printf " devbox stop\n"
|
||
printf " devbox stop --component=backend\n"
|
||
echo
|
||
|
||
fi
|
||
}
|
||
|
||
# :command.usage
|
||
devbox_status_usage() {
|
||
if [[ -n $long_usage ]]; then
|
||
printf "devbox status\n\n"
|
||
printf " Display the status of the local development environment based on DevBox\n container.\n This command will show the status of all containers, services, and processes \n that are required for Freeleaps development.\n \n Sub-command \`status\` uses Docker (or another container runtime) to show \n the status of the local DevBox environment for Freeleaps development. \n It follows these major steps:\n 1. Show the status of all containers.\n 2. Show the status of all services and processes.\n\n"
|
||
else
|
||
printf "devbox status - Display the status of the local development environment based on DevBox container.\n\n"
|
||
fi
|
||
printf "Alias: t\n"
|
||
echo
|
||
|
||
printf "%s\n" "Usage:"
|
||
printf " devbox status\n"
|
||
printf " devbox status --help | -h\n"
|
||
echo
|
||
|
||
# :command.long_usage
|
||
if [[ -n "$long_usage" ]]; then
|
||
printf "%s\n" "Options:"
|
||
|
||
# :command.usage_fixed_flags
|
||
printf " %s\n" "--help, -h"
|
||
printf " Show this help\n"
|
||
echo
|
||
|
||
# :command.usage_examples
|
||
printf "%s\n" "Examples:"
|
||
printf " devbox status\n"
|
||
printf " devbox status --component=backend\n"
|
||
echo
|
||
|
||
fi
|
||
}
|
||
|
||
# :command.usage
|
||
devbox_restart_usage() {
|
||
if [[ -n $long_usage ]]; then
|
||
printf "devbox restart\n\n"
|
||
printf " Restart the local development environment based on DevBox container.\n This command will restart all containers, services, and processes that \n are required for Freeleaps development.\n \n Sub-command \`restart\` uses Docker (or another container runtime) to restart \n the local DevBox environment for Freeleaps development. \n It follows these major steps:\n 1. Stop all containers.\n 2. Start all containers.\n 3. Stop all services and processes.\n 4. Start all services and processes.\n\n"
|
||
else
|
||
printf "devbox restart - Restart the local development environment based on DevBox container.\n\n"
|
||
fi
|
||
printf "Alias: r\n"
|
||
echo
|
||
|
||
printf "%s\n" "Usage:"
|
||
printf " devbox restart\n"
|
||
printf " devbox restart --help | -h\n"
|
||
echo
|
||
|
||
# :command.long_usage
|
||
if [[ -n "$long_usage" ]]; then
|
||
printf "%s\n" "Options:"
|
||
|
||
# :command.usage_fixed_flags
|
||
printf " %s\n" "--help, -h"
|
||
printf " Show this help\n"
|
||
echo
|
||
|
||
# :command.usage_examples
|
||
printf "%s\n" "Examples:"
|
||
printf " devbox restart\n"
|
||
printf " devbox restart --component=backend\n"
|
||
echo
|
||
|
||
fi
|
||
}
|
||
|
||
# :command.normalize_input
|
||
# :command.normalize_input_function
|
||
normalize_input() {
|
||
local arg passthru flags
|
||
passthru=false
|
||
|
||
while [[ $# -gt 0 ]]; do
|
||
arg="$1"
|
||
if [[ $passthru == true ]]; then
|
||
input+=("$arg")
|
||
elif [[ $arg =~ ^(--[a-zA-Z0-9_\-]+)=(.+)$ ]]; then
|
||
input+=("${BASH_REMATCH[1]}")
|
||
input+=("${BASH_REMATCH[2]}")
|
||
elif [[ $arg =~ ^(-[a-zA-Z0-9])=(.+)$ ]]; then
|
||
input+=("${BASH_REMATCH[1]}")
|
||
input+=("${BASH_REMATCH[2]}")
|
||
elif [[ $arg =~ ^-([a-zA-Z0-9][a-zA-Z0-9]+)$ ]]; then
|
||
flags="${BASH_REMATCH[1]}"
|
||
for ((i = 0; i < ${#flags}; i++)); do
|
||
input+=("-${flags:i:1}")
|
||
done
|
||
elif [[ "$arg" == "--" ]]; then
|
||
passthru=true
|
||
input+=("$arg")
|
||
else
|
||
input+=("$arg")
|
||
fi
|
||
|
||
shift
|
||
done
|
||
}
|
||
|
||
# :command.inspect_args
|
||
inspect_args() {
|
||
# Check and output the simulated args associative array (using args_keys and args_values)
|
||
if [ ${#args_keys[@]} -gt 0 ]; then
|
||
# 利用 printf 和 sort 对键进行排序
|
||
sorted_keys=$(printf "%s\n" "${args_keys[@]}" | sort)
|
||
echo "args:"
|
||
for key in $sorted_keys; do
|
||
value=""
|
||
# Find the value based on the key
|
||
for i in `seq 0 $((${#args_keys[@]} - 1))`; do
|
||
if [ "${args_keys[$i]}" = "$key" ]; then
|
||
value="${args_values[$i]}"
|
||
break
|
||
fi
|
||
done
|
||
|
||
done
|
||
else
|
||
echo "args: none"
|
||
fi
|
||
|
||
# Check and output the simulated deps associative array (using deps_keys and deps_values)
|
||
if [ ${#deps_keys[@]} -gt 0 ]; then
|
||
sorted_keys=$(printf "%s\n" "${deps_keys[@]}" | sort)
|
||
echo
|
||
echo "deps:"
|
||
for key in $sorted_keys; do
|
||
value=""
|
||
for i in `seq 0 $((${#deps_keys[@]} - 1))`; do
|
||
if [ "${deps_keys[$i]}" = "$key" ]; then
|
||
value="${deps_values[$i]}"
|
||
break
|
||
fi
|
||
done
|
||
echo "- \$deps[$key] = $value"
|
||
done
|
||
fi
|
||
|
||
# Check and output the simulated env_vars associative array (using env_var_names)
|
||
if [ ${#env_var_names[@]} -gt 0 ]; then
|
||
sorted_names=$(printf "%s\n" "${env_var_names[@]}" | sort)
|
||
echo
|
||
echo "environment variables:"
|
||
for name in $sorted_names; do
|
||
# Look up the value based on the name
|
||
echo "- \$${name} = ${!name:-}"
|
||
done
|
||
fi
|
||
}
|
||
|
||
|
||
install_docker() {
|
||
echo "[INFO] Checking Docker installation..."
|
||
|
||
# Check if Docker CLI is installed
|
||
if ! command -v docker >/dev/null 2>&1; then
|
||
echo "[ERROR] Docker CLI is not installed."
|
||
return 1
|
||
fi
|
||
|
||
echo "[INFO] Docker CLI is installed. Checking daemon..."
|
||
|
||
# Check if Docker daemon is running
|
||
if docker info >/dev/null 2>&1; then
|
||
echo "[OK] Docker daemon is running."
|
||
return 0
|
||
fi
|
||
|
||
# Check if running on WSL
|
||
if grep -qi microsoft /proc/version; then
|
||
echo "[INFO] Detected WSL environment. Skipping service startup."
|
||
if [ -S /var/run/docker.sock ]; then
|
||
echo "[OK] Docker socket found (/var/run/docker.sock)."
|
||
return 0
|
||
else
|
||
echo "[ERROR] Docker socket /var/run/docker.sock not found."
|
||
echo "[SOLUTION] Please start Docker Desktop on Windows and enable WSL integration, then mount /var/run/docker.sock into the container."
|
||
return 1
|
||
fi
|
||
fi
|
||
|
||
# Check if running on macOS
|
||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||
echo "[INFO] Running on Linux. Attempting to start Docker service..."
|
||
if command -v systemctl >/dev/null 2>&1; then
|
||
echo "[INFO] Starting Docker with systemctl..."
|
||
sudo systemctl start docker
|
||
sleep 2
|
||
if systemctl is-active --quiet docker; then
|
||
echo "[OK] Docker service started successfully via systemctl."
|
||
return 0
|
||
else
|
||
echo "[ERROR] Failed to start Docker using systemctl."
|
||
return 1
|
||
fi
|
||
elif command -v service >/dev/null 2>&1; then
|
||
echo "[INFO] systemctl not found, trying to start Docker using service..."
|
||
sudo service docker start
|
||
sleep 2
|
||
if docker info >/dev/null 2>&1; then
|
||
echo "[OK] Docker service started successfully via service command."
|
||
return 0
|
||
else
|
||
echo "[ERROR] Failed to start Docker using service command."
|
||
return 1
|
||
fi
|
||
else
|
||
echo "[ERROR] Neither systemctl nor service command found. Please start Docker manually."
|
||
return 1
|
||
fi
|
||
fi
|
||
|
||
return 1
|
||
}
|
||
|
||
check_docker_running() {
|
||
echo "==> Checking if Docker service is running..."
|
||
|
||
# if Docker CLI is installed and Docker daemon is running
|
||
if docker info >/dev/null 2>&1; then
|
||
echo "==> Docker is running."
|
||
return 0
|
||
fi
|
||
|
||
# if running on WSL, check for Docker socket
|
||
if grep -qi microsoft /proc/version; then
|
||
echo "[INFO] Detected WSL environment. Verifying /var/run/docker.sock..."
|
||
if [ -S /var/run/docker.sock ]; then
|
||
echo "==> Docker socket found. Docker should be available via Docker Desktop."
|
||
return 0
|
||
else
|
||
echo "[ERROR] Docker socket not found in WSL environment."
|
||
return 1
|
||
fi
|
||
fi
|
||
|
||
echo "==> Docker is not running. Attempting to start it..."
|
||
|
||
# Start Docker service using systemctl or service command
|
||
if command -v systemctl &>/dev/null; then
|
||
if systemctl list-units --type=service | grep -q "docker.service"; then
|
||
echo "==> Starting Docker with systemctl..."
|
||
sudo systemctl start docker && echo "==> Docker started successfully." && return 0
|
||
fi
|
||
fi
|
||
|
||
if command -v service &>/dev/null; then
|
||
if service --status-all | grep -q "docker"; then
|
||
echo "==> Starting Docker with service..."
|
||
sudo service docker start && echo "==> Docker started successfully." && return 0
|
||
fi
|
||
fi
|
||
|
||
if command -v snap &>/dev/null && snap list | grep -q "docker"; then
|
||
echo "==> Starting Docker with snap..."
|
||
sudo snap start docker && echo "==> Docker started successfully." && return 0
|
||
fi
|
||
|
||
echo "ERROR: Unable to start Docker automatically. Please start it manually."
|
||
return 1
|
||
}
|
||
|
||
start_local_mongodb() {
|
||
echo "==> Starting MongoDB service..."
|
||
|
||
MONGO_CONTAINER_NAME="freeleaps2-mongodb"
|
||
MONGO_IMAGE="mongo:latest"
|
||
|
||
# if a container with the same name exists, remove it
|
||
if docker ps -a --format '{{.Names}}' | grep -q "^${MONGO_CONTAINER_NAME}\$"; then
|
||
echo "==> Removing existing MongoDB container..."
|
||
docker stop "$MONGO_CONTAINER_NAME" &>/dev/null || true
|
||
docker rm "$MONGO_CONTAINER_NAME" &>/dev/null || true
|
||
fi
|
||
|
||
echo "==> Pulling MongoDB image: $MONGO_IMAGE"
|
||
if ! docker pull "$MONGO_IMAGE"; then
|
||
echo "ERROR: Failed to pull MongoDB image: $MONGO_IMAGE"
|
||
exit 1
|
||
fi
|
||
|
||
echo "==> Starting MongoDB container..."
|
||
mongo_container_id=$(docker run -d --name "$MONGO_CONTAINER_NAME" -p 27017:27017 "$MONGO_IMAGE" mongod --bind_ip_all)
|
||
if [[ -z "$mongo_container_id" ]]; then
|
||
echo "ERROR: Failed to start MongoDB container."
|
||
exit 1
|
||
fi
|
||
echo "MongoDB container started successfully: $mongo_container_id"
|
||
|
||
sleep 10
|
||
|
||
MAX_ATTEMPTS=10
|
||
ATTEMPT=0
|
||
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
|
||
if docker exec "$MONGO_CONTAINER_NAME" mongosh --eval "db.adminCommand('ping')" 2>/dev/null | grep -q '{ ok: 1 }'; then
|
||
echo "MongoDB health check passed."
|
||
break
|
||
fi
|
||
echo "Waiting for MongoDB to be ready... (Attempt $((ATTEMPT+1)))"
|
||
sleep 10
|
||
ATTEMPT=$((ATTEMPT+1))
|
||
done
|
||
|
||
|
||
if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then
|
||
echo "ERROR: MongoDB health check failed."
|
||
exit 1
|
||
fi
|
||
|
||
echo "$mongo_container_id" > "$WORKING_HOME/.mongodb-instance"
|
||
echo "==> Completed MongoDB container..."
|
||
}
|
||
|
||
start_local_rabbitMQ(){
|
||
echo "[INFO] Starting RabbitMQ container..."
|
||
|
||
RABBITMQ_CONTAINER_NAME="freeleaps2"
|
||
RABBITMQ_IMAGE="rabbitmq:latest"
|
||
|
||
# If a container with the same name exists, remove it
|
||
if docker ps -a --format '{{.Names}}' | grep -q "^${RABBITMQ_CONTAINER_NAME}\$"; then
|
||
echo "==> Removing existing RabbitMQ container..."
|
||
docker stop "${RABBITMQ_CONTAINER_NAME}" &>/dev/null || true
|
||
docker rm "${RABBITMQ_CONTAINER_NAME}" &>/dev/null || true
|
||
fi
|
||
|
||
# Pull the RabbitMQ image
|
||
echo "==> Pulling RabbitMQ image: ${RABBITMQ_IMAGE}"
|
||
if ! docker pull "${RABBITMQ_IMAGE}"; then
|
||
echo "ERROR: Failed to pull RabbitMQ image: ${RABBITMQ_IMAGE}"
|
||
exit 1
|
||
fi
|
||
|
||
# Run the RabbitMQ container mapping port 5672
|
||
rabbitmq_container_id=$(docker run -d --name "${RABBITMQ_CONTAINER_NAME}" -p 5672:5672 "${RABBITMQ_IMAGE}")
|
||
|
||
if [[ -z "${rabbitmq_container_id}" ]]; then
|
||
echo "ERROR: Failed to start RabbitMQ container."
|
||
exit 1
|
||
fi
|
||
|
||
echo "RabbitMQ container started successfully: ${rabbitmq_container_id}"
|
||
|
||
# Allow RabbitMQ some time to initialize
|
||
sleep 20
|
||
|
||
# Check RabbitMQ health via rabbitmqctl
|
||
if docker exec "${RABBITMQ_CONTAINER_NAME}" rabbitmqctl status &>/dev/null; then
|
||
echo "RabbitMQ health check passed."
|
||
else
|
||
echo "ERROR: RabbitMQ health check failed."
|
||
exit 1
|
||
fi
|
||
|
||
echo "$rabbitmq_container_id" > "$WORKING_HOME/.rabbitmq-instance"
|
||
|
||
echo "[INFO] Completed RabbitMQ container..."
|
||
}
|
||
|
||
# 定义键和值数组
|
||
local_components_ports_keys=("devsvc" "payment" "content" "central_storage" "authentication")
|
||
local_components_ports_values=("8007" "8006" "8013" "8005" "8004")
|
||
|
||
# 根据组件名查找对应的端口
|
||
get_port() {
|
||
local comp="$1"
|
||
local port=""
|
||
for i in "${!local_components_ports_keys[@]}"; do
|
||
if [ "${local_components_ports_keys[i]}" = "$comp" ]; then
|
||
port="${local_components_ports_values[i]}"
|
||
break
|
||
fi
|
||
done
|
||
echo "$port"
|
||
}
|
||
|
||
# :command.command_functions
|
||
# :command.function
|
||
devbox_init_command() {
|
||
|
||
#!/usr/bin/env bash
|
||
echo "==> [INIT] Starting DevBox environment initialization..."
|
||
echo
|
||
|
||
# -------------------------------------------------------------------
|
||
# 1. Get parameters from command line arguments
|
||
# -------------------------------------------------------------------
|
||
local OS="$args_os" # --os
|
||
local ARCH="$args_arch" # --arch
|
||
local DEVBOX_NAME="$args_devbox_container_name" # --devbox-container-name
|
||
local DEVBOX_PORT="$args_devbox_container_port" # --devbox-container-port
|
||
local DEVBOX_FRONTEND_PORT="$args_devbox_frontend_port" # --devbox-frontend-port
|
||
local DEVBOX_BACKEND_PORT="$args_devbox_backend_port" # --devbox-backend-port
|
||
local DEVBOX_REPO="$args_devbox_image_repo" # --devbox-image-repo
|
||
local DEVBOX_IMAGE="$args_devbox_image_name" # --devbox-image-name
|
||
local DEVBOX_TAG="$args_devbox_image_tag" # --devbox-image-tag
|
||
local WORKING_HOME="${args_working_home:-${WORKING_HOME:-${HOME}/.devbox}}"
|
||
local FREELEAPS_USERNAME="$args_freeleaps_username" # --freeleaps-username
|
||
local FREELEAPS_PASSWORD="$args_freeleaps_password" # --freeleaps-password
|
||
|
||
|
||
local USE_LOCAL_COMPONENT="$args_use_local_component" # --use-local-component
|
||
|
||
local DEVSVC_REPO="$args_devsvc_image_repo" # --devsvc-image-repo
|
||
local DEVSVC_IMAGE="$args_devsvc_image_image" # --devsvc-image-image
|
||
local DEVSVC_TAG="$args_devsvc_image_tag" # --devsvc-image-tag
|
||
|
||
local PAYMENT_REPO="$args_payment_image_repo" # --payment-image-repo
|
||
local PAYMENT_IMAGE="$args_payment_image_image" # --payment-image-image
|
||
local PAYMENT_TAG="$args_payment_image_tag" # --payment-image-tag
|
||
|
||
local CONTENT_REPO="$args_content_image_repo" # --content-image-repo
|
||
local CONTENT_IMAGE="$args_content_image_image" # --content-image-image
|
||
local CONTENT_TAG="$args_content_image_tag" # --content-image-tag
|
||
|
||
local CENTRAL_STORAGE_REPO="$args_central_storage_image_repo" # --central_storage-image-repo
|
||
local CENTRAL_STORAGE_IMAGE="$args_central_storage_image_image" # --central_storage-image-image
|
||
local CENTRAL_STORAGE_TAG="$args_central_storage_image_tag" # --central_storage-image-tag
|
||
|
||
local AUTHENTICATION_REPO="$args_authentication_image_repo" # --authentication-image-repo
|
||
local AUTHENTICATION_IMAGE="$args_authentication_image_image" # --authentication-image-image
|
||
local AUTHENTICATION_TAG="$args_authentication_image_tag" # --authentication-image-tag
|
||
|
||
# --force flag to overwrite existing resources
|
||
local FORCE_INIT="${args_force}"
|
||
|
||
local OS="$(get_arg '--os')"
|
||
local ARCH="$(get_arg '--arch')"
|
||
local DEVBOX_NAME="$(get_arg '--devbox-container-name')"
|
||
local DEVBOX_PORT="$(get_arg '--devbox-container-port')"
|
||
local DEVBOX_FRONTEND_PORT="$(get_arg '--devbox-frontend-port')"
|
||
local DEVBOX_BACKEND_PORT="$(get_arg '--devbox-backend-port')"
|
||
local DEVBOX_REPO="$(get_arg '--devbox-image-repo')"
|
||
local DEVBOX_IMAGE="$(get_arg '--devbox-image-name')"
|
||
local DEVBOX_TAG="$(get_arg '--devbox-image-tag')"
|
||
local WORKING_HOME="$(get_arg '--working-home' "${WORKING_HOME:-${HOME}/.devbox}")"
|
||
local FREELEAPS_USERNAME="$(get_arg '--freeleaps-username')"
|
||
local FREELEAPS_PASSWORD="$(get_arg '--freeleaps-password')"
|
||
local USE_LOCAL_COMPONENT="$(get_arg '--use-local-component')"
|
||
local DEVSVC_REPO="$(get_arg '--devsvc-image-repo')"
|
||
local DEVSVC_IMAGE="$(get_arg '--devsvc-image-name')"
|
||
local DEVSVC_TAG="$(get_arg '--devsvc-image-tag')"
|
||
local PAYMENT_REPO="$(get_arg '--payment-image-repo')"
|
||
local PAYMENT_IMAGE="$(get_arg '--payment-image-name')"
|
||
local PAYMENT_TAG="$(get_arg '--payment-image-tag')"
|
||
local CONTENT_REPO="$(get_arg '--content-image-repo')"
|
||
local CONTENT_IMAGE="$(get_arg '--content-image-name')"
|
||
local CONTENT_TAG="$(get_arg '--content-image-tag')"
|
||
local CENTRAL_STORAGE_REPO="$(get_arg '--central_storage-image-repo')"
|
||
local CENTRAL_STORAGE_IMAGE="$(get_arg '--central_storage-image-name')"
|
||
local CENTRAL_STORAGE_TAG="$(get_arg '--central_storage-image-tag')"
|
||
local AUTHENTICATION_REPO="$(get_arg '--authentication-image-repo')"
|
||
local AUTHENTICATION_IMAGE="$(get_arg '--authentication-image-name')"
|
||
local AUTHENTICATION_TAG="$(get_arg '--authentication-image-tag')"
|
||
local FORCE_INIT="$(get_arg '--force')"
|
||
|
||
local is_pull_all_components=true
|
||
local components=("devsvc" "payment" "content" "central_storage" "authentication")
|
||
|
||
echo "==> Checking parameters..."
|
||
for component in "${components[@]}"; do
|
||
echo "==> Checking ${component} image repo...value: $(get_arg "--${component}-image-repo")"
|
||
# if any component image repo is provided, then don't pull all components
|
||
|
||
if [[ -n "$(get_arg "--${component}-image-repo")" ]]; then
|
||
is_pull_all_components=false
|
||
break
|
||
fi
|
||
done
|
||
echo "==> is_pull_all_components: $is_pull_all_components"
|
||
|
||
echo " ===================================================== "
|
||
|
||
echo "Parameters:"
|
||
echo " OS = $OS"
|
||
echo " ARCH = $ARCH"
|
||
echo " DEVBOX_NAME = $DEVBOX_NAME"
|
||
echo " DEVBOX_PORT = $DEVBOX_PORT"
|
||
echo " DEVBOX_FRONTEND_PORT = $DEVBOX_FRONTEND_PORT"
|
||
echo " DEVBOX_BACKEND_PORT = $DEVBOX_BACKEND_PORT"
|
||
echo " DEVBOX_REPO = $DEVBOX_REPO"
|
||
echo " DEVBOX_IMAGE = $DEVBOX_IMAGE"
|
||
echo " DEVBOX_TAG = $DEVBOX_TAG"
|
||
echo " WORKING_HOME = $WORKING_HOME"
|
||
echo " FREELEAPS_USERNAME= $FREELEAPS_USERNAME"
|
||
echo " (FREELEAPS_PASSWORD is hidden for security)"
|
||
echo " USE_LOCAL_COMPONENT= $USE_LOCAL_COMPONENT"
|
||
echo " DEVSVC_REPO = $DEVSVC_REPO"
|
||
echo " DEVSVC_IMAGE = $DEVSVC_IMAGE"
|
||
echo " DEVSVC_TAG = $DEVSVC_TAG"
|
||
echo " PAYMENT_REPO = $PAYMENT_REPO"
|
||
echo " PAYMENT_IMAGE= $PAYMENT_IMAGE"
|
||
echo " PAYMENT_TAG = $PAYMENT_TAG"
|
||
echo " CONTENT_REPO = $CONTENT_REPO"
|
||
echo " CONTENT_IMAGE = $CONTENT_IMAGE"
|
||
echo " CONTENT_TAG = $CONTENT_TAG"
|
||
echo " CENTRAL_STORAGE_REPO = $CENTRAL_STORAGE_REPO"
|
||
echo " CENTRAL_STORAGE_IMAGE= $CENTRAL_STORAGE_IMAGE"
|
||
echo " CENTRAL_STORAGE_TAG = $CENTRAL_STORAGE_TAG"
|
||
echo " AUTHENTICATION_REPO = $AUTHENTICATION_REPO"
|
||
echo " AUTHENTICATION_IMAGE= $AUTHENTICATION_IMAGE"
|
||
echo " AUTHENTICATION_TAG = $AUTHENTICATION_TAG"
|
||
echo " FORCE_INIT = $FORCE_INIT"
|
||
echo
|
||
|
||
# -------------------------------------------------------------------
|
||
# 2. Check OS/ARCH support
|
||
# (if using auto, detect current system, here just show simple check)
|
||
# -------------------------------------------------------------------
|
||
if [[ "$OS" != "auto" && "$OS" != "linux" && "$OS" != "darwin" && "$OS" != "wsl2" ]]; then
|
||
echo "ERROR: Unsupported OS: $OS"
|
||
exit 1
|
||
fi
|
||
|
||
if [[ "$ARCH" != "auto" && "$ARCH" != "amd64" && "$ARCH" != "arm64" ]]; then
|
||
echo "ERROR: Unsupported architecture: $ARCH"
|
||
exit 1
|
||
fi
|
||
|
||
# Check ARCH match current device
|
||
if [[ "$ARCH" == "auto" ]]; then
|
||
ARCH="$(uname -m)"
|
||
if [[ "$ARCH" == "x86_64" ]]; then
|
||
ARCH="amd64"
|
||
elif [[ "$ARCH" == "aarch64" ]]; then
|
||
ARCH="arm64"
|
||
else
|
||
echo "ERROR: Unsupported architecture: $ARCH"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
echo "==> Detected OS: $OS, ARCH: $ARCH"
|
||
|
||
# Default arch tag value if Arch is amd64 then latest-linux-amd64 else latest-linux-arm64
|
||
local arch_tag="latest-linux-${ARCH}"
|
||
|
||
# -------------------------------------------------------------------
|
||
# 3. Check environment requirements
|
||
# -------------------------------------------------------------------
|
||
# 3.1 Docker Check
|
||
if ! command -v docker &>/dev/null; then
|
||
echo "ERROR: docker is not installed or not in PATH."
|
||
exit 1
|
||
fi
|
||
|
||
# 3.2 Check disk space
|
||
local free_space_kb
|
||
free_space_kb="$(df -Pk "$HOME" | awk 'END{print $4}')"
|
||
# 若无法获取或小于 10GB (10485760 KB),报错
|
||
if [[ -z "$free_space_kb" || $free_space_kb -lt 10485760 ]]; then
|
||
echo "ERROR: Insufficient disk space (need >10GB)."
|
||
exit 1
|
||
fi
|
||
|
||
# 3.3 WORKING_HOME Check
|
||
if ! mkdir -p "$WORKING_HOME" 2>/dev/null; then
|
||
echo "ERROR: Can't create or write to WORKING_HOME: $WORKING_HOME"
|
||
exit 1
|
||
fi
|
||
|
||
# 3.4 Network to docker.com(sample:ping docker.com)
|
||
if ! ping -c 1 docker.com &>/dev/null; then
|
||
echo "ERROR: Network unreachable."
|
||
exit 1
|
||
fi
|
||
|
||
# -------------------------------------------------------------------
|
||
# 4. If .devbox-instance exists, --force,use it
|
||
# -------------------------------------------------------------------
|
||
if [[ -f "$WORKING_HOME/.devbox-instance" && -z "$FORCE_INIT" ]]; then
|
||
echo "ERROR: DevBox already initialized. Use --force to overwrite."
|
||
exit 1
|
||
fi
|
||
|
||
|
||
# -------------------------------------------------------------------
|
||
# 5.install docker and check docker running
|
||
# -------------------------------------------------------------------
|
||
if ! install_docker; then
|
||
echo "ERROR: Failed to install Docker or Docker service is not running."
|
||
exit 1
|
||
fi
|
||
|
||
if ! check_docker_running; then
|
||
echo "ERROR: Docker service is not running."
|
||
exit 1
|
||
fi
|
||
|
||
|
||
# 如有 --force 且存在旧容器,则可在此删除旧容器/文件(也可在下面先检查容器再删)
|
||
# ...
|
||
|
||
# -------------------------------------------------------------------
|
||
# 5.1 pull and start DevBox container
|
||
# -------------------------------------------------------------------
|
||
local devbox_full_image="${DEVBOX_REPO}/${DEVBOX_IMAGE}:${DEVBOX_TAG}"
|
||
echo "==> Pulling DevBox image: $devbox_full_image"
|
||
if ! docker pull "$devbox_full_image"; then
|
||
echo "ERROR: Failed to pull DevBox image: $devbox_full_image"
|
||
exit 1
|
||
fi
|
||
|
||
# If container with same name exists, remove it
|
||
if docker ps -a --format '{{.Names}}' | grep -q "^${DEVBOX_NAME}\$"; then
|
||
if [[ -n "$FORCE_INIT" ]]; then
|
||
echo "==> Removing existing container named $DEVBOX_NAME ..."
|
||
docker stop "$DEVBOX_NAME" &>/dev/null || true
|
||
docker rm "$DEVBOX_NAME" &>/dev/null || true
|
||
else
|
||
echo "ERROR: Container named $DEVBOX_NAME already exists. Use --force to remove it."
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
|
||
# Create and start DevBox container
|
||
local container_id
|
||
container_id="$(
|
||
docker run -d \
|
||
--name "$DEVBOX_NAME" \
|
||
-p "${DEVBOX_PORT}:22" \
|
||
-p "${DEVBOX_FRONTEND_PORT}:5173" \
|
||
-p "${DEVBOX_BACKEND_PORT}:8002" \
|
||
-v "$WORKING_HOME:/home/.devbox" \
|
||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||
"$devbox_full_image" 2>/dev/null
|
||
)"
|
||
|
||
if [[ -z "$container_id" ]]; then
|
||
echo "ERROR: Failed to create DevBox container."
|
||
exit 1
|
||
fi
|
||
|
||
# record container id, DEVBOX_FRONTEND_PORT, DEVBOX_BACKEND_PORT
|
||
echo "$container_id" > "$WORKING_HOME/.devbox-instance"
|
||
echo "$DEVBOX_FRONTEND_PORT" > "$WORKING_HOME/.devbox-frontend-port"
|
||
echo "$DEVBOX_BACKEND_PORT" > "$WORKING_HOME/.devbox-backend-port"
|
||
|
||
# -------------------------------------------------------------------
|
||
# 6. linbwang: pull and start other components
|
||
# -------------------------------------------------------------------
|
||
|
||
echo "==> [INIT] Starting Freeleaps services... Use Local component $USE_LOCAL_COMPONENT"
|
||
|
||
if [[ "$(lower "$USE_LOCAL_COMPONENT")" == "true" ]]; then
|
||
# 3.Create and start MongoDB container
|
||
echo "Step 3. [INFO] Starting MongoDB container..."
|
||
|
||
start_local_mongodb
|
||
|
||
# 4. Pull and start RabbitMQ container
|
||
start_local_rabbitMQ
|
||
|
||
echo ' ===> Using local components for Freeleaps services.'
|
||
|
||
# Local components for Freeleaps services (devsvc, payment, content, central_storage, authentication)
|
||
for component in "${components[@]}"; do
|
||
repo_var="$(upper "$component")_REPO"
|
||
image_var="$(upper "$component")_IMAGE"
|
||
tag_var="$(upper "$component")_TAG"
|
||
|
||
|
||
# Get the component's repo, image, and tag
|
||
COMPONENT_REPO="${!repo_var}"
|
||
COMPONENT_IMAGE="${!image_var}"
|
||
COMPONENT_TAG="${!tag_var}"
|
||
|
||
echo "Component: $component"
|
||
echo " Repo: $COMPONENT_REPO"
|
||
echo " Image: $COMPONENT_IMAGE"
|
||
echo " Tag: $COMPONENT_TAG"
|
||
|
||
# check if is_pull_all_components is false and component repo and component image parameter not empty
|
||
if [[ "$is_pull_all_components" == false && -n "${!COMPONENT_REPO}" && -n "${!COMPONENT_IMAGE}" ]]; then
|
||
echo "==> Using local components for Freeleaps services. For $component, COMPONENT_REPO - '$COMPONENT_REPO', COMPONENT_IMAGE - '$COMPONENT_IMAGE'"
|
||
continue
|
||
fi
|
||
|
||
component_full_image=""
|
||
|
||
if [[ "$is_pull_all_components" == true ]]; then
|
||
component_full_image="docker.io/freeleaps/$component:$arch_tag"
|
||
else
|
||
component_full_image="${!COMPONENT_REPO}/${!COMPONENT_IMAGE}:${!COMPONENT_TAG}"
|
||
fi
|
||
|
||
echo "==> Pulling ${component} image: $component_full_image"
|
||
if ! docker pull "$component_full_image"; then
|
||
echo "WARNING: Failed to pull ${component} image: $component_full_image, please Check the image and specify it to initialize the component."
|
||
fi
|
||
|
||
# if container with same name exists, remove it
|
||
if docker ps -a --format '{{.Names}}' | grep -q "^${component}\$"; then
|
||
if [[ -n "$FORCE_INIT" ]]; then
|
||
echo "==> Removing existing container named $component ..."
|
||
docker stop "$component" &>/dev/null || true
|
||
docker rm "$component" &>/dev/null || true
|
||
else
|
||
echo "WARNING: Container named $component already exists. Use --force to remove it."
|
||
fi
|
||
fi
|
||
|
||
DEFAULT_IP=$(docker network inspect bridge | grep -m1 '"Gateway":' | sed -E 's/.*"Gateway": "([^"]+)".*/\1/')
|
||
echo "Default gateway IP: $DEFAULT_IP"
|
||
|
||
port=$(get_port $component)
|
||
echo "==> Creating and starting ${component} container... ${port}"
|
||
local component_container_id
|
||
component_container_id="$(
|
||
docker run -d \
|
||
--name "$component" \
|
||
--link "$DEVBOX_NAME" \
|
||
-p "${port}:${port}" \
|
||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||
-e SERVICE_API_ACCESS_PORT=${port} \
|
||
-e SERVICE_API_ACCESS_HOST=0.0.0.0 \
|
||
-e MONGODB_URI="mongodb://$DEFAULT_IP:27017" \
|
||
"$component_full_image" \
|
||
uvicorn webapi.main:app --reload --port ${port} --host 0.0.0.0 2>/dev/null
|
||
)"
|
||
if [[ -z "$component_container_id" ]]; then
|
||
echo "WARNING: Failed to create ${component} container. please Check the image and specify it to initialize the component."
|
||
fi
|
||
|
||
echo "$component_container_id" > "$WORKING_HOME/.${component}-instance"
|
||
|
||
echo "${component} container created: $component_container_id"
|
||
done
|
||
else
|
||
echo '============================================'
|
||
echo ' ===> Using online components for Freeleaps services.'
|
||
echo '============================================'
|
||
fi
|
||
|
||
pushd $WORKING_HOME
|
||
|
||
# Check if freeleaps2-frontend exists, if not git clone it
|
||
if [ ! -d $WORKING_HOME/freeleaps ]; then
|
||
echo "Git cloning freeleaps.com:3443/products/freeleaps.git"
|
||
FRONTEND_GIT_URL="https://$FREELEAPS_USERNAME:$FREELEAPS_PASSWORD@freeleaps.com:3443/products/freeleaps.git"
|
||
git clone --depth 5 $FRONTEND_GIT_URL
|
||
else
|
||
pushd $WORKING_HOME/freeleaps
|
||
pwd
|
||
ls -la
|
||
echo "Git pulling freeleaps.com:3443/products/freeleaps.git"
|
||
git pull
|
||
fi
|
||
|
||
# Run banckend service and frontend service in the container
|
||
docker exec -i "$DEVBOX_NAME" bash <<EOF
|
||
# Set environment variables
|
||
|
||
export FREELEAPS_USERNAME="${FREELEAPS_USERNAME}"
|
||
export FREELEAPS_PASSWORD="${FREELEAPS_PASSWORD}"
|
||
export USE_LOCAL_COMPONENT="${USE_LOCAL_COMPONENT}"
|
||
export DEVBOX_BACKEND_PORT="${DEVBOX_BACKEND_PORT}"
|
||
export DEVBOX_FRONTEND_PORT="${DEVBOX_FRONTEND_PORT}"
|
||
|
||
|
||
# Check if useing local component and update /home/.devbox/freeleaps/.dev.env
|
||
echo "step 2: Update /home/.devbox/freeleaps/apps/.env"
|
||
# Get default IP address
|
||
|
||
DEFAULT_IP=\$(ip route | grep default | sed -n 's/.*default via \([^ ]*\).*/\1/p')
|
||
if [[ "\$(lower "\$USE_LOCAL_COMPONENT")" == "true" ]]; then
|
||
echo "==> Using local components"
|
||
# Local components for Freeleaps services (devsvc, payment, content, central_storage, authentication)
|
||
cat << 'EOFinner' > /home/.devbox/freeleaps/apps/.env
|
||
# Online endpoint info
|
||
export MONGODB_NAME=freeleaps2
|
||
export MONGODB_URI=mongodb://\$DEFAULT_IP:27017/
|
||
export MONGODB_PORT=27017
|
||
export BLOB_STORE_CONNECTION_STR="DefaultEndpointsProtocol=https;AccountName=freeleaps1static;AccountKey=SIk7S3RviJxl1XhGiDZKA3cvzfxNrSbsBMfJ3EbKTsKPeMwhy8FTLpJliRLzQVE6uaSX8giDYw2h+ASt5MmHxQ==;EndpointSuffix=core.windows.net"
|
||
export RABBITMQ_HOSTNAME=freeleaps2
|
||
export RABBITMQ_HOST=\$DEFAULT_IP
|
||
export RABBITMQ_PORT=5672
|
||
export FREELEAPS_ENV=dev
|
||
export STRIPE_API_KEY=sk_test_51Ogsw5B0IyqaSJBrwczlr820jnmvA1qQQGoLZ2XxOsIzikpmXo4pRLjw4XVMTEBR8DdVTYySiAv1XX53Zv5xqynF00GfMqttFd
|
||
export STRIPE_WEBHOOK_SECRET=whsec_S6ZWjSAdR5Cpsn2USH6ZRBqbdBIENjTC
|
||
export STRIPE_ACCOUNT_WEBHOOK_SECRET=whsec_PgPnkWGhEUiQfnV8aIb5Wmruz7XETJLm
|
||
export SITE_URL_ROOT=http://\$DEFAULT_IP/
|
||
export FREELEAPS_DEVSVC_ENDPOINT=http://\$DEFAULT_IP:8007/api/devsvc/
|
||
export FREELEAPS_CONTENT_ENDPOINT=http://\$DEFAULT_IP:8013/api/content/
|
||
export FREELEAPS_PAYMENT_ENDPOINT=http://\$DEFAULT_IP:8006/api/payment/
|
||
export FREELEAPS_CENTRAL_STORAGE_ENDPOINT=http://\$DEFAULT_IP:8005/api/central_storage/
|
||
export FREELEAPS_AUTHENTICATION_ENDPOINT=http://\$DEFAULT_IP:8004/api/auth/
|
||
export FREELEAPS_AILAB_ENDPOINT=https://as010-w2-re-vm.mathmast.com:8009/api/
|
||
export KAFKA_SERVER_URL=''
|
||
export EMAIL_FROM=freeleaps@freeleaps.com
|
||
EOFinner
|
||
else
|
||
cat << 'EOFinner' > /home/.devbox/freeleaps/apps/.env
|
||
# Online endpoint info
|
||
export MONGODB_NAME=freeleaps2
|
||
export MONGODB_PORT=27017
|
||
export MONGODB_URI='mongodb+srv://jetli:8IHKx6dZK8BfugGp@freeleaps2.hanbj.mongodb.net/'
|
||
export RABBITMQ_HOSTNAME=freeleaps2
|
||
export RABBITMQ_HOST=52.149.35.244
|
||
export RABBITMQ_PORT=5672
|
||
export FREELEAPS_ENV=dev
|
||
export STRIPE_API_KEY=sk_test_51Ogsw5B0IyqaSJBrwczlr820jnmvA1qQQGoLZ2XxOsIzikpmXo4pRLjw4XVMTEBR8DdVTYySiAv1XX53Zv5xqynF00GfMqttFd
|
||
export STRIPE_WEBHOOK_SECRET=whsec_S6ZWjSAdR5Cpsn2USH6ZRBqbdBIENjTC
|
||
export STRIPE_ACCOUNT_WEBHOOK_SECRET=whsec_PgPnkWGhEUiQfnV8aIb5Wmruz7XETJLm
|
||
export SITE_URL_ROOT=http://localhost/
|
||
export FREELEAPS_DEVSVC_ENDPOINT=http://52.149.3.85:8007/api/devsvc/
|
||
export FREELEAPS_CONTENT_ENDPOINT=http://52.149.35.244:8013/api/content/
|
||
export FREELEAPS_PAYMENT_ENDPOINT=http://52.149.35.244:8006/api/payment/
|
||
export FREELEAPS_CENTRAL_STORAGE_ENDPOINT=http://52.149.35.244:8005/api/central_storage/
|
||
export FREELEAPS_AUTHENTICATION_ENDPOINT=http://52.149.35.244:8004/api/auth/
|
||
export FREELEAPS_AILAB_ENDPOINT=https://as010-w2-re-vm.mathmast.com:8009/api/
|
||
export KAFKA_SERVER_URL=''
|
||
export EMAIL_FROM=freeleaps@freeleaps.com
|
||
EOFinner
|
||
fi
|
||
|
||
# Effect the environment variables in the current shell
|
||
|
||
source /home/.devbox/freeleaps/apps/.env
|
||
|
||
# Ensure /home/.devbox/logs exists
|
||
mkdir -p /home/.devbox/logs
|
||
|
||
# Start WebAPI service
|
||
echo "Starting WebAPI service..."
|
||
pushd /home/.devbox/freeleaps/apps
|
||
cp /home/.devbox/freeleaps/backend_env.sh /home/.devbox/freeleaps/apps/backend_env.sh
|
||
|
||
# 5. Istall python3.10 and venv module
|
||
echo "5. Istall python3.10 and venv module"
|
||
sudo apt update
|
||
sudo apt install python3.10 python3.10-venv -y
|
||
|
||
# make sore python3.10 is installed
|
||
if ! command -v python3.10 &>/dev/null; then
|
||
echo "ERROR: Python3.10 is not installed."
|
||
exit 1
|
||
fi
|
||
|
||
# Upgrade pip and install virtualenv
|
||
echo "7. Upgrade pip and install virtualenv"
|
||
python3.10 -m ensurepip --upgrade
|
||
python3.10 -m pip install --upgrade pip
|
||
|
||
# 8. Create and activate a virtual environment
|
||
echo "8. Create and activate a virtual environment"
|
||
python3.10 -m venv venv_t
|
||
|
||
sleep 5
|
||
|
||
# CHeck if the virtual environment is created
|
||
if [ ! -f "venv_t/bin/activate" ]; then
|
||
echo "ERROR: The virtual environment cannot be created"
|
||
exit 1
|
||
fi
|
||
|
||
echo '============================================'
|
||
echo ' Start to activate virtual environment'
|
||
echo '============================================'
|
||
source venv_t/bin/activate
|
||
source /home/.devbox/freeleaps/apps/.env
|
||
|
||
# Verify the virtual environment is activated
|
||
if [[ "\$VIRTUAL_ENV" != "" ]]; then
|
||
echo "Virtual environment activate: \$VIRTUAL_ENV"
|
||
else
|
||
echo "ERROR: The virtual environment cannot be startup \$VIRTUAL_ENV"
|
||
exit 1
|
||
fi
|
||
|
||
echo '============================================'
|
||
echo ' Install requirements'
|
||
echo '============================================'
|
||
pip install -r /home/.devbox/freeleaps/apps/requirements.txt
|
||
|
||
echo '============================================'
|
||
echo 'Start to run start_webapi.sh'
|
||
echo '============================================'
|
||
./start_webapi.sh > /home/.devbox/logs/backend.logs 2>&1 &
|
||
BACKEND_PID=\$!
|
||
|
||
# Save BACKEND_PID to a file \${WORKING_HOME}/.backend.pid: Stores the process id of backend process.
|
||
echo "\$BACKEND_PID" > /home/.devbox/.backend.pid
|
||
|
||
echo '============================================'
|
||
echo 'Check if the WebAPI service started successfully'
|
||
echo '============================================'
|
||
|
||
sleep 30
|
||
|
||
# 30 attempts, 5 seconds each, total wait time 2.5 minutes
|
||
MAX_ATTEMPTS=30
|
||
ATTEMPT=0
|
||
|
||
echo "Waiting for WebAPI service to become healthy..."
|
||
|
||
while [ \$ATTEMPT -lt \$MAX_ATTEMPTS ]; do
|
||
HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$DEVBOX_BACKEND_PORT/docs")
|
||
# Check HTTP Code 200
|
||
if [ "\$HTTP_CODE" -eq 200 ]; then
|
||
echo "Backend Swagger UI is available at \$URL (HTTP \$HTTP_CODE)"
|
||
break
|
||
else
|
||
echo "Waiting for Swagger UI to become available... Attempt \$((ATTEMPT+1))"
|
||
ATTEMPT=\$((ATTEMPT+1))
|
||
sleep 5 # Wait 5 seconds
|
||
fi
|
||
done
|
||
|
||
if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then
|
||
echo "ERROR: WebAPI failed to start after \$MAX_ATTEMPTS attempts"
|
||
exit 1
|
||
fi
|
||
|
||
|
||
echo '============================================'
|
||
echo ' Start frontend service locally'
|
||
echo '============================================'
|
||
pushd /home/.devbox/freeleaps/frontend
|
||
|
||
# start the frontend service
|
||
export VITE_API_URL='http://127.0.0.1:8002'
|
||
export VITE_WEBSOCKET_URL='http://127.0.0.1:8002'
|
||
npm install
|
||
|
||
npm update
|
||
|
||
npm install -g pnpm
|
||
pnpm install
|
||
npm run build
|
||
npm run format
|
||
# Start the frontend service with nohup in order to keep it running after the SSH session is closed. Save the process ID of the frontend service
|
||
nohup npm run dev > /home/.devbox/logs/frontend.logs 2>&1 &
|
||
FRONTEND_PID=\$!
|
||
|
||
echo "npm run dev has been started with PID: \$FRONTEND_PID"
|
||
echo "\$FRONTEND_PID" > /home/.devbox/.frontend.pid
|
||
|
||
|
||
echo '============================================'
|
||
|
||
# Wait for the frontend service to start
|
||
sleep 30
|
||
|
||
# 30 attempts, 10 seconds each, total wait time 5 minutes
|
||
MAX_ATTEMPTS=30
|
||
ATTEMPT=0
|
||
|
||
echo "Waiting for Frontend service to start..."
|
||
|
||
while [ \$ATTEMPT -lt \$MAX_ATTEMPTS ]; do
|
||
HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$DEVBOX_FRONTEND_PORT/")
|
||
# Check HTTP Code 200
|
||
if [ "\$HTTP_CODE" -eq 200 ]; then
|
||
echo "Frontend is available (HTTP \$HTTP_CODE)"
|
||
break
|
||
else
|
||
echo "Waiting for Frontend to become available... (http://localhost:\$DEVBOX_FRONTEND_PORT), (HTTP \$HTTP_CODE) Attempt \$((ATTEMPT+1))"
|
||
ATTEMPT=\$((ATTEMPT+1))
|
||
sleep 10
|
||
fi
|
||
done
|
||
|
||
if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then
|
||
echo "ERROR: Frontend failed to start after \$MAX_ATTEMPTS attempts"
|
||
exit 1
|
||
fi
|
||
|
||
|
||
echo "Freeleaps services started successfully"
|
||
EOF
|
||
|
||
|
||
# -------------------------------------------------------------------
|
||
# 10. Final notification
|
||
# -------------------------------------------------------------------
|
||
echo
|
||
echo "==========================================================="
|
||
echo "DevBox init completed successfully!"
|
||
echo " DevBox container ID: $container_id"
|
||
[[ -f "${WORKING_HOME}/.devbox-instance" ]] && echo " devbox container ID: $(cat "${WORKING_HOME}/.devbox-instance")"
|
||
echo " Repository cloned to: $WORKING_HOME/freeleaps"
|
||
echo " Backend logs: $WORKING_HOME/logs/backend.logs"
|
||
echo " Frontend logs: $WORKING_HOME/logs/frontend.logs"
|
||
echo " Backend PID: $WORKING_HOME/.backend.pid"
|
||
echo " Frontend PID: $WORKING_HOME/.frontend.pid"
|
||
echo "==========================================================="
|
||
echo
|
||
|
||
}
|
||
|
||
|
||
# :command.function
|
||
devbox_deinit_command() {
|
||
|
||
# src/deinit_command.sh
|
||
echo "# It contains the implementation for the 'devbox deinit' command."
|
||
local WORKING_HOME="$(get_arg '--working-home' "${HOME}/.devbox")"
|
||
local CLEAR_LOGS="$(get_arg '--clear-logs')"
|
||
local CLEAR_REPO="$(get_arg '--clear-repo')"
|
||
|
||
local FORCE="$(get_arg '--force')"
|
||
|
||
# print the parameters
|
||
echo "==> Deinitialization parameters:"
|
||
echo " WORKING_HOME = $WORKING_HOME"
|
||
echo " CLEAR_LOGS = $CLEAR_LOGS"
|
||
echo " CLEAR_REPO = $CLEAR_REPO"
|
||
echo " FORCE = $FORCE"
|
||
|
||
echo "==> Starting DevBox deinitialization..."
|
||
|
||
# Clear the DevBox container logs
|
||
if [[ "$CLEAR_LOGS" == "true" ]]; then
|
||
echo "==> Clearing logs in $WORKING_HOME/logs..."
|
||
rm -rf "$WORKING_HOME/logs"/* 2>/dev/null || true
|
||
else
|
||
echo "==> Skipping log clearing."
|
||
fi
|
||
|
||
# Clear the source repository
|
||
if [[ "$CLEAR_REPO" == "true" && -d "$WORKING_HOME/freeleaps" ]]; then
|
||
echo "==> Deleting source repository at $WORKING_HOME/freeleaps"
|
||
rm -rf "$WORKING_HOME/freeleaps"
|
||
else
|
||
echo "==> Skipping repository deletion."
|
||
fi
|
||
|
||
# Stop and remove DevBox container
|
||
if [[ -f "$WORKING_HOME/.devbox-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "$WORKING_HOME/.devbox-instance")
|
||
echo "==> Stopping and removing DevBox container: $container_id"
|
||
docker stop "$container_id" &>/dev/null || true
|
||
docker rm "$container_id" &>/dev/null || true
|
||
rm -f "$WORKING_HOME/.devbox-instance"
|
||
|
||
# Remove the frontend and backend ports if the file exists
|
||
rm -f "$WORKING_HOME/.devbox-frontend-port"
|
||
rm -f "$WORKING_HOME/.devbox-backend-port"
|
||
|
||
# Remove the backend and frontend process IDs
|
||
rm -f "$WORKING_HOME/.backend.pid"
|
||
rm -f "$WORKING_HOME/.frontend.pid"
|
||
fi
|
||
|
||
# Stop and remove MongoDB container
|
||
if [[ -f "$WORKING_HOME/.mongodb-instance" ]]; then
|
||
local mongodb_container_id
|
||
mongodb_container_id=$(cat "$WORKING_HOME/.mongodb-instance")
|
||
echo "==> Stopping and removing MongoDB container: $mongodb_container_id"
|
||
docker stop "$mongodb_container_id" &>/dev/null || true
|
||
docker rm "$mongodb_container_id" &>/dev/null || true
|
||
rm -f "$WORKING_HOME/.mongodb-instance"
|
||
fi
|
||
|
||
# Stop and remove RabbitMQ container
|
||
if [[ -f "$WORKING_HOME/.rabbitmq-instance" ]]; then
|
||
local rabbitmq_container_id
|
||
rabbitmq_container_id=$(cat "$WORKING_HOME/.rabbitmq-instance")
|
||
echo "==> Stopping and removing RabbitMQ container: $rabbitmq_container_id"
|
||
docker stop "$rabbitmq_container_id" &>/dev/null || true
|
||
docker rm "$rabbitmq_container_id" &>/dev/null || true
|
||
rm -f "$WORKING_HOME/.rabbitmq-instance"
|
||
fi
|
||
|
||
# Stop and remove other components
|
||
local components=("devsvc" "payment" "content" "central_storage" "authentication")
|
||
for component in "${components[@]}"; do
|
||
if [[ -f "$WORKING_HOME/.${component}-instance" ]]; then
|
||
local component_container_id
|
||
component_container_id=$(cat "$WORKING_HOME/.${component}-instance")
|
||
echo "==> Stopping and removing ${component} container: $component_container_id"
|
||
docker stop "$component_container_id" &>/dev/null || true
|
||
docker rm "$component_container_id" &>/dev/null || true
|
||
rm -f "$WORKING_HOME/.${component}-instance"
|
||
fi
|
||
done
|
||
|
||
echo "==> DevBox deinitialization completed."
|
||
}
|
||
|
||
# :command.function
|
||
devbox_start_command() {
|
||
|
||
local COMPONENT="$(get_arg '--component')"
|
||
local WORKING_HOME="$(get_arg '--working-home' "${HOME}/.devbox")"
|
||
|
||
# Check if the DevBox container is running
|
||
local devbox_container_id_file_path="${WORKING_HOME}/.devbox-instance"
|
||
if [[ ! -f "$devbox_container_id_file_path" ]]; then
|
||
echo "ERROR: DevBox container is not running. Please run 'devbox init' first."
|
||
exit 1
|
||
fi
|
||
|
||
local devbox_container_id=$(cat "$devbox_container_id_file_path")
|
||
|
||
echo "==> Starting DevBox services..."
|
||
|
||
# Check if DevBox container is running
|
||
if ! docker ps --no-trunc --format '{{.ID}}' | grep -q "^${devbox_container_id}\$"; then
|
||
echo "==> DevBox container is not running, starting container..."
|
||
# Start the container
|
||
if ! docker start "${devbox_container_id}"; then
|
||
echo "ERROR: Failed to start DevBox container."
|
||
exit 1
|
||
fi
|
||
echo "==> DevBox container started successfully."
|
||
else
|
||
echo "==> DevBox container is already running."
|
||
fi
|
||
|
||
# If no component is specified, start all components
|
||
if [[ -z "$COMPONENT" ]]; then
|
||
COMPONENTS=("mongodb" "rabbitmq" "backend" "frontend" "devsvc" "payment" "content" "central_storage" "authentication")
|
||
else
|
||
COMPONENTS=("$COMPONENT")
|
||
fi
|
||
|
||
# Start the specified components
|
||
for comp in "${COMPONENTS[@]}"; do
|
||
case "$comp" in
|
||
"mongodb")
|
||
echo "==> Starting MongoDB..."
|
||
# Check if MongoDB container file path
|
||
local mongodb_container_id_file_path="${WORKING_HOME}/.mongodb-instance"
|
||
if [[ ! -f "$mongodb_container_id_file_path" ]]; then
|
||
echo "ERROR: MongoDB container is not running. Please run 'devbox init' first."
|
||
else
|
||
local mongodb_container_id=$(cat "$mongodb_container_id_file_path")
|
||
if ! docker ps --no-trunc --format '{{.ID}}' | grep -q "^${mongodb_container_id}\$"; then
|
||
echo "==> MongoDB container is not running, starting container..."
|
||
# Start the container
|
||
if ! docker start "${mongodb_container_id}"; then
|
||
echo "ERROR: Failed to start MongoDB container."
|
||
exit 1
|
||
fi
|
||
echo "==> MongoDB container started successfully."
|
||
else
|
||
echo "==> MongoDB container is already running."
|
||
fi
|
||
fi
|
||
;;
|
||
"rabbitmq")
|
||
echo "==> Starting RabbitMQ..."
|
||
# Check if RabbitMQ container file path
|
||
local rabbitmq_container_id_file_path="${WORKING_HOME}/.rabbitmq-instance"
|
||
if [[ ! -f "$rabbitmq_container_id_file_path" ]]; then
|
||
echo "ERROR: RabbitMQ container is not running. Please run 'devbox init' first."
|
||
else
|
||
local rabbitmq_container_id=$(cat "$rabbitmq_container_id_file_path")
|
||
if ! docker ps --no-trunc --format '{{.ID}}' | grep -q "^${rabbitmq_container_id}\$"; then
|
||
echo "==> RabbitMQ container is not running, starting container..."
|
||
# Start the container
|
||
if ! docker start "${rabbitmq_container_id}"; then
|
||
echo "ERROR: Failed to start RabbitMQ container."
|
||
exit 1
|
||
fi
|
||
echo "==> RabbitMQ container started successfully."
|
||
else
|
||
echo "==> RabbitMQ container is already running."
|
||
fi
|
||
fi
|
||
;;
|
||
"backend")
|
||
echo "==> Starting backend service..."
|
||
# start the backend service
|
||
docker exec -i "$devbox_container_id" bash <<EOF
|
||
# Start the backend service
|
||
echo "Starting backend service..."
|
||
|
||
# Check if /home/.devbox/.backend.pid exists, if not exists, ask for executing devbox init first
|
||
if [ ! -f /home/.devbox/.backend.pid ]; then
|
||
echo "ERROR: Backend service is not running. Please run 'devbox init' first."
|
||
exit 1
|
||
fi
|
||
|
||
echo "Checking if the backend service is already running..."
|
||
|
||
backend_pid=\$(cat /home/.devbox/.backend.pid)
|
||
|
||
echo "Backend PID: \$backend_pid"
|
||
|
||
if ps -p "\$backend_pid" > /dev/null; then
|
||
echo "Backend service is already running."
|
||
else
|
||
# Remove the .backend.pid file
|
||
rm -f /home/.devbox/.backend.pid
|
||
|
||
echo '============================================'
|
||
echo 'Start to run start_webapi.sh'
|
||
echo '============================================'
|
||
pushd /home/.devbox/freeleaps/apps
|
||
./start_webapi.sh > /home/.devbox/logs/backend.logs 2>&1 &
|
||
BACKEND_PID=\$!
|
||
|
||
# Save BACKEND_PID to a file \${WORKING_HOME}/.frontend.pid: Stores the process id of frontend process.
|
||
echo "\$BACKEND_PID" > /home/.devbox/.backend.pid
|
||
|
||
echo '============================================'
|
||
echo 'Check if the WebAPI service started successfully'
|
||
echo '============================================'
|
||
|
||
sleep 30
|
||
|
||
# 30 attempts, 5 seconds each, total wait time 2.5 minutes
|
||
MAX_ATTEMPTS=30
|
||
ATTEMPT=0
|
||
|
||
# Check if \$DEVBOX_BACKEND_PORT exists
|
||
DEVBOX_BACKEND_PORT=\$(cat /home/.devbox/.devbox-backend-port)
|
||
if [ -z "\$DEVBOX_BACKEND_PORT" ]; then
|
||
echo "ERROR: DEVBOX_BACKEND_PORT is not set."
|
||
export DEVBOX_BACKEND_PORT=8002
|
||
fi
|
||
|
||
echo "Waiting for WebAPI service to become healthy..."
|
||
|
||
while [ \$ATTEMPT -lt \$MAX_ATTEMPTS ]; do
|
||
HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$DEVBOX_BACKEND_PORT/docs")
|
||
# Check HTTP Code 200
|
||
if [ "\$HTTP_CODE" -eq 200 ]; then
|
||
echo "Backend Swagger UI is available at \$URL (HTTP \$HTTP_CODE)"
|
||
break
|
||
else
|
||
echo "Waiting for Swagger UI to become available... Attempt \$((ATTEMPT+1))"
|
||
ATTEMPT=\$((ATTEMPT+1))
|
||
sleep 5 # Wait 5 seconds
|
||
fi
|
||
done
|
||
|
||
if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then
|
||
echo "ERROR: WebAPI failed to start after \$MAX_ATTEMPTS attempts"
|
||
exit 1
|
||
fi
|
||
fi
|
||
EOF
|
||
|
||
;;
|
||
"frontend")
|
||
echo "==> Starting frontend service..."
|
||
# Start the frontend service
|
||
docker exec -i "$devbox_container_id" bash <<EOF
|
||
# Start the frontend service
|
||
echo "Starting frontend service..."
|
||
# Check if /home/.devbox/.frontend.pid exists
|
||
if [ -f /home/.devbox/.frontend.pid ]; then
|
||
|
||
frontend_pid=\$(cat /home/.devbox/.frontend.pid)
|
||
|
||
# Remove empty spaces and new lines in the frontend_pid
|
||
frontend_pid=\$(echo "\$frontend_pid" | tr -d '[:space:]')
|
||
|
||
# Check if frontend pid is empty
|
||
if [ -z "\$frontend_pid" ]; then
|
||
echo "Frontend service is not running. "
|
||
else
|
||
echo '============================================'
|
||
if ps -p "\$frontend_pid" > /dev/null; then
|
||
echo "Frontend service is already running."
|
||
exit 0
|
||
fi
|
||
fi
|
||
|
||
# Remove the .frontend.pid file before starting the frontend service
|
||
rm -f /home/.devbox/.frontend.pid
|
||
fi
|
||
echo '============================================'
|
||
echo ' Start frontend service locally'
|
||
echo '============================================'
|
||
pushd /home/.devbox/freeleaps/frontend
|
||
|
||
# Check if npm is installed and pnpm is installed and is npm run dev result is generated
|
||
if ! command -v npm &>/dev/null; then
|
||
echo "ERROR: npm is not installed."
|
||
exit 1
|
||
fi
|
||
|
||
if ! command -v pnpm &>/dev/null; then
|
||
echo "ERROR: pnpm is not installed."
|
||
exit 1
|
||
fi
|
||
|
||
if [ ! -f "package.json" ]; then
|
||
echo "ERROR: package.json not found."
|
||
exit 1
|
||
fi
|
||
|
||
# Start the frontend service with nohup in order to keep it running after the SSH session is closed
|
||
# Save the process ID of the frontend service
|
||
|
||
nohup npm run dev > /home/.devbox/logs/frontend.logs 2>&1 &
|
||
FRONTEND_PID=\$!
|
||
|
||
echo "npm run dev has been started with PID: \$FRONTEND_PID"
|
||
echo "\$FRONTEND_PID" > /home/.devbox/.frontend.pid
|
||
|
||
# Wait for the frontend service to start
|
||
sleep 10
|
||
|
||
# 30 attempts, 10 seconds each, total wait time 5 minutes
|
||
MAX_ATTEMPTS=30
|
||
ATTEMPT=0
|
||
|
||
DEVBOX_FRONTEND_PORT=\$(cat /home/.devbox/.devbox-frontend-port)
|
||
# get DEVBOX_FRONTEND_PORT from environment variables
|
||
if [ -z "\$DEVBOX_FRONTEND_PORT" ]; then
|
||
echo "ERROR: DEVBOX_FRONTEND_PORT is not set."
|
||
export DEVBOX_FRONTEND_PORT=5173
|
||
fi
|
||
|
||
echo "Waiting for Frontend service to start..."
|
||
while [ \$ATTEMPT -lt \$MAX_ATTEMPTS ]; do
|
||
HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$DEVBOX_FRONTEND_PORT/")
|
||
# Check HTTP Code 200
|
||
if [ "\$HTTP_CODE" -eq 200 ]; then
|
||
echo "Frontend is available (HTTP \$HTTP_CODE)"
|
||
break
|
||
else
|
||
echo "Waiting for Frontend to become available... (http://localhost:\$DEVBOX_FRONTEND_PORT), (HTTP \$HTTP_CODE) Attempt \$((ATTEMPT+1))"
|
||
ATTEMPT=\$((ATTEMPT+1))
|
||
sleep 10
|
||
fi
|
||
done
|
||
|
||
if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then
|
||
echo "ERROR: Frontend failed to start after \$MAX_ATTEMPTS attempts"
|
||
exit 1
|
||
fi
|
||
EOF
|
||
;;
|
||
"devsvc" | "payment" | "content" | "central_storage" | "authentication")
|
||
echo "==> Starting $comp service..."
|
||
# Check if the component container file exists
|
||
local component_container_id_file_path="${WORKING_HOME}/.${comp}-instance"
|
||
if [[ ! -f "$component_container_id_file_path" ]]; then
|
||
echo "ERROR: $comp container is not running. Please run 'devbox init' first."
|
||
else
|
||
local component_container_id=$(cat "$component_container_id_file_path")
|
||
if ! docker ps --no-trunc --format '{{.ID}}' | grep -q "^${component_container_id}\$"; then
|
||
echo "==> $comp container is not running, starting container..."
|
||
# Start the container
|
||
if ! docker start "${component_container_id}"; then
|
||
echo "ERROR: Failed to start $comp container."
|
||
else
|
||
echo "==> $comp container started successfully."
|
||
fi
|
||
else
|
||
echo "==> $comp container is already running."
|
||
fi
|
||
fi
|
||
;;
|
||
*)
|
||
echo "ERROR: Unknown component: $comp"
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# If the frontend component is started, print the URL
|
||
if [[ " ${COMPONENTS[@]} " =~ " frontend " ]]; then
|
||
echo "==> Frontend started. You can access the Freeleaps web application at: http://localhost:5173"
|
||
fi
|
||
|
||
echo "==> DevBox services started successfully."
|
||
}
|
||
|
||
# :command.function
|
||
devbox_stop_command() {
|
||
echo "==> Stopping DevBox services..."
|
||
local COMPONENT="$(get_arg '--component')"
|
||
local WORKING_HOME="$(get_arg '--working-home' "${HOME}/.devbox")"
|
||
|
||
# If the DevBox container is not running, exit
|
||
if [[ -z "$COMPONENT" ]]; then
|
||
COMPONENTS=("mongodb" "rabbitmq" "backend" "frontend" "devsvc" "payment" "content" "central_storage" "authentication")
|
||
else
|
||
COMPONENTS=("$COMPONENT")
|
||
fi
|
||
|
||
# Stop the specified components
|
||
for comp in "${COMPONENTS[@]}"; do
|
||
case "$comp" in
|
||
"mongodb")
|
||
echo "==> Stopping MongoDB..."
|
||
if [[ -f "${WORKING_HOME}/.mongodb-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.mongodb-instance")
|
||
docker stop "$container_id" &>/dev/null || true
|
||
else
|
||
echo "==> MongoDB container is not running."
|
||
fi
|
||
;;
|
||
"rabbitmq")
|
||
echo "==> Stopping RabbitMQ..."
|
||
if [[ -f "${WORKING_HOME}/.rabbitmq-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.rabbitmq-instance")
|
||
docker stop "$container_id" &>/dev/null || true
|
||
else
|
||
echo "==> RabbitMQ container is not running."
|
||
fi
|
||
;;
|
||
"backend")
|
||
echo "==> Stopping backend service..."
|
||
if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.devbox-instance")
|
||
docker stop "$container_id" &>/dev/null || true
|
||
else
|
||
echo "==> Backend service is not running."
|
||
fi
|
||
;;
|
||
"frontend")
|
||
echo "==> Stopping frontend service..."
|
||
if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.devbox-instance")
|
||
docker stop "$container_id" &>/dev/null || true
|
||
else
|
||
echo "==> Frontend service is not running."
|
||
fi
|
||
;;
|
||
"devsvc" | "payment" | "content" | "central_storage" | "authentication")
|
||
echo "==> Stopping $comp service..."
|
||
if [[ -f "${WORKING_HOME}/.${comp}-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.${comp}-instance")
|
||
docker stop "$container_id" &>/dev/null || true
|
||
else
|
||
echo "==> $comp service is not running."
|
||
fi
|
||
;;
|
||
*)
|
||
echo "ERROR: Unknown component: $comp"
|
||
exit 1
|
||
;;
|
||
esac
|
||
echo "==> $comp service stopped successfully."
|
||
done
|
||
echo "==> DevBox services stopped successfully."
|
||
}
|
||
|
||
# :command.function
|
||
devbox_status_command() {
|
||
|
||
echo "==> Checking DevBox services status..."
|
||
local COMPONENT="$(get_arg '--component')"
|
||
local WORKING_HOME="$(get_arg '--working-home' "${HOME}/.devbox")"
|
||
|
||
# Check if .devbox-instance file exists
|
||
if [[ ! -f "${WORKING_HOME}/.devbox-instance" ]]; then
|
||
echo "==> DevBox container is not running."
|
||
exit 1
|
||
fi
|
||
|
||
local devbox_container_id=$(cat "${WORKING_HOME}/.devbox-instance")
|
||
|
||
# If the DevBox container devbox_container_id is not running, exit
|
||
if ! docker ps --no-trunc --format '{{.ID}}' | grep -q "^${devbox_container_id}\$"; then
|
||
echo "==> DevBox container is not running."
|
||
exit 1
|
||
fi
|
||
|
||
|
||
# If no component is specified, check all components
|
||
if [[ -z "$COMPONENT" ]]; then
|
||
COMPONENTS=("mongodb" "rabbitmq" "backend" "frontend" "devsvc" "payment" "content" "central_storage" "authentication")
|
||
else
|
||
COMPONENTS=("$COMPONENT")
|
||
fi
|
||
|
||
# Check the status of the specified components
|
||
for comp in "${COMPONENTS[@]}"; do
|
||
case "$comp" in
|
||
"mongodb")
|
||
echo "==> Checking MongoDB status..."
|
||
if [[ -f "${WORKING_HOME}/.mongodb-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.mongodb-instance")
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then
|
||
echo "[RESULT]: MongoDB container is running."
|
||
else
|
||
echo "[RESULT]: MongoDB container is not running."
|
||
fi
|
||
else
|
||
echo "[RESULT]: MongoDB container is not running."
|
||
fi
|
||
;;
|
||
|
||
"rabbitmq")
|
||
echo "==> Checking RabbitMQ status..."
|
||
if [[ -f "${WORKING_HOME}/.rabbitmq-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.rabbitmq-instance")
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then
|
||
echo "[RESULT]: RabbitMQ container is running."
|
||
else
|
||
echo "[RESULT]: RabbitMQ container is not running."
|
||
fi
|
||
else
|
||
echo "[RESULT]: RabbitMQ container is not running."
|
||
fi
|
||
;;
|
||
|
||
"backend")
|
||
echo "==> Checking backend service status..."
|
||
if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.devbox-instance")
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then
|
||
if [[ -f "${WORKING_HOME}/.backend.pid" ]]; then
|
||
local backend_pid
|
||
backend_pid=$(cat "${WORKING_HOME}/.backend.pid")
|
||
if docker exec -i "$container_id" ps -p "$backend_pid" &>/dev/null; then
|
||
echo "[RESULT]: Backend service is running."
|
||
else
|
||
echo "[RESULT]: Backend service is not running."
|
||
fi
|
||
else
|
||
echo "[RESULT]: Backend service is not running."
|
||
fi
|
||
else
|
||
echo "[RESULT]: Backend service is not running."
|
||
fi
|
||
fi
|
||
;;
|
||
|
||
"frontend")
|
||
echo "==> Checking frontend service status..."
|
||
if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.devbox-instance")
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then
|
||
if [[ -f "${WORKING_HOME}/.frontend.pid" ]]; then
|
||
local frontend_pid
|
||
frontend_pid=$(cat "${WORKING_HOME}/.frontend.pid")
|
||
if docker exec -i "$container_id" ps -p "$frontend_pid" &>/dev/null; then
|
||
echo "[RESULT]: Frontend service is running."
|
||
else
|
||
echo "[RESULT]: Frontend service is not running."
|
||
fi
|
||
else
|
||
echo "[RESULT]: Frontend service is not running."
|
||
fi
|
||
else
|
||
echo "[RESULT]: Frontend service is not running."
|
||
fi
|
||
fi
|
||
;;
|
||
"devsvc")
|
||
echo "==> Checking devsvc service status..."
|
||
if [[ -f "${WORKING_HOME}/.devsvc-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.devsvc-instance")
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then
|
||
echo "[RESULT]: devsvc container is running."
|
||
else
|
||
echo "[RESULT]: devsvc container is not running."
|
||
fi
|
||
else
|
||
echo "[RESULT]: devsvc container is not running."
|
||
fi
|
||
;;
|
||
"payment")
|
||
echo "==> Checking payment service status..."
|
||
if [[ -f "${WORKING_HOME}/.payment-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.payment-instance")
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then
|
||
echo "[RESULT]: payment container is running."
|
||
else
|
||
echo "[RESULT]: payment container is not running."
|
||
fi
|
||
else
|
||
echo "[RESULT]: payment container is not running."
|
||
fi
|
||
;;
|
||
"content")
|
||
echo "==> Checking content service status..."
|
||
if [[ -f "${WORKING_HOME}/.content-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.content-instance")
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then
|
||
echo "[RESULT]: content container is running."
|
||
else
|
||
echo "[RESULT]: content container is not running."
|
||
fi
|
||
else
|
||
echo "[RESULT]: content container is not running."
|
||
fi
|
||
;;
|
||
"central_storage")
|
||
echo "==> Checking central_storage service status..."
|
||
if [[ -f "${WORKING_HOME}/.central_storage-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.central_storage-instance")
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then
|
||
echo "[RESULT]: central_storage container is running."
|
||
else
|
||
echo "[RESULT]: central_storage container is not running."
|
||
fi
|
||
else
|
||
echo "[RESULT]: central_storage container is not running."
|
||
fi
|
||
;;
|
||
"authentication")
|
||
echo "==> Checking authentication service status..."
|
||
if [[ -f "${WORKING_HOME}/.authentication-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.authentication-instance")
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then
|
||
echo "[RESULT]: authentication container is running."
|
||
else
|
||
echo "[RESULT]: authentication container is not running."
|
||
fi
|
||
else
|
||
echo "[RESULT]: authentication container is not running."
|
||
fi
|
||
;;
|
||
*)
|
||
echo "ERROR: Unknown component: $comp"
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
echo "==> DevBox services status checked successfully."
|
||
}
|
||
|
||
# :command.function
|
||
devbox_restart_command() {
|
||
echo "==> Restarting DevBox services..."
|
||
local COMPONENT="$(get_arg '--component')"
|
||
local WORKING_HOME="$(get_arg '--working-home' "${HOME}/.devbox")"
|
||
|
||
# Check devbox container file path
|
||
local devbox_container_id_file_path="${WORKING_HOME}/.devbox-instance"
|
||
if [[ ! -f "$devbox_container_id_file_path" ]]; then
|
||
echo "ERROR: DevBox container is not running. Please run 'devbox init' first."
|
||
exit 1
|
||
fi
|
||
|
||
local devbox_container_id=$(cat "$devbox_container_id_file_path")
|
||
if ! docker ps -a --no-trunc --format '{{.ID}}' | grep -q "^${devbox_container_id}\$"; then
|
||
echo "ERROR: DevBox container is not running. Please run 'devbox init' first."
|
||
rm -f "$devbox_container_id_file_path"
|
||
exit 1
|
||
fi
|
||
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${devbox_container_id}\$"; then
|
||
echo "==> DevBox container is running."
|
||
else
|
||
echo "==> DevBox container is not running."
|
||
docker start "$devbox_container_id" &>/dev/null || true
|
||
sleep 20
|
||
fi
|
||
|
||
if [[ -z "$COMPONENT" ]]; then
|
||
COMPONENTS=("mongodb" "rabbitmq" "backend" "frontend" "devsvc" "payment" "content" "central_storage" "authentication")
|
||
else
|
||
COMPONENTS=("$COMPONENT")
|
||
fi
|
||
|
||
# Stop the specified components
|
||
for comp in "${COMPONENTS[@]}"; do
|
||
case "$comp" in
|
||
"mongodb")
|
||
echo "==> Stopping MongoDB..."
|
||
if [[ -f "${WORKING_HOME}/.mongodb-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.mongodb-instance")
|
||
docker stop "$container_id" &>/dev/null || true
|
||
else
|
||
echo "==> MongoDB container is not running."
|
||
fi
|
||
;;
|
||
"rabbitmq")
|
||
echo "==> Stopping RabbitMQ..."
|
||
if [[ -f "${WORKING_HOME}/.rabbitmq-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.rabbitmq-instance")
|
||
docker stop "$container_id" &>/dev/null || true
|
||
else
|
||
echo "==> RabbitMQ container is not running."
|
||
fi
|
||
;;
|
||
"backend")
|
||
echo "==> Stopping backend service..."
|
||
if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.devbox-instance")
|
||
docker stop "$container_id" &>/dev/null || true
|
||
else
|
||
echo "==> Backend service is not running."
|
||
fi
|
||
;;
|
||
"frontend")
|
||
echo "==> Stopping frontend service..."
|
||
if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.devbox-instance")
|
||
docker stop "$container_id" &>/dev/null || true
|
||
else
|
||
echo "==> Frontend service is not running."
|
||
fi
|
||
;;
|
||
"devsvc" | "payment" | "content" | "central_storage" | "authentication")
|
||
echo "==> Stopping $comp service..."
|
||
if [[ -f "${WORKING_HOME}/.${comp}-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.${comp}-instance")
|
||
docker stop "$container_id" &>/dev/null || true
|
||
else
|
||
echo "==> $comp service is not running."
|
||
fi
|
||
;;
|
||
*)
|
||
echo "ERROR: Unknown component: $comp"
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# Start the specified components
|
||
for comp in "${COMPONENTS[@]}"; do
|
||
case "$comp" in
|
||
"mongodb")
|
||
echo "==> Restarting MongoDB..."
|
||
if [[ -f "${WORKING_HOME}/.mongodb-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.mongodb-instance")
|
||
docker start "$container_id" &>/dev/null || true
|
||
else
|
||
echo "==> MongoDB container is not running."
|
||
fi
|
||
;;
|
||
"rabbitmq")
|
||
echo "==> Restarting RabbitMQ..."
|
||
if [[ -f "${WORKING_HOME}/.rabbitmq-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.rabbitmq-instance")
|
||
docker start "$container_id" &>/dev/null || true
|
||
else
|
||
echo "==> RabbitMQ container is not running."
|
||
fi
|
||
;;
|
||
"backend")
|
||
echo "==> Restarting backend service..."
|
||
if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.devbox-instance")
|
||
docker start "$container_id" &>/dev/null || true
|
||
|
||
# Start backend service in the container
|
||
docker exec -i "$devbox_container_id" bash <<EOF
|
||
# Start the backend service
|
||
echo "Starting backend service..."
|
||
backend_pid=\$(cat /home/.devbox/.backend.pid)
|
||
if ps -p "\$backend_pid" > /dev/null; then
|
||
echo "Backend service is already running."
|
||
else
|
||
echo '============================================'
|
||
echo 'Start to run start_webapi.sh'
|
||
echo '============================================'
|
||
pushd /home/.devbox/freeleaps/apps
|
||
./start_webapi.sh > /home/.devbox/logs/backend.logs 2>&1 &
|
||
BACKEND_PID=\$!
|
||
|
||
# Save BACKEND_PID to a file \${WORKING_HOME}/.frontend.pid: Stores the process id of frontend process.
|
||
echo "\$BACKEND_PID" > /home/.devbox/.backend.pid
|
||
|
||
echo '============================================'
|
||
echo 'Check if the WebAPI service started successfully'
|
||
echo '============================================'
|
||
|
||
sleep 30
|
||
|
||
# 30 attempts, 5 seconds each, total wait time 2.5 minutes
|
||
MAX_ATTEMPTS=30
|
||
ATTEMPT=0
|
||
|
||
# Check if \$DEVBOX_BACKEND_PORT exists
|
||
if [ -z "\$DEVBOX_BACKEND_PORT" ]; then
|
||
echo "WARNING: DEVBOX_BACKEND_PORT is not set."
|
||
export DEVBOX_BACKEND_PORT=8002
|
||
fi
|
||
|
||
echo "DEVBOX_BACKEND_PORT: \$DEVBOX_BACKEND_PORT"
|
||
echo "Waiting for WebAPI service to become healthy..."
|
||
|
||
while [ \$ATTEMPT -lt \$MAX_ATTEMPTS ]; do
|
||
HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$DEVBOX_BACKEND_PORT/docs")
|
||
# Check HTTP Code 200
|
||
if [ "\$HTTP_CODE" -eq 200 ]; then
|
||
echo "Backend Swagger UI is available at \$URL (HTTP \$HTTP_CODE)"
|
||
break
|
||
else
|
||
echo "Waiting for Swagger UI to become available... Attempt \$((ATTEMPT+1))"
|
||
ATTEMPT=\$((ATTEMPT+1))
|
||
sleep 5 # Wait 5 seconds
|
||
fi
|
||
done
|
||
|
||
if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then
|
||
echo "ERROR: WebAPI failed to start after \$MAX_ATTEMPTS attempts"
|
||
exit 1
|
||
fi
|
||
fi
|
||
EOF
|
||
|
||
else
|
||
echo "==> Backend service is not running."
|
||
fi
|
||
;;
|
||
"frontend")
|
||
echo "==> Restarting frontend service..."
|
||
if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.devbox-instance")
|
||
docker start "$container_id" &>/dev/null || true
|
||
|
||
# Start frontend service in the container
|
||
docker exec -i "$DEVBOX_NAME" bash <<EOF
|
||
# Start the frontend service
|
||
# Check if /home/.devbox/.frontend.pid exists
|
||
if [ -f /home/.devbox/.frontend.pid ]; then
|
||
frontend_pid=\$(cat /home/.devbox/.frontend.pid)
|
||
|
||
# Check if the frontend service is already running
|
||
if ps -p "\$frontend_pid" > /dev/null; then
|
||
echo "Frontend service is already running."
|
||
exit 0
|
||
else
|
||
# Remove the frontend.pid file
|
||
rm -f /home/.devbox/.frontend.pid
|
||
fi
|
||
fi
|
||
|
||
echo '============================================'
|
||
echo ' Start frontend service locally'
|
||
echo '============================================'
|
||
pushd /home/.devbox/freeleaps/frontend
|
||
|
||
# Check if npm is installed and pnpm is installed and is npm run dev result is generated
|
||
if ! command -v npm &>/dev/null; then
|
||
echo "ERROR: npm is not installed."
|
||
exit 1
|
||
fi
|
||
|
||
if ! command -v pnpm &>/dev/null; then
|
||
echo "ERROR: pnpm is not installed."
|
||
exit 1
|
||
fi
|
||
|
||
if [ ! -f "package.json" ]; then
|
||
echo "ERROR: package.json not found."
|
||
exit 1
|
||
fi
|
||
|
||
# Start the frontend service with nohup in order to keep it running after the SSH session is closed
|
||
# Save the process ID of the frontend service
|
||
nohup npm run dev > /home/.devbox/logs/frontend.logs 2>&1 &
|
||
FRONTEND_PID=\$!
|
||
|
||
echo "npm run dev has been started with PID: \$FRONTEND_PID"
|
||
echo "\$FRONTEND_PID" > /home/.devbox/.frontend.pid
|
||
|
||
# Wait for the frontend service to start
|
||
sleep 30
|
||
|
||
# 30 attempts, 10 seconds each, total wait time 5 minutes
|
||
MAX_ATTEMPTS=30
|
||
ATTEMPT=0
|
||
|
||
# Check if \$DEVBOX_FRONTEND_PORT exists
|
||
if [ -z "\$DEVBOX_FRONTEND_PORT" ]; then
|
||
echo "ERROR: DEVBOX_FRONTEND_PORT is not set."
|
||
export DEVBOX_FRONTEND_PORT=5173
|
||
fi
|
||
|
||
echo "Waiting for Frontend service to start..."
|
||
while [ \$ATTEMPT -lt \$MAX_ATTEMPTS ]; do
|
||
HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$DEVBOX_FRONTEND_PORT/")
|
||
# Check HTTP Code 200
|
||
if [ "\$HTTP_CODE" -eq 200 ]; then
|
||
echo "Frontend is available (HTTP \$HTTP_CODE)"
|
||
break
|
||
else
|
||
echo "Waiting for Frontend to become available... (http://localhost:\$DEVBOX_FRONTEND_PORT), (HTTP \$HTTP_CODE) Attempt \$((ATTEMPT+1))"
|
||
ATTEMPT=\$((ATTEMPT+1))
|
||
sleep 10
|
||
fi
|
||
done
|
||
|
||
if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then
|
||
echo "ERROR: Frontend failed to start after \$MAX_ATTEMPTS attempts"
|
||
exit 1
|
||
fi
|
||
EOF
|
||
else
|
||
echo "==> Frontend service is not running."
|
||
fi
|
||
;;
|
||
"devsvc" | "payment" | "content" | "central_storage" | "authentication")
|
||
echo "==> Restarting $comp service..."
|
||
if [[ -f "${WORKING_HOME}/.${comp}-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.${comp}-instance")
|
||
docker start "$container_id" &>/dev/null || true
|
||
else
|
||
echo "==> $comp service is not running."
|
||
fi
|
||
;;
|
||
*)
|
||
echo "ERROR: Unknown component: $comp"
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
echo "==> DevBox services restarted successfully."
|
||
}
|
||
|
||
# :command.parse_requirements
|
||
parse_requirements() {
|
||
# :command.fixed_flags_filter
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
--version | -v)
|
||
version_command
|
||
exit
|
||
;;
|
||
|
||
--help | -h)
|
||
long_usage=yes
|
||
devbox_usage
|
||
exit
|
||
;;
|
||
|
||
*)
|
||
break
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
# :command.environment_variables_filter
|
||
|
||
env_var_names+=("FREELEAPS_USERNAME")
|
||
env_var_names+=("FREELEAPS_PASSWORD")
|
||
env_var_names+=("WORKING_HOME")
|
||
|
||
# :command.command_filter
|
||
action=${1:-}
|
||
|
||
case $action in
|
||
-*) ;;
|
||
|
||
init | i)
|
||
action="init"
|
||
shift
|
||
devbox_init_parse_requirements "$@"
|
||
shift $#
|
||
;;
|
||
|
||
deinit | d)
|
||
action="deinit"
|
||
shift
|
||
devbox_deinit_parse_requirements "$@"
|
||
shift $#
|
||
;;
|
||
|
||
start | s)
|
||
action="start"
|
||
shift
|
||
devbox_start_parse_requirements "$@"
|
||
shift $#
|
||
;;
|
||
|
||
stop | p)
|
||
action="stop"
|
||
shift
|
||
devbox_stop_parse_requirements "$@"
|
||
shift $#
|
||
;;
|
||
|
||
status | t)
|
||
action="status"
|
||
shift
|
||
devbox_status_parse_requirements "$@"
|
||
shift $#
|
||
;;
|
||
|
||
restart | r)
|
||
action="restart"
|
||
shift
|
||
devbox_restart_parse_requirements "$@"
|
||
shift $#
|
||
;;
|
||
|
||
# :command.command_fallback
|
||
"")
|
||
devbox_usage >&2
|
||
exit 1
|
||
;;
|
||
|
||
*)
|
||
printf "invalid command: %s\n" "$action" >&2
|
||
exit 1
|
||
;;
|
||
|
||
esac
|
||
|
||
# :command.parse_requirements_while
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
|
||
-?*)
|
||
printf "invalid option: %s\n" "$key" >&2
|
||
exit 1
|
||
;;
|
||
|
||
*)
|
||
# :command.parse_requirements_case
|
||
# :command.parse_requirements_case_simple
|
||
printf "invalid argument: %s\n" "$key" >&2
|
||
exit 1
|
||
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
}
|
||
|
||
|
||
# :command.parse_requirements
|
||
devbox_init_parse_requirements() {
|
||
# :command.fixed_flags_filter
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
--help | -h)
|
||
long_usage=yes
|
||
devbox_init_usage
|
||
exit
|
||
;;
|
||
|
||
*)
|
||
break
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
# :command.command_filter
|
||
action="init"
|
||
|
||
# :command.parse_requirements_while
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
# :flag.case
|
||
--os)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--os' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--os requires an argument: --os OS" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--arch)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--arch' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--arch requires an argument: --arch ARCH" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--devbox-container-name)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devbox-container-name' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--devbox-container-name requires an argument: --devbox-container-name DEVBOX_CONTAINER_NAME" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--devbox-container-port)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devbox-container-port' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--devbox-container-port requires an argument: --devbox-container-port DEVBOX_CONTAINER_PORT" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--devbox-image-repo)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devbox-image-repo' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--devbox-image-repo requires an argument: --devbox-image-repo DEVBOX_IMAGE_REPO" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--devbox-image-name)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devbox-image-name' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--devbox-image-name requires an argument: --devbox-image-name DEVBOX_IMAGE_NAME" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--devbox-image-tag)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devbox-image-tag' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--devbox-image-tag requires an argument: --devbox-image-tag DEVBOX_IMAGE_TAG" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--working-home)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--working-home' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--working-home requires an argument: --working-home WORKING_HOME" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--freeleaps-username)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--freeleaps-username' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--freeleaps-username requires an argument: --freeleaps-username FREELEAPS_USERNAME" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--freeleaps-password)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--freeleaps-password' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--freeleaps-password requires an argument: --freeleaps-password FREELEAPS_PASSWORD" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--use-local-component)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--use-local-component' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--use-local-component requires an argument: --use-local-component USING_LOCAL_COMPONENT" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--devsvc-image-repo)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devsvc-image-repo' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--devsvc-image-repo requires an argument: --devsvc-image-repo DEVSVC_IMAGE_REPO" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--devsvc-image-name)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devsvc-image-name' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--devsvc-image-name requires an argument: --devsvc-image-name DEVSVC_IMAGE_NAME" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--devsvc-image-tag)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devsvc-image-tag' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--devsvc-image-tag requires an argument: --devsvc-image-tag DEVSVC_IMAGE_TAG" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--payment-image-repo)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--payment-image-repo' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--payment-image-repo requires an argument: --payment-image-repo FREELEAPS_PAYMENT_IMAGE_REPO" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--payment-image-name)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--payment-image-name' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--payment-image-name requires an argument: --payment-image-name FREELEAPS_PAYMENT_IMAGE_NAME" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--payment-image-tag)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--payment-image-tag' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--payment-image-tag requires an argument: --payment-image-tag FREELEAPS_PAYMENT_IMAGE_TAG" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--content-image-repo)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--content-image-repo' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--content-image-repo requires an argument: --content-image-repo FREELEAPS_CONTENT_IMAGE_REPO" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--content-image-name)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--content-image-name' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--content-image-name requires an argument: --content-image-name FREELEAPS_CONTENT_IMAGE_NAME" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--content-image-tag)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--content-image-tag' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--content-image-tag requires an argument: --content-image-tag FREELEAPS_CONTENT_IMAGE_TAG" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--central_storage-image-repo)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--central_storage-image-repo' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--central_storage-image-repo requires an argument: --central_storage-image-repo FREELEAPS_CENTRAL_STORAGE_IMAGE_REPO" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--central_storage-image-name)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--central_storage-image-name' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--central_storage-image-name requires an argument: --central_storage-image-name FREELEAPS_CENTRAL_STORAGE_IMAGE_NAME" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--central_storage-image-tag)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--central_storage-image-tag' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--central_storage-image-tag requires an argument: --central_storage-image-tag FREELEAPS_CENTRAL_STORAGE_IMAGE_TAG" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--authentication-image-repo)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--authentication-image-repo' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--authentication-image-repo requires an argument: --authentication-image-repo FREELEAPS_AUTHENTICATION_IMAGE_REPO" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--authentication-image-name)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--authentication-image-name' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--authentication-image-name requires an argument: --authentication-image-name FREELEAPS_AUTHENTICATION_IMAGE_NAME" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--authentication-image-tag)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--authentication-image-tag' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--authentication-image-tag requires an argument: --authentication-image-tag FREELEAPS_AUTHENTICATION_IMAGE_TAG" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
# :flag.case
|
||
--force | -f)
|
||
|
||
# :flag.case_no_arg
|
||
add_arg '--force' '1'
|
||
shift
|
||
;;
|
||
|
||
-?*)
|
||
printf "invalid option: %s\n" "$key" >&2
|
||
exit 1
|
||
;;
|
||
|
||
*)
|
||
# :command.parse_requirements_case
|
||
# :command.parse_requirements_case_simple
|
||
printf "invalid argument: %s\n" "$key" >&2
|
||
exit 1
|
||
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
# :command.required_flags_filter
|
||
|
||
if [[ -z "$(get_arg '--freeleaps-username')" ]]; then
|
||
|
||
printf "missing required flag: --freeleaps-username FREELEAPS_USERNAME\n" >&2
|
||
exit 1
|
||
fi
|
||
if [[ -z "$(get_arg '--freeleaps-password')" ]]; then
|
||
printf "missing required flag: --freeleaps-password FREELEAPS_PASSWORD\n" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# :command.default_assignments
|
||
|
||
if [ -z "$(get_arg '--os')" ]; then
|
||
add_arg '--os' "auto"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--arch')" ]; then
|
||
add_arg '--arch' "auto"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--devbox-container-name')" ]; then
|
||
add_arg '--devbox-container-name' "devbox"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--devbox-container-port')" ]; then
|
||
add_arg '--devbox-container-port' "22222"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--devbox-frontend-port')" ]; then
|
||
add_arg '--devbox-frontend-port' "5173"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--devbox-backend-port')" ]; then
|
||
add_arg '--devbox-backend-port' "8002"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--devbox-image-repo')" ]; then
|
||
add_arg '--devbox-image-repo' "docker.io/freeleaps"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--devbox-image-name')" ]; then
|
||
add_arg '--devbox-image-name' "devbox_v1"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--devbox-image-tag')" ]; then
|
||
add_arg '--devbox-image-tag' "devbox_local"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--devsvc-image-tag')" ]; then
|
||
add_arg '--devsvc-image-tag' "latest-linux-arm64"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--payment-image-tag')" ]; then
|
||
add_arg '--payment-image-tag' "latest-linux-arm64"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--content-image-tag')" ]; then
|
||
add_arg '--content-image-tag' "latest-linux-arm64"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--central_storage-image-tag')" ]; then
|
||
add_arg '--central_storage-image-tag' "latest-linux-arm64"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--authentication-image-tag')" ]; then
|
||
add_arg '--authentication-image-tag' "latest-linux-arm64"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--working-home')" ]; then
|
||
add_arg '--working-home' "${HOME}/.devbox"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--use-local-component')" ]; then
|
||
add_arg '--use-local-component' "false"
|
||
fi
|
||
|
||
|
||
}
|
||
|
||
|
||
# :command.parse_requirements
|
||
devbox_deinit_parse_requirements() {
|
||
# :command.fixed_flags_filter
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
--help | -h)
|
||
long_usage=yes
|
||
devbox_deinit_usage
|
||
exit
|
||
;;
|
||
|
||
*)
|
||
break
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
# :command.command_filter
|
||
action="deinit"
|
||
|
||
# :command.parse_requirements_while
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
# :flag.case
|
||
--working-home)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--working-home' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--working-home requires an argument: --working-home WORKING_HOME" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--clear-logs)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--clear-logs' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--clear-logs requires an argument: --clear-logs CLEAR_LOGS" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
# :flag.case
|
||
--clear-repo)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--clear-repo' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--clear-repo requires an argument: --clear-repo CLEAR_REPO" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
-?*)
|
||
printf "invalid option: %s\n" "$key" >&2
|
||
exit 1
|
||
;;
|
||
|
||
*)
|
||
# :command.parse_requirements_case
|
||
# :command.parse_requirements_case_simple
|
||
printf "invalid argument: %s\n" "$key" >&2
|
||
exit 1
|
||
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
# :command.default_assignments
|
||
if [ -z "$(get_arg '--working-home')" ]; then
|
||
add_arg '--working-home' "${HOME}/.devbox"
|
||
fi
|
||
if [ -z "$(get_arg '--clear-logs')" ]; then
|
||
add_arg '--clear-logs' "false"
|
||
fi
|
||
if [ -z "$(get_arg '--clear-repo')" ]; then
|
||
add_arg '--clear-repo' "false"
|
||
fi
|
||
|
||
}
|
||
|
||
# :command.parse_requirements
|
||
devbox_start_parse_requirements() {
|
||
# :command.fixed_flags_filter
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
--help | -h)
|
||
long_usage=yes
|
||
devbox_start_usage
|
||
exit
|
||
;;
|
||
|
||
*)
|
||
break
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
# :command.command_filter
|
||
action="start"
|
||
|
||
# :command.parse_requirements_while
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
# :flag.case
|
||
--component)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--component' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--component requires an argument: --component COMPONENT" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
-?*)
|
||
printf "invalid option: %s\n" "$key" >&2
|
||
exit 1
|
||
;;
|
||
|
||
*)
|
||
# :command.parse_requirements_case
|
||
# :command.parse_requirements_case_simple
|
||
printf "invalid argument: %s\n" "$key" >&2
|
||
exit 1
|
||
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
}
|
||
|
||
# :command.parse_requirements
|
||
devbox_stop_parse_requirements() {
|
||
# :command.fixed_flags_filter
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
--help | -h)
|
||
long_usage=yes
|
||
devbox_stop_usage
|
||
exit
|
||
;;
|
||
|
||
*)
|
||
break
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
# :command.command_filter
|
||
action="stop"
|
||
|
||
# :command.parse_requirements_while
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
# :flag.case
|
||
--component)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--component' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--component requires an argument: --component COMPONENT" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
|
||
-?*)
|
||
printf "invalid option: %s\n" "$key" >&2
|
||
exit 1
|
||
;;
|
||
|
||
*)
|
||
# :command.parse_requirements_case
|
||
# :command.parse_requirements_case_simple
|
||
printf "invalid argument: %s\n" "$key" >&2
|
||
exit 1
|
||
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
}
|
||
|
||
# :command.parse_requirements
|
||
devbox_status_parse_requirements() {
|
||
# :command.fixed_flags_filter
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
--help | -h)
|
||
long_usage=yes
|
||
devbox_status_usage
|
||
exit
|
||
;;
|
||
|
||
*)
|
||
break
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
# :command.command_filter
|
||
action="status"
|
||
|
||
# :command.parse_requirements_while
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
|
||
-?*)
|
||
printf "invalid option: %s\n" "$key" >&2
|
||
exit 1
|
||
;;
|
||
|
||
*)
|
||
# :command.parse_requirements_case
|
||
# :command.parse_requirements_case_simple
|
||
printf "invalid argument: %s\n" "$key" >&2
|
||
exit 1
|
||
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
}
|
||
|
||
# :command.parse_requirements
|
||
devbox_restart_parse_requirements() {
|
||
# :command.fixed_flags_filter
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
--help | -h)
|
||
long_usage=yes
|
||
devbox_restart_usage
|
||
exit
|
||
;;
|
||
|
||
*)
|
||
break
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
# :command.command_filter
|
||
action="restart"
|
||
|
||
# :command.parse_requirements_while
|
||
while [[ $# -gt 0 ]]; do
|
||
key="$1"
|
||
case "$key" in
|
||
|
||
-?*)
|
||
printf "invalid option: %s\n" "$key" >&2
|
||
exit 1
|
||
;;
|
||
|
||
*)
|
||
# :command.parse_requirements_case
|
||
# :command.parse_requirements_case_simple
|
||
printf "invalid argument: %s\n" "$key" >&2
|
||
exit 1
|
||
|
||
;;
|
||
|
||
esac
|
||
done
|
||
|
||
}
|
||
|
||
|
||
|
||
initialize() {
|
||
version="1.0.0"
|
||
long_usage=""
|
||
set -e
|
||
|
||
# Use the following variables to define the environment variables and input parameters
|
||
args_keys=()
|
||
args_values=()
|
||
|
||
deps_keys=()
|
||
deps_values=()
|
||
|
||
# For each environment variable, add a line like the following:
|
||
env_var_names=()
|
||
input=()
|
||
}
|
||
|
||
# :command.run
|
||
run() {
|
||
normalize_input "$@"
|
||
parse_requirements "${input[@]}"
|
||
|
||
case "$action" in
|
||
"init") devbox_init_command ;;
|
||
"deinit") devbox_deinit_command ;;
|
||
"start") devbox_start_command ;;
|
||
"stop") devbox_stop_command ;;
|
||
"status") devbox_status_command ;;
|
||
"restart") devbox_restart_command ;;
|
||
esac
|
||
}
|
||
initialize
|
||
run "$@"
|