forked from freeleaps/freeleaps-pub
3795 lines
131 KiB
Bash
Executable File
3795 lines
131 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Modifying it manually is not recommended
|
||
|
||
# All components that can be started in the DevBox container. [:COMPONENT_SETTINGS]
|
||
DEVBOX_COMPONENTS=("devsvc" "notification" "content" "central_storage" "chat" "authentication")
|
||
|
||
log_info() {
|
||
echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') $*"
|
||
}
|
||
log_warn() {
|
||
echo "[WARN] $(date '+%Y-%m-%d %H:%M:%S') $*"
|
||
}
|
||
log_error() {
|
||
echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S') $*" >&2
|
||
}
|
||
|
||
# :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:]'
|
||
}
|
||
|
||
exit_with_message() {
|
||
local message="$1"
|
||
local code="${2:-1}"
|
||
echo
|
||
echo "============================================================================"
|
||
echo
|
||
if [[ $code -eq 0 ]]; then
|
||
echo "[INFO] $message"
|
||
else
|
||
echo "[ERROR] $message" >&2
|
||
fi
|
||
echo
|
||
echo "============================================================================"
|
||
echo
|
||
exit $code
|
||
}
|
||
|
||
|
||
detect_os() {
|
||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||
echo "darwin"
|
||
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||
echo "linux"
|
||
elif grep -qi microsoft /proc/version; then
|
||
echo "wsl2"
|
||
else
|
||
echo "unknown"
|
||
fi
|
||
}
|
||
|
||
|
||
# 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
|
||
}
|
||
|
||
|
||
devbox_init_guidance() {
|
||
printf "Welcome to DevBox CLI!\n\n"
|
||
# if $1 is empty, then ask user select a choice or match user input $1 action to be product_id
|
||
if [[ -z $1 ]]; then
|
||
# Guide user to select use freeleaps env or custom repository for source code
|
||
printf "Please choose an option:\n"
|
||
printf " 1. Use Freeleaps.com repository\n"
|
||
printf " 2. Use custom repository\n"
|
||
read -p "Enter your choice (1 or 2): " choice
|
||
else
|
||
log_info "Your will start with init product $1 develop environment"
|
||
product_id=$1
|
||
case "$product_id" in
|
||
freeleaps)
|
||
choice=1
|
||
;;
|
||
*)
|
||
choice=2
|
||
;;
|
||
esac
|
||
fi
|
||
|
||
case "$choice" in
|
||
1)
|
||
freeleaps_username=""
|
||
freeleaps_password=""
|
||
use_local_component=false
|
||
use_custom_repository=""
|
||
freeleaps_components=""
|
||
|
||
# Ask user for Freeleaps.com username and password
|
||
read -p "Enter your Freeleaps.com username: " freeleaps_username
|
||
read -s -p "Enter your Freeleaps.com password: " freeleaps_password
|
||
echo
|
||
read -p "Use local component dev environment? (y/n): " choose_local_component
|
||
if [[ $choose_local_component == "y" ]]; then
|
||
use_local_component=true
|
||
fi
|
||
|
||
add_arg "--freeleaps-username" "$freeleaps_username"
|
||
add_arg "--freeleaps-password" "$freeleaps_password"
|
||
add_arg "--use-local-component" "$use_local_component"
|
||
add_arg "--use-custom-repository" "$use_custom_repository"
|
||
;;
|
||
2)
|
||
# Check if product_id is empty
|
||
if [[ -z $product_id ]]; then
|
||
# Ask user for product_id
|
||
read -p "Enter your product_id: " product_id
|
||
if [[ -z $product_id ]]; then
|
||
exit_with_message "Product ID is required, please provide a valid product ID." 1
|
||
fi
|
||
fi
|
||
|
||
# Ask user for Freeleaps.com username and password
|
||
read -p "Enter your Freeleaps.com username: " freeleaps_username
|
||
read -s -p "Enter your Freeleaps.com password: " freeleaps_password
|
||
echo
|
||
|
||
add_arg "--freeleaps-username" "$freeleaps_username"
|
||
add_arg "--freeleaps-password" "$freeleaps_password"
|
||
|
||
ENCODING_FREELEAPS_USERNAME=$(url_encode "$freeleaps_username")
|
||
ENCODEING_FREELEAPS_PASSWORD=$(url_encode "$freeleaps_password")
|
||
use_custom_repository="https://$ENCODING_FREELEAPS_USERNAME:$ENCODEING_FREELEAPS_PASSWORD@gitea.freeleaps.mathmast.com/products/$product_id.git"
|
||
|
||
# Test the repository connection
|
||
if ! git ls-remote "$use_custom_repository"; then
|
||
exit_with_message " Failed to connect to the repository. Please check your username and password." 1
|
||
fi
|
||
|
||
printf "Repository connection successfully.\n"
|
||
|
||
add_arg "--use-custom-repository" "$use_custom_repository"
|
||
;;
|
||
*)
|
||
exit_with_message "Invalid choice. Please enter 1 or 2." 1
|
||
;;
|
||
esac
|
||
}
|
||
|
||
# :command.usage
|
||
devbox_usage() {
|
||
printf "Command\n"
|
||
printf " devbox : DevBox Command Line Tool for managing the local development environment.\n\n"
|
||
|
||
printf "Usage\n"
|
||
printf " devbox : Interactive mode to initialize development environment\n"
|
||
printf " devbox freeleaps : Initialize Freeleaps.com development environment\n"
|
||
printf " devbox <product_id> : Initialize specific product development environment\n\n"
|
||
|
||
printf "Arguments\n"
|
||
printf " COMMAND [Required] : Specify the command to execute.\n"
|
||
printf " init, i : Initialize the local development environment.\n"
|
||
printf " deinit, d : De-initialize the local development environment.\n"
|
||
printf " start, s : Start services in the local development environment.\n"
|
||
printf " stop, p : Stop services in the local development environment.\n"
|
||
printf " status, t : Display status of services in the local environment.\n"
|
||
printf " restart, r : Restart services in the local environment.\n\n"
|
||
|
||
printf "Global Arguments\n"
|
||
printf " --help, -h : Show this help message and exit.\n"
|
||
printf " --version, -v : Show version number.\n\n"
|
||
|
||
printf "Examples\n"
|
||
printf " Initialize development environment interactively:\n"
|
||
printf " devbox\n\n"
|
||
printf " Initialize Freeleaps.com development environment:\n"
|
||
printf " devbox freeleaps\n\n"
|
||
printf " Initialize specific product development environment:\n"
|
||
printf " devbox <product_id>\n\n"
|
||
printf " Initialize development environment with command:\n"
|
||
printf " devbox init\n\n"
|
||
printf " Display help for the 'init' command:\n"
|
||
printf " devbox init --help\n\n"
|
||
printf " Start all services:\n"
|
||
printf " devbox start\n\n"
|
||
printf " Start specific service:\n"
|
||
printf " devbox start --component=backend\n\n"
|
||
printf " Display version information:\n"
|
||
printf " devbox --version\n"
|
||
echo
|
||
}
|
||
|
||
|
||
# :command.usage
|
||
devbox_init_usage() {
|
||
if [[ -n $long_usage ]]; then
|
||
printf "Command\n"
|
||
printf " devbox init : Initialize the local development environment based on DevBox container.\n\n"
|
||
|
||
printf "Arguments\n"
|
||
printf " --os -o [Optional] : Specifies the operating system. Default: auto.\n"
|
||
printf " --arch -a [Optional] : Specifies the architecture. Default: auto.\n"
|
||
printf " --working-home -w [Optional] : Specifies the working home of DevBox CLI. Default: %s/devbox\n" "$HOME"
|
||
printf " --devbox-container-name -n [Optional] : Specifies the DevBox container name. Default: devbox.\n"
|
||
printf " --devbox-container-port -p [Optional] : Specifies the container port for DevBox SSH access. Default: 22222.\n"
|
||
printf " --devbox-image-repo -r [Optional] : Specifies the DevBox container image repository. Default: docker.io/freeleaps.\n"
|
||
printf " --devbox-image-name -i [Optional] : Specifies the DevBox container image name. Default: devbox.\n"
|
||
printf " --devbox-image-tag -t [Optional] : Specifies the DevBox container image tag. Default: latest.\n"
|
||
printf " --devbox-frontend-port -q [Optional] : Specifies the container port for DevBox frontend access. Default: 5173.\n"
|
||
printf " --devbox-backend-port -b [Optional] : Specifies the container port for DevBox backend access. Default: 8002.\n"
|
||
printf " --freeleaps-username -u [Optional] : Specifies the Freeleaps.com repository username.\n"
|
||
printf " --freeleaps-password -x [Optional] : Specifies the Freeleaps.com repository password.\n"
|
||
printf " --use-local-component -l [Optional] : Check if using local component or online dev environment. Default: false.\n"
|
||
printf " --use-custom-repository -c [Optional] : Specifies the custom git repository for source code.\n"
|
||
printf " --freeleaps-components -m [Optional] : Specifies the Freeleaps.com components to start in the DevBox container.\n"
|
||
printf " --force -f [Optional] : Force initialization even if resources already exist.\n\n"
|
||
|
||
printf "Global Arguments\n"
|
||
printf " --help -h : Show this help message and exit.\n\n"
|
||
|
||
printf "Examples\n"
|
||
printf " Initialize DevBox with Linux OS and ARM64 architecture:\n"
|
||
printf " devbox init --os linux --arch arm64 --freeleaps-username alice --freeleaps-password secret\n"
|
||
printf " Initialize with custom container settings:\n"
|
||
printf " devbox init --devbox-container-name custom-devbox --devbox-container-port 22222 --freeleaps-username alice --freeleaps-password secret\n"
|
||
else
|
||
printf "devbox init - Initialize the local development environment based on DevBox container.\n\n"
|
||
fi
|
||
}
|
||
|
||
# :command.usage
|
||
devbox_deinit_usage() {
|
||
if [[ -n $long_usage ]]; then
|
||
printf "Command\n"
|
||
printf " devbox deinit : De-initialize the local development environment based on DevBox container.\n\n"
|
||
|
||
printf "Arguments\n"
|
||
printf " --working-home -w [Optional] : Specifies the working home of DevBox CLI. Default: %s/devbox\n" "$HOME"
|
||
printf " --clear-logs -l [Optional] : Specifies whether to clear log files. Default: true\n"
|
||
printf " --clear-repo -r [Optional] : Specifies whether to delete the source repository. Default: false\n\n"
|
||
printf " --clear-all -a [Optional] : Specifies whether to clear all resources. Default: false\n\n"
|
||
|
||
printf "Global Arguments\n"
|
||
printf " --help, -h : Show this help message and exit.\n\n"
|
||
|
||
printf "Examples\n"
|
||
printf " De-initialize the local development environment.\n"
|
||
printf " devbox deinit\n"
|
||
printf " De-initialize with custom working home and options.\n"
|
||
printf " devbox deinit --working-home=/tmp/devbox --clear-logs=false --clear-repo=true\n"
|
||
printf " Clear all resources.\n"
|
||
printf " devbox deinit --clear-all=true\n"
|
||
else
|
||
printf "devbox deinit - De-initialize the local development environment based on DevBox container.\n\n"
|
||
fi
|
||
}
|
||
|
||
# :command.usage
|
||
devbox_start_usage() {
|
||
if [[ -n $long_usage ]]; then
|
||
printf "Command\n"
|
||
printf " devbox start : Start the local development environment based on DevBox container.\n\n"
|
||
|
||
printf "Arguments\n"
|
||
printf " --component COMPONENT [Optional] : Specifies the name of the component to start (e.g., mongodb, rabbitmq, devsvc, content, central_storage, notification, chat, authentication).\n\n"
|
||
printf " --freeleaps-endpoint -e [Optional] : Specifies the Freeleaps.com endpoint backend & frontend to start in the DevBox container.\n\n"
|
||
printf "Global Arguments\n"
|
||
printf " --help, -h : Show this help message and exit.\n\n"
|
||
|
||
printf "Examples\n"
|
||
printf " Start all components:\n"
|
||
printf " devbox start\n"
|
||
printf " Start a specific component (e.g., backend):\n"
|
||
printf " devbox start --component=backend\n"
|
||
else
|
||
printf "devbox start - Start the local development environment based on DevBox container.\n\n"
|
||
fi
|
||
printf "Alias: s\n"
|
||
echo
|
||
}
|
||
|
||
# :command.usage
|
||
devbox_stop_usage() {
|
||
if [[ -n $long_usage ]]; then
|
||
printf "Command\n"
|
||
printf " devbox stop : Stop the local development environment based on DevBox container.\n\n"
|
||
printf "Arguments\n"
|
||
printf " --component -c [Optional] : Specifies the name of the component to stop (e.g., mongodb, rabbitmq, devbox, devsvc, content, central_storage, notification, chat, authentication).\n\n"
|
||
printf " --freeleaps-endpoint -e [Optional] : Specifies the Freeleaps.com endpoint backend & frontend to stop in the DevBox container.\n\n"
|
||
printf "Global Arguments\n"
|
||
printf " --help -h : Show this help message and exit.\n\n"
|
||
printf "Examples\n"
|
||
printf " stop freeleaps backend service:\n"
|
||
printf " devbox stop --freeleaps-endpoint=backend\n"
|
||
printf " stop all services:\n"
|
||
printf " devbox stop --freeleaps-endpoint=all\n"
|
||
printf " Stop all components:\n"
|
||
printf " devbox stop\n\n"
|
||
printf " Stop a specific component (e.g., backend):\n"
|
||
printf " devbox stop --component=backend\n"
|
||
else
|
||
printf "devbox stop - Stop the local development environment based on DevBox container.\n"
|
||
fi
|
||
echo
|
||
}
|
||
|
||
# :command.usage
|
||
devbox_status_usage() {
|
||
if [[ -n $long_usage ]]; then
|
||
printf "Command\n"
|
||
printf " devbox status : Display the status of the local development environment based on DevBox container.\n\n"
|
||
|
||
printf "Arguments\n"
|
||
printf " --component -c [Optional] : Specifies the component to show status (e.g., devbox, devsvc, content, central_storage, notification, chat, authentication).\n\n"
|
||
|
||
printf "Global Arguments\n"
|
||
printf " --help -h : Show this help message and exit.\n\n"
|
||
|
||
printf "Examples\n"
|
||
printf " Display status for all components:\n"
|
||
printf " devbox status\n\n"
|
||
printf " Display status for a specific component:\n"
|
||
printf " devbox status --component=content\n"
|
||
else
|
||
printf "devbox status - Display the status of the local development environment based on DevBox container.\n"
|
||
fi
|
||
echo
|
||
}
|
||
|
||
# :command.usage
|
||
devbox_restart_usage() {
|
||
if [[ -n $long_usage ]]; then
|
||
printf "Command\n"
|
||
printf " devbox restart : Restart the local development environment based on DevBox container.\n\n"
|
||
printf "Arguments\n"
|
||
printf " --component -c [Optional] : Specifies the component to restart (e.g., devbox, devsvc, content, central_storage, notification, chat, authentication).\n"
|
||
printf " --freeleaps-endpoint -e [Optional] : Specifies the Freeleaps.com backend & frontend to restart in the DevBox container.\n"
|
||
printf " --force -f [Optional] : Force the restart operation without prompt.\n\n"
|
||
printf "Global Arguments\n"
|
||
printf " --help -h : Show this help message and exit.\n"
|
||
printf "Examples\n"
|
||
printf " Restart all components:\n"
|
||
printf " devbox restart\n\n"
|
||
printf " Restart a specific component (e.g., backend):\n"
|
||
printf " devbox restart --component=backend\n"
|
||
else
|
||
printf "devbox restart - Restart the local development environment based on DevBox container.\n\n"
|
||
fi
|
||
printf "Alias: r\n"
|
||
echo
|
||
}
|
||
|
||
# :command.normalize_input
|
||
# :command.normalize_input_function
|
||
normalize_input() {
|
||
local arg passthru flags
|
||
passthru=false
|
||
|
||
regex='^--([a-zA-Z0-9_\-]+)=(.+)$'
|
||
regex2='^(-[a-zA-Z0-9])=(.+)$'
|
||
regex3='^-([a-zA-Z0-9][a-zA-Z0-9]+)$'
|
||
|
||
while [[ $# -gt 0 ]]; do
|
||
arg="$1"
|
||
if [[ $passthru == true ]]; then
|
||
input+=("$arg")
|
||
elif [[ $arg =~ $regex ]]; then
|
||
input+=("${BASH_REMATCH[1]}")
|
||
input+=("${BASH_REMATCH[2]}")
|
||
elif [[ $arg =~ $regex2 ]]; then
|
||
input+=("${BASH_REMATCH[1]}")
|
||
input+=("${BASH_REMATCH[2]}")
|
||
elif [[ $arg =~ $regex3 ]]; 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)
|
||
log_info "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
|
||
log_info "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
|
||
log_info "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
|
||
log_info "- \$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
|
||
log_info "environment variables:"
|
||
for name in $sorted_names; do
|
||
# Look up the value based on the name
|
||
log_info "- \$${name} = ${!name:-}"
|
||
done
|
||
fi
|
||
}
|
||
|
||
|
||
install_docker() {
|
||
log_info "Installing Docker..."
|
||
|
||
# Check if Docker is already installed
|
||
if command -v docker &>/dev/null; then
|
||
log_info "Docker is already installed."
|
||
return 0
|
||
fi
|
||
|
||
# Install Docker using the official script
|
||
if command -v curl &>/dev/null || command -v wget &>/dev/null; then
|
||
if command -v curl &>/dev/null; then
|
||
curl -fsSL https://get.docker.com -o get-docker.sh
|
||
elif command -v wget &>/dev/null; then
|
||
wget -qO get-docker.sh https://get.docker.com
|
||
fi
|
||
|
||
if [ -f get-docker.sh ]; then
|
||
sudo sh get-docker.sh
|
||
rm -f get-docker.sh
|
||
return 0
|
||
fi
|
||
fi
|
||
|
||
# Install Docker using package manager
|
||
if command -v apt-get &>/dev/null; then
|
||
sudo apt-get update
|
||
sudo apt-get install -y docker.io
|
||
return 0
|
||
fi
|
||
|
||
if command -v yum &>/dev/null; then
|
||
sudo yum install -y docker
|
||
sudo systemctl start docker
|
||
sudo systemctl enable docker
|
||
return 0
|
||
fi
|
||
|
||
if command -v dnf &>/dev/null; then
|
||
sudo dnf install -y docker
|
||
sudo systemctl start docker
|
||
sudo systemctl enable docker
|
||
return 0
|
||
fi
|
||
|
||
if command -v zypper &>/dev/null; then
|
||
sudo zypper install -y docker
|
||
sudo systemctl start docker
|
||
sudo systemctl enable docker
|
||
return 0
|
||
fi
|
||
|
||
if command -v apk &>/dev/null; then
|
||
sudo apk add docker
|
||
sudo rc-update add docker boot
|
||
sudo service docker start
|
||
return 0
|
||
fi
|
||
|
||
if command -v pacman &>/dev/null; then
|
||
sudo pacman -S --noconfirm docker
|
||
sudo systemctl start docker
|
||
sudo systemctl enable docker
|
||
return 0
|
||
fi
|
||
|
||
if command -v brew &>/dev/null; then
|
||
brew install docker
|
||
return 0
|
||
fi
|
||
|
||
if command -v snap &>/dev/null; then
|
||
sudo snap install docker
|
||
return 0
|
||
fi
|
||
|
||
log_info "ERROR: Unable to install Docker automatically. Please install Docker manually."
|
||
return 1
|
||
}
|
||
|
||
check_docker_running() {
|
||
log_info "Checking if Docker service is running..."
|
||
|
||
# if Docker CLI is installed and Docker daemon is running
|
||
if docker info >/dev/null 2>&1; then
|
||
log_info "Docker is running."
|
||
return 0
|
||
fi
|
||
|
||
# if running on WSL, check for Docker socket
|
||
if grep -qi microsoft /proc/version; then
|
||
log_info "Detected WSL environment. Verifying /var/run/docker.sock..."
|
||
if [ -S /var/run/docker.sock ]; then
|
||
log_info "Docker socket found. Docker should be available via Docker Desktop."
|
||
return 0
|
||
else
|
||
log_error "Docker socket not found in WSL environment."
|
||
return 1
|
||
fi
|
||
fi
|
||
|
||
log_info "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
|
||
log_info "Starting Docker with systemctl..."
|
||
sudo systemctl start docker && log_info "Docker started successfully." && return 0
|
||
fi
|
||
fi
|
||
|
||
if command -v service &>/dev/null; then
|
||
if service --status-all | grep -q "docker"; then
|
||
log_info "Starting Docker with service..."
|
||
sudo service docker start && log_info "Docker started successfully." && return 0
|
||
fi
|
||
fi
|
||
|
||
if command -v snap &>/dev/null && snap list | grep -q "docker"; then
|
||
log_info "Starting Docker with snap..."
|
||
sudo snap start docker && log_info "Docker started successfully." && return 0
|
||
fi
|
||
|
||
log_error "Unable to start Docker automatically. Please start it manually."
|
||
return 1
|
||
}
|
||
|
||
build_local_image() {
|
||
local dockerfile_path="$1"
|
||
log_info "[Build] use Dockerfile: $(grep '^FROM' "$dockerfile_path")"
|
||
|
||
# Check if the image already exists
|
||
docker rmi -f $devbox_full_image 2>/dev/null || true
|
||
|
||
# Build the image
|
||
if ! docker buildx build \
|
||
--platform linux/amd64 \
|
||
--build-arg BUILDARCH="x86-64-v3" \
|
||
--no-cache \
|
||
-t $devbox_full_image \
|
||
-f "$dockerfile_path" . 2>&1 | tee "$WORKING_HOME/build.log"; then
|
||
|
||
exit_with_message " Image build failed, please check the log file: $WORKING_HOME/build.log" 1
|
||
fi
|
||
|
||
# Check if the image is built successfully
|
||
if ! docker inspect $devbox_full_image | grep -q 'amd64'; then
|
||
exit_with_message " Image build failed, please check the log file: $WORKING_HOME/build.log" 1
|
||
fi
|
||
}
|
||
|
||
|
||
# used for repository username and password encoding
|
||
url_encode() {
|
||
echo "$1" | sed 's/@/%40/g'
|
||
}
|
||
|
||
|
||
|
||
###############################################
|
||
# Initialize the development environment
|
||
###############################################
|
||
init_compile_env() {
|
||
|
||
# Update for export environments []
|
||
docker exec -i "$DEVBOX_NAME" bash <<EOF
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Starting DevBox initialization..."
|
||
|
||
# Export environment variables
|
||
export WORKING_HOME="${WORKING_HOME}"
|
||
export FREELEAPS_USERNAME="${FREELEAPS_USERNAME}"
|
||
export FREELEAPS_PASSWORD="${FREELEAPS_PASSWORD}"
|
||
export USE_LOCAL_COMPONENT_VAL="${USE_LOCAL_COMPONENT_VAL}"
|
||
export DEVBOX_BACKEND_PORT="${DEVBOX_BACKEND_PORT}"
|
||
export DEVBOX_FRONTEND_PORT="${DEVBOX_FRONTEND_PORT}"
|
||
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') USE_LOCAL_COMPONENT_VAL: ${USE_LOCAL_COMPONENT_VAL}"
|
||
# Check if the working home directory exists, if not, create it. [:COMPONENT_SETTINGS]
|
||
if [[ "$USE_LOCAL_COMPONENT_VAL" == "true" ]]; then
|
||
# Local component environment variables
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Use local component dev environment."
|
||
cat << 'EOFinner' > /home/devbox/freeleaps/apps/.env
|
||
export MONGODB_NAME=freeleaps2
|
||
export MONGODB_URI=mongodb://freeleaps2-mongodb: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=freeleaps2-rabbitmq
|
||
export RABBITMQ_PORT=5672
|
||
export FREELEAPS_ENV=dev
|
||
export REDIS_URL=redis://freeleaps2-redis:6379/0
|
||
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://devsvc:8007/api/devsvc/
|
||
export FREELEAPS_CHAT_ENDPOINT=http://chat:8012/api/chat/
|
||
export FREELEAPS_CONTENT_ENDPOINT=http://content:8013/api/content/
|
||
export FREELEAPS_NOTIFICATION_ENDPOINT=http://notification:8003/api/notification/
|
||
export FREELEAPS_CENTRAL_STORAGE_ENDPOINT=http://central_storage:8005/api/central_storage/
|
||
export FREELEAPS_AUTHENTICATION_ENDPOINT=http://authentication:8004/api/auth/
|
||
export FREELEAPS_AILAB_ENDPOINT=https://localhost:8009/api/
|
||
export KAFKA_SERVER_URL=''
|
||
export JWT_SECRET_KEY=8f87ca8c3c9c3df09a9c78e0adb0927855568f6072d9efc892534aee35f5867b
|
||
export EMAIL_FROM=freeleaps@freeleaps.com
|
||
export VITE_PROXY_WEBSOCKET_CHAT_URL=ws://localhost:8012
|
||
export VITE_PROXY_API_CHAT_URL=http://localhost:8012
|
||
EOFinner
|
||
|
||
# Update set VITE_PROXY_WEBSOCKET_CHAT_URL and VITE_PROXY_API_CHAT_URL in frontend/.env.development
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Update VITE_PROXY_WEBSOCKET_CHAT_URL and VITE_PROXY_API_CHAT_URL in frontend/.env.development"
|
||
sed -i "s|VITE_PROXY_WEBSOCKET_CHAT_URL=.*|VITE_PROXY_WEBSOCKET_CHAT_URL=ws://chat:8012|g" /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
sed -i "s|VITE_PROXY_API_CHAT_URL=.*|VITE_PROXY_API_CHAT_URL=http://chat:8012|g" /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
|
||
else
|
||
# Online component environment variables
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Use online component dev environment."
|
||
cat << 'EOFinner' > /home/devbox/freeleaps/apps/.env
|
||
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_CHAT_ENDPOINT=https://freeleaps-alpha.com/api/chat/
|
||
export FREELEAPS_CONTENT_ENDPOINT=http://52.149.35.244:8013/api/content/
|
||
export FREELEAPS_NOTIFICATION_ENDPOINT=http://52.149.35.244:8003/api/notification/
|
||
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
|
||
export JWT_SECRET_KEY=ea84edf152976b2fcec12b78aa8e45bc26a5cf0ef61bf16f5c317ae33b3fd8b0
|
||
export REDIS_URL=redis://freeleaps2-redis:6379/0
|
||
export VITE_PROXY_WEBSOCKET_CHAT_URL=wss://freeleaps-alpha.com
|
||
export VITE_PROXY_API_CHAT_URL=https://freeleaps-alpha.com
|
||
EOFinner
|
||
|
||
# Update set VITE_PROXY_WEBSOCKET_CHAT_URL and VITE_PROXY_API_CHAT_URL in frontend/.env.development
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Update VITE_PROXY_WEBSOCKET_CHAT_URL and VITE_PROXY_API_CHAT_URL in frontend/.env.development"
|
||
sed -i "s|VITE_PROXY_WEBSOCKET_CHAT_URL=.*|VITE_PROXY_WEBSOCKET_CHAT_URL=wss://freeleaps-alpha.com|g" /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
sed -i "s|VITE_PROXY_API_CHAT_URL=.*|VITE_PROXY_API_CHAT_URL=https://freeleaps-alpha.com|g" /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
|
||
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Online component dev environment variables set."
|
||
fi
|
||
|
||
if true ; then
|
||
# Git configuration to skip worktree for .env file
|
||
pushd /home/devbox/freeleaps > /dev/null
|
||
git config --global core.sparseCheckout true
|
||
git config --global --add safe.directory /home/devbox/freeleaps
|
||
|
||
git update-index --skip-worktree /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
|
||
popd > /dev/null
|
||
|
||
# Load the environment variables
|
||
source /home/devbox/freeleaps/apps/.env
|
||
|
||
# Create the logs directory if it does not exist
|
||
mkdir -p /home/devbox/logs
|
||
|
||
# Install the net-tools package for ifconfig
|
||
sudo apt install net-tools -y
|
||
|
||
#####################################
|
||
# Initialize the backend environment, including Python3.11 and venv
|
||
#####################################
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Check Python3.11 environment..."
|
||
sudo apt update
|
||
sudo apt install python3.11 python3.11-venv -y
|
||
if ! command -v python3.11 &>/dev/null; then
|
||
echo
|
||
echo "============================================"
|
||
echo
|
||
echo "[ERROR] Python3.11 is failed to install, please check the log."
|
||
echo
|
||
echo "============================================"
|
||
echo
|
||
exit 1
|
||
fi
|
||
|
||
echo " [INIT] Upgrade pip and ensurepip..."
|
||
python3.11 -m ensurepip --upgrade
|
||
python3.11 -m pip install --upgrade pip
|
||
|
||
# If the venv_t directory does not exist, create it
|
||
pushd /home/devbox/freeleaps/apps > /dev/null
|
||
|
||
if [ ! -d "venv_t" ]; then
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Create Python3.11 virtual environment..."
|
||
python3.11 -m venv venv_t || { echo "[ERROR] Python3.11 virtual environment creation failed."; exit 1; }
|
||
sleep 5
|
||
fi
|
||
popd > /dev/null
|
||
|
||
# Install pipreqs for generating requirements.txt
|
||
python3.11 -m pip install pipreqs
|
||
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Backend environment initialization completed."
|
||
|
||
#####################################
|
||
# Initialize the frontend environment, including Node.js and npm
|
||
#####################################
|
||
|
||
pushd /home/devbox/freeleaps/frontend > /dev/null
|
||
|
||
npm update
|
||
|
||
# 1️⃣ Install pnpm globally
|
||
npm install -g pnpm
|
||
|
||
# 2️⃣ Verify installation
|
||
pnpm --version
|
||
|
||
# 3️⃣ Clean up old dependencies
|
||
if [ -f "pnpm-lock.yaml" ]; then
|
||
cp pnpm-lock.yaml /tmp/pnpm-lock.yaml.bak
|
||
fi
|
||
|
||
# Remove node_modules directory
|
||
rm -rf node_modules
|
||
|
||
# 4️⃣ Install dependencies
|
||
pnpm store prune
|
||
|
||
# 4️⃣ Install dependencies (ensuring lockfile updates)
|
||
pnpm install --no-frozen-lockfile \\
|
||
--shamefully-hoist \\
|
||
--link-workspace-packages false \\
|
||
--store-dir /home/tmp/.pnpm-store
|
||
|
||
# 4️⃣ Build the frontend
|
||
pnpm run build
|
||
|
||
popd > /dev/null
|
||
|
||
fi
|
||
EOF
|
||
|
||
}
|
||
|
||
stop_backend_service() {
|
||
echo "[BACKEND] $(date '+%Y-%m-%d %H:%M:%S') Stopping backend service..."
|
||
devbox_container_id_file_path="${WORKING_HOME}/.devbox-instance"
|
||
DEVBOX_NAME=$(cat "$devbox_container_id_file_path")
|
||
|
||
docker exec -i "$DEVBOX_NAME" bash <<EOF
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Stopping backend service..."
|
||
if [ -f /home/devbox/.backend.pid ]; then
|
||
BACKEND_PID=\$(cat /home/devbox/.backend.pid)
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Killing backend service PID: \$BACKEND_PID"
|
||
kill -9 \$BACKEND_PID
|
||
rm -f /home/devbox/.backend.pid
|
||
else
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Backend service is not running."
|
||
fi
|
||
EOF
|
||
|
||
}
|
||
|
||
stop_frontend_service() {
|
||
devbox_container_id_file_path="${WORKING_HOME}/.devbox-instance"
|
||
DEVBOX_NAME=$(cat "$devbox_container_id_file_path")
|
||
|
||
docker exec -i "$DEVBOX_NAME" bash <<EOF
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Stopping frontend service..."
|
||
if [ -f /home/devbox/.frontend.pid ]; then
|
||
FRONTEND_PID=\$(cat /home/devbox/.frontend.pid)
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Killing frontend service PID: \$FRONTEND_PID"
|
||
kill -9 \$FRONTEND_PID
|
||
rm -f /home/devbox/.frontend.pid
|
||
else
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Frontend service is not running."
|
||
fi
|
||
EOF
|
||
|
||
}
|
||
|
||
|
||
###############################################
|
||
# Backend compilation and startup logic
|
||
###############################################
|
||
compile_backend_service() {
|
||
|
||
echo "[BACKEND] $(date '+%Y-%m-%d %H:%M:%S') Start backend service at home path $WORKING_HOME."
|
||
|
||
devbox_container_id_file_path="${WORKING_HOME}/.devbox-instance"
|
||
DEVBOX_NAME=$(cat "$devbox_container_id_file_path")
|
||
|
||
devbox_backend_port_file_path="${WORKING_HOME}/.devbox-backend-port"
|
||
DEVBOX_BACKEND_PORT=$(cat "$devbox_backend_port_file_path")
|
||
|
||
echo "[BACKEND] $(date '+%Y-%m-%d %H:%M:%S') Start backend service from $DEVBOX_NAME."
|
||
|
||
docker exec -i "$DEVBOX_NAME" bash <<EOF
|
||
# Check if /home/devbox/.backend.pid exits
|
||
if [ -f /home/devbox/.backend.pid ]; then
|
||
backend_pid=\$(cat /home/devbox/.backend.pid)
|
||
if [ -n "\$backend_pid" ]; then
|
||
# Check if the backend service is running
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Backend service is running with PID: \$backend_pid"
|
||
if ps -p "\$backend_pid" > /dev/null; then
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
echo "[BACKEND] [WARNING] Backend service is running with PID: \$backend_pid, if you want to restart, please stop it first or run devbox restart -e backend."
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
exit 0
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Starting backend compilation and startup..."
|
||
|
||
pushd /home/devbox/freeleaps/apps > /dev/null
|
||
|
||
|
||
# Record the git status baseline before compilation
|
||
baseline_backend=\$(mktemp)
|
||
git config --global --add safe.directory /home/devbox/freeleaps
|
||
git status -s > "\$baseline_backend"
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Recorded baseline before compilation: \$baseline_backend"
|
||
|
||
|
||
# CHeck if the virtual environment is created
|
||
if [ ! -f "venv_t/bin/activate" ]; then
|
||
echo
|
||
echo "============================================"
|
||
echo
|
||
echo "[BACKEND] [ERROR] The virtual environment cannot be created. Please check the log for more information."
|
||
echo
|
||
echo "============================================"
|
||
echo
|
||
|
||
# rm baseline_backend
|
||
rm -f "\$baseline_backend"
|
||
|
||
exit 1
|
||
fi
|
||
|
||
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Start to activate virtual environment."
|
||
|
||
source venv_t/bin/activate
|
||
source /home/devbox/freeleaps/apps/.env
|
||
|
||
# Verify the virtual environment is activated
|
||
if [[ "\$VIRTUAL_ENV" != "" ]]; then
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Virtual environment activate: \$VIRTUAL_ENV"
|
||
else
|
||
echo
|
||
echo "============================================"
|
||
echo
|
||
echo "[BACKEND] [ERROR] The virtual environment cannot be startup \$VIRTUAL_ENV, please check the log for more information."
|
||
echo
|
||
echo "============================================"
|
||
echo
|
||
rm -f "\$baseline_backend"
|
||
|
||
exit 1
|
||
fi
|
||
|
||
# Check if it's the first time by verifying if the backend dependencies have been installed
|
||
if [ ! -f "/home/devbox/.backend_deps_installed" ]; then
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Install backend dependencies..."
|
||
pip install -r /home/devbox/freeleaps/apps/requirements.txt
|
||
if ! pip show async_timeout; then
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') async_timeout is missing. Installing..."
|
||
pip install async_timeout
|
||
fi
|
||
|
||
# Generate /home/devbox/tmp/requirements.txt
|
||
mkdir -p /home/devbox/tmp
|
||
|
||
## Backup the requirements.txt file
|
||
cp /home/devbox/freeleaps/apps/requirements.txt /home/devbox/tmp/requirements.txt.bak
|
||
|
||
|
||
ORIGINAL_REQ="/home/devbox/freeleaps/apps/requirements.txt"
|
||
NEW_REQ="/home/devbox/tmp/requirements.txt"
|
||
|
||
# Check if /home/devbox/tmp/requirements.txt exists, if yes, remove it
|
||
if [ -f "/home/devbox/tmp/requirements.txt" ]; then
|
||
rm /home/devbox/tmp/requirements.txt
|
||
fi
|
||
|
||
# Generate /home/devbox/tmp/requirements.txt
|
||
pipreqs /home/devbox/freeleaps/apps --ignore venv_t --force --use-local --savepath /home/devbox/tmp/requirements.txt
|
||
|
||
if [ ! -f "\$ORIGINAL_REQ" ]; then
|
||
mv "\$NEW_REQ" "\$ORIGINAL_REQ"
|
||
else
|
||
IS_NEW_REQ_ADDED=0
|
||
while IFS= read -r line; do
|
||
# Revome the version number from the line
|
||
pkg=\$(echo "\$line" | cut -d '=' -f 1 | tr -d ' ')
|
||
# Check if the package is already in the requirements.txt file
|
||
if ! grep -i -E "^\${pkg}([=]|$)" "\$ORIGINAL_REQ" > /dev/null; then
|
||
echo "\$line" >> "\$ORIGINAL_REQ"
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Added package: \${pkg}"
|
||
IS_NEW_REQ_ADDED=1
|
||
else
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Package \${pkg} already exists in requirements.txt"
|
||
fi
|
||
done < "\$NEW_REQ"
|
||
fi
|
||
|
||
|
||
|
||
if [ \$IS_NEW_REQ_ADDED -eq 1 ]; then
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Reinstalling dependencies..."
|
||
pip install -r /home/devbox/freeleaps/apps/requirements.txt
|
||
fi
|
||
# Undo update for /home/devbox/freeleaps/apps/requirements.txt
|
||
rm /home/devbox/freeleaps/apps/requirements.txt
|
||
mv /home/devbox/tmp/requirements.txt.bak /home/devbox/freeleaps/apps/requirements.txt
|
||
|
||
touch /home/devbox/.backend_deps_installed
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Run backend service..."
|
||
./start_webapi.sh > /home/devbox/logs/backend.logs 2>&1 &
|
||
else
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Backend dependencies already installed. Skipping installation."
|
||
# Check if all dependencies are installed, if not, install them
|
||
if ! pip check; then
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Some dependencies are missing. Reinstalling..."
|
||
pip install -r /home/devbox/freeleaps/apps/requirements.txt
|
||
fi
|
||
|
||
# pip install async_timeout if not installed
|
||
if ! pip show async_timeout; then
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') async_timeout is missing. Installing..."
|
||
pip install async_timeout
|
||
fi
|
||
|
||
|
||
# Generate /home/devbox/tmp/requirements.txt
|
||
mkdir -p /home/devbox/tmp
|
||
|
||
## Backup the requirements.txt file
|
||
cp /home/devbox/freeleaps/apps/requirements.txt /home/devbox/tmp/requirements.txt.bak
|
||
|
||
|
||
ORIGINAL_REQ="/home/devbox/freeleaps/apps/requirements.txt"
|
||
NEW_REQ="/home/devbox/tmp/requirements.txt"
|
||
|
||
# Check if /home/devbox/tmp/requirements.txt exists, if yes, remove it
|
||
if [ -f "/home/devbox/tmp/requirements.txt" ]; then
|
||
rm /home/devbox/tmp/requirements.txt
|
||
fi
|
||
|
||
pipreqs /home/devbox/freeleaps/apps --ignore venv_t --force --use-local --savepath /home/devbox/tmp/requirements.txt
|
||
if [ ! -f "\$ORIGINAL_REQ" ]; then
|
||
mv "\$NEW_REQ" "\$ORIGINAL_REQ"
|
||
else
|
||
IS_NEW_REQ_ADDED=0
|
||
while IFS= read -r line; do
|
||
# Revome the version number from the line
|
||
pkg=\$(echo "\$line" | cut -d '=' -f 1 | tr -d ' ')
|
||
# Check if the package is already in the requirements.txt file
|
||
if ! grep -i -E "^\${pkg}([=]|$)" "\$ORIGINAL_REQ" > /dev/null; then
|
||
echo "\$line" >> "\$ORIGINAL_REQ"
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Added package: \${pkg}"
|
||
IS_NEW_REQ_ADDED=1
|
||
else
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Package \${pkg} already exists in requirements.txt"
|
||
fi
|
||
done < "\$NEW_REQ"
|
||
fi
|
||
|
||
if [ \$IS_NEW_REQ_ADDED -eq 1 ]; then
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Reinstalling dependencies..."
|
||
pip install -r /home/devbox/freeleaps/apps/requirements.txt
|
||
fi
|
||
|
||
# Undo update for /home/devbox/freeleaps/apps/requirements.txt
|
||
rm /home/devbox/freeleaps/apps/requirements.txt
|
||
mv /home/devbox/tmp/requirements.txt.bak /home/devbox/freeleaps/apps/requirements.txt
|
||
|
||
# Check if the backend service is already running
|
||
SERVICE_API_ACCESS_PORT=\$(cat /home/devbox/.devbox-backend-port)
|
||
uvicorn freeleaps.webapi.main:app --reload --host 0.0.0.0 --port \$SERVICE_API_ACCESS_PORT > /home/devbox/logs/backend.logs 2>&1 &
|
||
fi
|
||
|
||
# Remove tempory file /home/devbox/tmp/requirements.txt if it exists
|
||
if [ -f "/home/devbox/tmp/requirements.txt" ]; then
|
||
rm /home/devbox/tmp/requirements.txt
|
||
fi
|
||
|
||
# Check the health of the backend service: poll to detect HTTP status
|
||
MAX_ATTEMPTS=30
|
||
ATTEMPT=0
|
||
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Checking backend service startup..."
|
||
while [ \$ATTEMPT -lt \$MAX_ATTEMPTS ]; do
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Backend url http://localhost:${DEVBOX_BACKEND_PORT}/docs"
|
||
HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${DEVBOX_BACKEND_PORT}/docs")
|
||
if [ "\$HTTP_CODE" -eq 200 ]; then
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Service started successfully (HTTP \$HTTP_CODE)"
|
||
# Get the backend service PID by checking the process port with netstat -tulnp | grep ${DEVBOX_BACKEND_PORT}
|
||
BACKEND_PID=\$(netstat -tulnp 2>/dev/null | grep "${DEVBOX_BACKEND_PORT}" | awk '{print \$7}' | awk -F'/' '{print \$1}')
|
||
|
||
echo "\$BACKEND_PID" > /home/devbox/.backend.pid
|
||
break
|
||
else
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Waiting for backend service... Attempt \$((ATTEMPT+1)) with HTTP \$HTTP_CODE"
|
||
ATTEMPT=\$((ATTEMPT+1))
|
||
sleep 10
|
||
fi
|
||
done
|
||
if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
echo
|
||
echo "[BACKEND] [ERROR] Backend service startup failed. Please check the logs for more information. Logs: ${WORKING_HOME}/logs/backend.logs"
|
||
echo
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
exit 1
|
||
fi
|
||
|
||
# Restore git changes caused by compilation
|
||
current_backend=\$(mktemp)
|
||
git config --global --add safe.directory /home/devbox/freeleaps
|
||
git status -s > "\$current_backend"
|
||
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Checking git changes after compilation..."
|
||
while read -r line; do
|
||
file=\$(echo "\$line" | awk '{print \$2}')
|
||
if ! grep -q "[[:space:]]\${file}$" "\$baseline_backend"; then
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Restore file \$file"
|
||
git reset HEAD "\$file"
|
||
git checkout -- "\$file"
|
||
fi
|
||
done < "\$current_backend"
|
||
rm "\$baseline_backend" "\$current_backend"
|
||
|
||
popd > /dev/null
|
||
echo "[BACKEND] \$(date '+%Y-%m-%d %H:%M:%S') Backend compilation and startup completed."
|
||
EOF
|
||
}
|
||
|
||
###############################################
|
||
# Frontend compilation and startup logic
|
||
###############################################
|
||
compile_frontend_service() {
|
||
echo "[FRONTEND] $(date '+%Y-%m-%d %H:%M:%S') start frontend service at home path $WORKING_HOME."
|
||
|
||
devbox_container_id_file_path="${WORKING_HOME}/.devbox-instance"
|
||
if [ ! -f "$devbox_container_id_file_path" ]; then
|
||
# Check if devbox container exists by checking the container name of devbox
|
||
if ! docker ps -a --format "{{.Names}}" | grep -q "devbox"; then
|
||
exit_with_message "DevBox container is not running. Please start the DevBox container first." 1
|
||
fi
|
||
fi
|
||
|
||
DEVBOX_NAME=$(cat "$devbox_container_id_file_path")
|
||
|
||
DEVBOX_FRONTEND_PORT=$(cat "$WORKING_HOME/.devbox-frontend-port")
|
||
|
||
docker exec -i "$DEVBOX_NAME" bash <<EOF
|
||
|
||
# Check if /home/devbox/.frontend.pid exits
|
||
if [ -f /home/devbox/.frontend.pid ]; then
|
||
frontend_pid=\$(cat /home/devbox/.frontend.pid)
|
||
if [ -n "\$frontend_pid" ]; then
|
||
# Check if the frontend service is running
|
||
if ps -p "\$frontend_pid" > /dev/null; then
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
echo "[FRONTEND] [WARNING] Frontend service is running with PID: \$frontend_pid, if you want to restart, please stop it first or run devbox restart -e frontend."
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
exit 1
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
USE_LOCAL_COMPONENT_FLAG="/home/devbox/.use-local-component"
|
||
|
||
USE_LOCAL_COMPONENT_VAL="false"
|
||
if [ -f "\$USE_LOCAL_COMPONENT_FLAG" ]; then
|
||
# Read the value from the file
|
||
USE_LOCAL_COMPONENT_VAL=\$(cat "\$USE_LOCAL_COMPONENT_FLAG")
|
||
fi
|
||
|
||
pushd /home/devbox/freeleaps/frontend > /dev/null
|
||
|
||
# Record the git status baseline before compilation
|
||
baseline_frontend=\$(mktemp)
|
||
git config --global --add safe.directory /home/devbox/freeleaps
|
||
git status -s > "\$baseline_frontend"
|
||
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Recorded baseline before compilation: \$baseline_frontend"
|
||
|
||
# Check if the frontend service is already running according to the package.json and pnpm-lock.yaml files timestamps
|
||
|
||
# Get the timestamps of the package.json and pnpm-lock.yaml files
|
||
lock_time=\$(stat -c "%Y" pnpm-lock.yaml)
|
||
modules_time=\$(stat -c "%Y" node_modules)
|
||
|
||
# Calculate the absolute value of the time difference between the lock file and the modules file
|
||
time_diff=\$(( lock_time - modules_time ))
|
||
if [ \$time_diff -lt 0 ]; then
|
||
time_diff=\$(( -time_diff ))
|
||
fi
|
||
|
||
# Set the threshold for the time difference
|
||
threshold=150
|
||
|
||
# Frontend environment variable settings. [:COMPONENT_SETTINGS]
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') USE_LOCAL_COMPONENT_VAL: \$USE_LOCAL_COMPONENT_VAL"
|
||
if [[ "\$USE_LOCAL_COMPONENT_VAL" == "true" ]]; then
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Use local component dev environment."
|
||
sed -i 's#VITE_PROXY_WEBSOCKET_CHAT_URL=ws://localhost:8012#VITE_PROXY_WEBSOCKET_CHAT_URL=ws://chat:8012#g' /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
sed -i 's#VITE_PROXY_API_CHAT_URL=http://localhost:8012#VITE_PROXY_API_CHAT_URL=http://chat:8012#g' /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
else
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Use online component dev environment."
|
||
sed -i 's#VITE_PROXY_WEBSOCKET_CHAT_URL=wss://localhost:8012#VITE_PROXY_WEBSOCKET_CHAT_URL=wss://freeleaps-alpha.com#g' /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
sed -i 's#VITE_PROXY_API_CHAT_URL=http://localhost:8012#VITE_PROXY_API_CHAT_URL=https://freeleaps-alpha.com#g' /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
fi
|
||
|
||
pushd /home/devbox/freeleaps > /dev/null
|
||
git update-index --skip-worktree /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
popd > /dev/null
|
||
|
||
if [[ ! -d "node_modules" || "package.json" -nt "node_modules" || \$time_diff -gt \$threshold ]]; then
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Installing/Updating frontend dependencies..."
|
||
|
||
# Clean up old dependencies
|
||
rm -rf node_modules
|
||
|
||
# Clean up old pnpm store
|
||
pnpm store prune
|
||
|
||
# Backup the pnpm-lock.yaml file
|
||
if [ -f "pnpm-lock.yaml" ]; then
|
||
mv pnpm-lock.yaml /tmp/pnpm-lock.yaml.bak
|
||
fi
|
||
|
||
# if /home/tmp/.pnpm-store exists, remove it
|
||
if [ -d "/home/tmp/.pnpm-store" ]; then
|
||
rm -rf /home/tmp/.pnpm-store
|
||
fi
|
||
|
||
# Install dependencies
|
||
pnpm install --no-frozen-lockfile \\
|
||
--shamefully-hoist \\
|
||
--link-workspace-packages false \\
|
||
--store-dir /home/tmp/.pnpm-store || {
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
echo "[FRONTEND] [ERROR] Failed to install dependencies. Please check the logs for more information."
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
|
||
# rm baseline_frontend if it exists
|
||
if [ -f "\$baseline_frontend" ]; then
|
||
rm "\$baseline_frontend"
|
||
fi
|
||
exit 1
|
||
}
|
||
fi
|
||
|
||
# Check pnpm result if node_modules exists or if node_modules has not file inside and contains the required dependencies
|
||
if [[ ! -d "node_modules" || ! -f "node_modules/.bin/vite" ]]; then
|
||
# Check if the frontend dependencies are installed correctly
|
||
pnpm install --no-frozen-lockfile || {
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
echo "[FRONTEND] [ERROR] Frontend dependencies are not installed correctly. Please check the logs for more information."
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
|
||
if [ -f "\$baseline_frontend" ]; then
|
||
rm "\$baseline_frontend"
|
||
fi
|
||
exit 1
|
||
}
|
||
|
||
# Check if the frontend dependencies are installed correctly
|
||
if [[ ! -d "node_modules" || ! -f "node_modules/.bin/vite" ]]; then
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
echo "[FRONTEND] [ERROR] Frontend dependencies are not installed correctly. Please check the logs for more information."
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
|
||
if [ -f "\$baseline_frontend" ]; then
|
||
rm "\$baseline_frontend"
|
||
fi
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Starting frontend compilation and startup..."
|
||
|
||
# Start the frontend service
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Start frontend service..."
|
||
nohup pnpm run dev > /home/devbox/logs/frontend.logs 2>&1 &
|
||
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Frontend service started. Logs: /home/devbox/logs/frontend.logs"
|
||
|
||
# Check the health of the frontend service: poll to detect HTTP status
|
||
MAX_ATTEMPTS=30
|
||
ATTEMPT=0
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Checking frontend service startup..."
|
||
while [ \$ATTEMPT -lt \$MAX_ATTEMPTS ]; do
|
||
HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${DEVBOX_FRONTEND_PORT}/")
|
||
if [ "\$HTTP_CODE" -eq 200 ]; then
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Service started successfully (HTTP \$HTTP_CODE)"
|
||
|
||
# Get the backend service PID by checking the process port with netstat -tulnp | grep ${DEVBOX_FRONTEND_PORT}
|
||
FRONTEND_PID=\$(netstat -tulnp 2>/dev/null | grep "${DEVBOX_FRONTEND_PORT}" | awk '{print \$7}' | awk -F'/' '{print \$1}')
|
||
|
||
echo "\$FRONTEND_PID" > /home/devbox/.frontend.pid
|
||
break
|
||
else
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Waiting for frontend service... Attempt \$((ATTEMPT+1))"
|
||
ATTEMPT=\$((ATTEMPT+1))
|
||
sleep 10
|
||
fi
|
||
done
|
||
|
||
# if /tmp/pnpm-lock.yaml.bak exists, restore it
|
||
if [ -f "/tmp/pnpm-lock.yaml.bak" ];
|
||
then
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Restore pnpm-lock.yaml..."
|
||
rm -rf pnpm-lock.yaml
|
||
mv /tmp/pnpm-lock.yaml.bak pnpm-lock.yaml
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') pnpm-lock.yaml restored."
|
||
fi
|
||
|
||
# Restore git changes caused by compilation
|
||
current_frontend=\$(mktemp)
|
||
|
||
git config --global --add safe.directory /home/devbox/freeleaps
|
||
git status -s > "\$current_frontend"
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Checking git changes after compilation..."
|
||
while read -r line; do
|
||
file=\$(echo "\$line" | awk '{print \$2}')
|
||
if ! grep -q "[[:space:]]\${file}$" "\$baseline_frontend"; then
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Restore file \$file"
|
||
git reset HEAD "\$file"
|
||
git checkout -- "\$file"
|
||
fi
|
||
done < "\$current_frontend"
|
||
rm "\$baseline_frontend" "\$current_frontend"
|
||
|
||
popd > /dev/null
|
||
|
||
if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
echo "[FRONTEND] [ERROR] Frontend service startup failed. Please check the logs for more information. Logs: ${WORKING_HOME}/logs/frontend.logs"
|
||
echo
|
||
echo "============================================================================================"
|
||
echo
|
||
exit 1
|
||
fi
|
||
|
||
# Frontend environment variable settings. [:COMPONENT_SETTINGS]
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') USE_LOCAL_COMPONENT_VAL: \$USE_LOCAL_COMPONENT_VAL"
|
||
if [[ "\$USE_LOCAL_COMPONENT_VAL" == "true" ]]; then
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Use local component dev environment."
|
||
sed -i 's#VITE_PROXY_WEBSOCKET_CHAT_URL=.*#VITE_PROXY_WEBSOCKET_CHAT_URL=ws://chat:8012#g' /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
sed -i 's#VITE_PROXY_API_CHAT_URL=.*#VITE_PROXY_API_CHAT_URL=http://chat:8012#g' /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
else
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Use online component dev environment."
|
||
sed -i "s|VITE_PROXY_WEBSOCKET_CHAT_URL=.*|VITE_PROXY_WEBSOCKET_CHAT_URL=wss://freeleaps-alpha.com|g" /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
sed -i "s|VITE_PROXY_API_CHAT_URL=.*|VITE_PROXY_API_CHAT_URL=https://freeleaps-alpha.com|g" /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
fi
|
||
|
||
echo
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Frontend compilation and startup completed."
|
||
echo
|
||
|
||
# Check frontend git checkout status
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Checking git status after compilation..."
|
||
pushd /home/devbox/freeleaps/frontend > /dev/null
|
||
git config --global --add safe.directory /home/devbox/freeleaps
|
||
git status -s
|
||
if [ -n "\$(git status --porcelain)" ]; then
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Uncommitted changes found. Resetting..."
|
||
git reset --hard HEAD
|
||
else
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') No uncommitted changes found."
|
||
fi
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Checking for untracked files..."
|
||
|
||
EOF
|
||
}
|
||
|
||
reset_freeleaps_repo() {
|
||
echo "[INIT] $(date '+%Y-%m-%d %H:%M:%S') Resetting FreeLeaps repository..."
|
||
devbox_container_id_file_path="${WORKING_HOME}/.devbox-instance"
|
||
DEVBOX_NAME=$(cat "$devbox_container_id_file_path")
|
||
|
||
docker exec -i "$DEVBOX_NAME" bash <<EOF
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Resetting FreeLeaps repository..."
|
||
pushd /home/devbox/freeleaps > /dev/null
|
||
git config --global --add safe.directory /home/devbox/freeleaps
|
||
git reset --hard HEAD
|
||
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Checking for uncommitted changes..."
|
||
git status -s
|
||
if [ -n "\$(git status --porcelain)" ]; then
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Uncommitted changes found. Resetting..."
|
||
git reset --hard HEAD
|
||
else
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') No uncommitted changes found."
|
||
fi
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') Checking for untracked files..."
|
||
|
||
popd > /dev/null
|
||
echo "[INIT] \$(date '+%Y-%m-%d %H:%M:%S') FreeLeaps repository reset completed."
|
||
|
||
USE_LOCAL_COMPONENT_FLAG="/home/devbox/.use-local-component"
|
||
USE_LOCAL_COMPONENT_VAL="false"
|
||
if [ -f "\$USE_LOCAL_COMPONENT_FLAG" ]; then
|
||
# Read the value from the file
|
||
USE_LOCAL_COMPONENT_VAL=\$(cat "\$USE_LOCAL_COMPONENT_FLAG")
|
||
fi
|
||
|
||
if [[ "\$USE_LOCAL_COMPONENT_VAL" == "true" ]]; then
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Use local component dev environment."
|
||
sed -i 's#VITE_PROXY_WEBSOCKET_CHAT_URL=.*#VITE_PROXY_WEBSOCKET_CHAT_URL=ws://chat:8012#g' /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
sed -i 's#VITE_PROXY_API_CHAT_URL=.*#VITE_PROXY_API_CHAT_URL=http://chat:8012#g' /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
else
|
||
echo "[FRONTEND] \$(date '+%Y-%m-%d %H:%M:%S') Use online component dev environment."
|
||
sed -i 's#VITE_PROXY_WEBSOCKET_CHAT_URL=.*#VITE_PROXY_WEBSOCKET_CHAT_URL=wss://freeleaps-alpha.com#g' /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
sed -i 's#VITE_PROXY_API_CHAT_URL=http://localhost:8012#VITE_PROXY_API_CHAT_URL=https://freeleaps-alpha.com#g' /home/devbox/freeleaps/frontend/freeleaps/.env.development
|
||
fi
|
||
|
||
EOF
|
||
}
|
||
|
||
# :command.command_functions
|
||
# :command.function
|
||
devbox_init_command() {
|
||
log_info "[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 FREELEAPS_COMPONENTS="$args_freeleaps_components" # --freeleaps-components
|
||
|
||
local USE_CUSTOM_REPOSITORY="$args_use_custom_repository" # --use-custom-repository
|
||
|
||
# --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 FREELEAPS_COMPONENTS="$(get_arg '--freeleaps-components')"
|
||
local USE_CUSTOM_REPOSITORY="$(get_arg '--use-custom-repository')"
|
||
|
||
local FORCE_INIT="$(get_arg '--force')"
|
||
|
||
local is_pull_all_components=true
|
||
# set local components to content of DEVBOX_COMPONENTS
|
||
local components=("${DEVBOX_COMPONENTS[@]}")
|
||
local start_components=()
|
||
|
||
# Check if using local components
|
||
USE_LOCAL_COMPONENT_VAL=false
|
||
if [[ "$(lower "$USE_LOCAL_COMPONENT")" == "true" ]]; then
|
||
USE_LOCAL_COMPONENT_VAL=true
|
||
fi
|
||
|
||
# if use online components, check if any component image repo is specified
|
||
if [[ $USE_LOCAL_COMPONENT_VAL == false ]]; then
|
||
is_pull_all_components=false
|
||
fi
|
||
|
||
# split FREELEAPS_COMPONENTS
|
||
freeleaps_components=()
|
||
if [[ -n "$FREELEAPS_COMPONENTS" ]]; then
|
||
freeleaps_components=($(echo "$FREELEAPS_COMPONENTS" | tr ',' ' '))
|
||
fi
|
||
|
||
# Check if freeleaps_components is not empty, then check if freeleaps_components is valid component
|
||
if [ ${#freeleaps_components[@]} -gt 0 ]; then
|
||
for component in "${freeleaps_components[@]}"; do
|
||
found=false
|
||
for valid_component in "${components[@]}"; do
|
||
if [ "$component" = "$valid_component" ]; then
|
||
found=true
|
||
break
|
||
fi
|
||
done
|
||
if [ "$found" = false ]; then
|
||
exit_with_message " Invalid component: $component, please check the component name." 1
|
||
fi
|
||
done
|
||
|
||
start_components=("${freeleaps_components[@]}")
|
||
else
|
||
start_components=("${components[@]}")
|
||
fi
|
||
|
||
log_info "init arch value is : $ARCH "
|
||
|
||
# If is_pull_all_components is true, then pull all components
|
||
if [[ "$is_pull_all_components" == true ]]; then
|
||
start_components=("${components[@]}")
|
||
log_info "Pulling all components..."
|
||
log_info "start components: ${start_components[@]}"
|
||
fi
|
||
|
||
# Remove duplicated components
|
||
start_components=($(echo "${start_components[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
|
||
|
||
echo "===================================================== "
|
||
log_info "Parameters:"
|
||
log_info " OS = $OS"
|
||
log_info " ARCH = $ARCH"
|
||
log_info " DEVBOX_NAME = $DEVBOX_NAME"
|
||
log_info " DEVBOX_PORT = $DEVBOX_PORT"
|
||
log_info " DEVBOX_FRONTEND_PORT = $DEVBOX_FRONTEND_PORT"
|
||
log_info " DEVBOX_BACKEND_PORT = $DEVBOX_BACKEND_PORT"
|
||
log_info " DEVBOX_REPO = $DEVBOX_REPO"
|
||
log_info " DEVBOX_IMAGE = $DEVBOX_IMAGE"
|
||
log_info " DEVBOX_TAG = $DEVBOX_TAG"
|
||
log_info " WORKING_HOME = $WORKING_HOME"
|
||
log_info " FREELEAPS_USERNAME= $FREELEAPS_USERNAME"
|
||
log_info " (FREELEAPS_PASSWORD is hidden for security)"
|
||
log_info " USE_LOCAL_COMPONENT= $USE_LOCAL_COMPONENT"
|
||
log_info " FREELEAPS_COMPONENTS= ${start_components[@]}"
|
||
log_info " 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
|
||
exit_with_message " Unsupported OS: $OS, please check the OS." 1
|
||
fi
|
||
|
||
# Auto detected $OS
|
||
if [[ "$OS" == "auto" ]]; then
|
||
log_info "Auto detecting OS..."
|
||
OS="$(detect_os)"
|
||
log_info "Detected OS: $OS"
|
||
fi
|
||
|
||
if [[ "$ARCH" != "auto" && "$ARCH" != "amd64" && "$ARCH" != "arm64" ]]; then
|
||
exit_with_message " Unsupported architecture: $ARCH, please check the architecture." 1
|
||
fi
|
||
|
||
# Check ARCH match current device
|
||
ARCH_MICRO=""
|
||
if [[ "$ARCH" == "auto" ]]; then
|
||
ARCH="$(uname -m)"
|
||
if [[ "$ARCH" == "x86_64" ]]; then
|
||
# Check if the CPU supports AVX2
|
||
if grep -q avx2 /proc/cpuinfo; then
|
||
ARCH="amd64"
|
||
ARCH_MICRO="v3"
|
||
log_info "Detected AMD64 architecture."
|
||
else
|
||
ARCH="amd64"
|
||
fi
|
||
elif [[ "$ARCH" == "aarch64" ]] || [[ "$ARCH" == "arm64" ]]; then
|
||
ARCH="arm64"
|
||
fi
|
||
fi
|
||
|
||
component_tag="latest-linux-arm64"
|
||
if [[ "$ARCH" == "amd64" ]]; then
|
||
component_tag="latest-linux-amd64"
|
||
fi
|
||
|
||
# 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
|
||
# -------------------------------------------------------------------
|
||
# 3.1.1.install docker and check docker running
|
||
# -------------------------------------------------------------------
|
||
if ! install_docker; then
|
||
exit_with_message " Failed to install Docker or Docker service is not running. Please install Docker and start Docker service." 1
|
||
fi
|
||
|
||
if ! check_docker_running; then
|
||
exit_with_message " Docker service is not running. Please start Docker service." 1
|
||
fi
|
||
|
||
sudo usermod -aG docker $USER
|
||
|
||
sudo apt-get update -y
|
||
sudo apt-get install docker-compose -y
|
||
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
|
||
exit_with_message " Insufficient disk space (need >10GB). Please free up some space." 1
|
||
fi
|
||
|
||
# 3.3 WORKING_HOME Check
|
||
if ! mkdir -p "$WORKING_HOME" 2>/dev/null; then
|
||
exit_with_message " Can't create or write to WORKING_HOME: $WORKING_HOME, please check the path." 1
|
||
fi
|
||
|
||
# 3.4 Network to docker.com(sample:ping docker.com)
|
||
if ! ping -c 1 docker.com &>/dev/null; then
|
||
exit_with_message " Network to Docker.com is not available. Please check your network connection." 1
|
||
fi
|
||
|
||
# 3.5 Check if the user has permission to write to WORKING_HOME
|
||
if [[ -f "$WORKING_HOME/.devbox-instance" && -z "$FORCE_INIT" ]]; then
|
||
echo
|
||
read -p "DevBox instance already exists. Do you want to force remove it? (y/N): " ans
|
||
case "$ans" in
|
||
[Yy]* )
|
||
FORCE_INIT=true
|
||
;;
|
||
* )
|
||
exit_with_message "DevBox instance already exists. Use --force to remove it." 1
|
||
;;
|
||
esac
|
||
fi
|
||
|
||
echo
|
||
# Check if any component is running on the host when force init is not set
|
||
if [ -z "$FORCE_INIT" ]; then
|
||
running_containers=$(docker ps --format '{{.Names}}')
|
||
# Check if any component is running on the host
|
||
components_to_check=("devbox" "freeleaps2-gitea" "freeleaps2-mongodb" "freeleaps2-rabbitmq" "freeleaps2-redis")
|
||
components_to_check+=("${DEVBOX_COMPONENTS[@]}")
|
||
|
||
for comp in "${components_to_check[@]}"; do
|
||
if echo "$running_containers" | grep -qx "$comp"; then
|
||
echo
|
||
read -p "Container '$comp' is already running. Do you want to force update it? (y/N): " ans
|
||
case "$ans" in
|
||
[Yy]* )
|
||
FORCE_INIT=true
|
||
break
|
||
;;
|
||
* )
|
||
exit_with_message " Container '$comp' is already running. Use --force to override." 1
|
||
;;
|
||
esac
|
||
fi
|
||
done
|
||
fi
|
||
|
||
echo
|
||
|
||
log_info "Current OS is $OS"
|
||
# Check if Installed the net-tools netstat under MacOS, WSL2 and Linux OS
|
||
if [[ "$OS" == "darwin" || "$OS" == "wsl2" || "$OS" == "linux" ]]; then
|
||
if ! command -v netstat &>/dev/null; then
|
||
log_info "Installing net-tools package..."
|
||
if [[ "$OS" == "darwin" ]]; then
|
||
brew install net-tools
|
||
elif [[ "$OS" == "wsl2" ]]; then
|
||
sudo apt-get update -y
|
||
sudo apt-get install net-tools -y
|
||
elif [[ "$OS" == "linux" ]]; then
|
||
sudo apt-get update -y
|
||
sudo apt-get install net-tools -y
|
||
else
|
||
exit_with_message " Failed install net-tools package on OS: $OS, please install it manually." 1
|
||
fi
|
||
else
|
||
log_info "net-tools package already installed."
|
||
fi
|
||
fi
|
||
|
||
# Check if force init is set, if not, check if the ports are in use
|
||
if [[ -z "$FORCE_INIT" ]]; then
|
||
log_info "Checking if the ports are in use..."
|
||
# Check if the gittea, mongodb, rabbitmq, redis ports are in use
|
||
if netstat -tuln | grep -q ":3000"; then
|
||
exit_with_message " gitea port 3000 is already in use, please stop the service." 1
|
||
fi
|
||
|
||
if netstat -tuln | grep -q ":27017"; then
|
||
exit_with_message " mongodb port 27017 is already in use, please stop the service." 1
|
||
fi
|
||
|
||
if netstat -tuln | grep -q ":5672"; then
|
||
exit_with_message " rabbitmq port 5672 is already in use, please stop the service." 1
|
||
fi
|
||
|
||
if netstat -tuln | grep -q ":15672"; then
|
||
exit_with_message " rabbitmq port 15672 is already in use, please stop the service." 1
|
||
fi
|
||
|
||
if netstat -tuln | grep -q ":6379"; then
|
||
exit_with_message " redis port 6379 is already in use, please stop the service." 1
|
||
fi
|
||
fi
|
||
|
||
|
||
|
||
local devbox_full_image="${DEVBOX_REPO}/${DEVBOX_IMAGE}:${DEVBOX_TAG}"
|
||
|
||
# Check local and remote version. User doesn’t need to rebuild devbox if local version is consistent with remote version
|
||
if [[ -n "$DEVBOX_REPO" && -n "$DEVBOX_IMAGE" && -n "$DEVBOX_TAG" ]]; then
|
||
if docker images --format '{{.Repository}}:{{.Tag}}' | grep -q "^${DEVBOX_REPO}/${DEVBOX_IMAGE}:${DEVBOX_TAG}\$"; then
|
||
log_info "DevBox image $devbox_full_image already exists."
|
||
|
||
# Check if the local image is not used by any container
|
||
local devbox_full_image="${DEVBOX_REPO}/${DEVBOX_IMAGE}:${DEVBOX_TAG}"
|
||
local local_image_id remote_image_id
|
||
|
||
# Get the local image ID
|
||
log_info "DevBox image $devbox_full_image already exists."
|
||
|
||
local_image_id=$(docker images --format '{{.ID}}' | grep "^${devbox_full_image}\$")
|
||
remote_image_id=$(docker images --format '{{.ID}}' "$devbox_full_image" | head -n 1)
|
||
|
||
if [[ "$local_image_id" != "$remote_image_id" ]]; then
|
||
timestamp=$(date +%Y%m%d%H%M%S)
|
||
local backup_tag="${DEVBOX_TAG}-$timestamp"
|
||
if docker tag "$local_image_id" "${DEVBOX_REPO}/${DEVBOX_IMAGE}:${backup_tag}"; then
|
||
log_info "Backup local image $local_image_id to ${DEVBOX_REPO}/${DEVBOX_IMAGE}:${backup_tag}"
|
||
else
|
||
log_warn " Failed to backup local image $local_image_id to ${DEVBOX_REPO}/${DEVBOX_IMAGE}:${backup_tag}"
|
||
fi
|
||
|
||
# Check if the local image is not used by any container
|
||
if docker ps -a --format '{{.Image}}' | grep -q "^${local_image_id}\$"; then
|
||
log_info "Local image $local_image_id is used by a container. Stopping it first..."
|
||
docker ps -a --filter "ancestor=$local_image_id" --format '{{.ID}}' | while read -r container_id; do
|
||
docker stop "$container_id" &>/dev/null || true
|
||
docker rm "$container_id" &>/dev/null || true
|
||
done
|
||
fi
|
||
|
||
# Delete local image by image id
|
||
if docker rmi "$local_image_id" &>/dev/null; then
|
||
log_info "Deleted local image $local_image_id"
|
||
else
|
||
log_warn " Failed to delete local image $local_image_id"
|
||
fi
|
||
|
||
# Pull the latest image from the remote repository
|
||
log_info "Pulling DevBox image $devbox_full_image..."
|
||
docker pull "$devbox_full_image" || {
|
||
exit_with_message " Failed to pull DevBox image $devbox_full_image, please check the image name and tag." 1
|
||
}
|
||
else
|
||
log_info "The correct version of devbox image exists and use local image."
|
||
fi
|
||
else
|
||
log_info "Pulling DevBox image $devbox_full_image..."
|
||
docker pull "$devbox_full_image"
|
||
fi
|
||
else
|
||
exit_with_message " DevBox image repository, name, or tag is not specified, please check the parameters." 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
|
||
log_info "Removing existing container named $DEVBOX_NAME ..."
|
||
docker stop "$DEVBOX_NAME" &>/dev/null || true
|
||
docker rm "$DEVBOX_NAME" &>/dev/null || true
|
||
|
||
# Remove .devbox-instance file
|
||
rm -f "$WORKING_HOME/.devbox-instance"
|
||
|
||
# Remove .backend.pid .frontend.pid
|
||
rm -f "$WORKING_HOME/.backend.pid"
|
||
rm -f "$WORKING_HOME/.frontend.pid"
|
||
else
|
||
exit_with_message " Container named $DEVBOX_NAME already exists. Use --force to remove it." 1
|
||
fi
|
||
fi
|
||
|
||
# Create Docker network for DevBox container. TODO: if the network need to be configured in the docker-compose file add some logic to load it from the file
|
||
DEVBOX_FREELEAPS2_NETWORK="devbox_freeleaps2-network"
|
||
|
||
log_info ' Starting DevBox environment initialization...'
|
||
# Check if docker network create devbox_freeleaps2-network
|
||
if ! docker network ls | grep -q "$DEVBOX_FREELEAPS2_NETWORK"; then
|
||
log_info "Creating Docker network: $DEVBOX_FREELEAPS2_NETWORK"
|
||
docker network create "$DEVBOX_FREELEAPS2_NETWORK"
|
||
else
|
||
log_info "Docker network devbox_freeleaps2-network already exists."
|
||
fi
|
||
|
||
# Check if use custom repository
|
||
if [[ -n "$USE_CUSTOM_REPOSITORY" ]]; then
|
||
log_info "[INIT] Using custom repository."
|
||
elif [[ -z "$FREELEAPS_USERNAME" || -z "$FREELEAPS_PASSWORD" ]]; then
|
||
exit_with_message " Username or password is missing. Please provide a valid username and password for freeleaps.com repository." 1
|
||
fi
|
||
|
||
log_info ' [INIT] Starting DevBox container...'
|
||
|
||
# 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 \
|
||
--network "$DEVBOX_FREELEAPS2_NETWORK" \
|
||
"$devbox_full_image" 2>/dev/null
|
||
)"
|
||
|
||
if [[ -z "$container_id" ]]; then
|
||
exit_with_message " Failed to create DevBox container." 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"
|
||
|
||
DOVBOX_CLI_DIR=$(pwd)
|
||
|
||
ECHO_USE_CUSTOM_REPOSITORY=""
|
||
|
||
# Check if USE_CUSTOM_REPOSITORY is empty
|
||
if [[ -z "$USE_CUSTOM_REPOSITORY" ]]; then
|
||
ENCODEING_FREELEAPS_USERNAME=$(url_encode "$FREELEAPS_USERNAME")
|
||
ENCODEING_FREELEAPS_PASSWORD=$(url_encode "$FREELEAPS_PASSWORD")
|
||
# Test if the user can access the freeleaps.com repository
|
||
log_info "Testing access to freeleaps.com repository..."
|
||
if ! git ls-remote "https://$ENCODEING_FREELEAPS_USERNAME:$ENCODEING_FREELEAPS_PASSWORD@gitea.freeleaps.mathmast.com/products/freeleaps.git" &>/dev/null; then
|
||
exit_with_message " Failed to access freeleaps.com repository. Please check your username and password." 1
|
||
fi
|
||
|
||
FREELEAPS_DIR="$WORKING_HOME/freeleaps"
|
||
FRONTEND_GIT_URL="https://$ENCODEING_FREELEAPS_USERNAME:$ENCODEING_FREELEAPS_PASSWORD@gitea.freeleaps.mathmast.com/products/freeleaps.git"
|
||
# Check if freeleaps2-frontend exists, if not git clone it
|
||
if [ ! -d "$FREELEAPS_DIR" ]; then
|
||
pushd "$WORKING_HOME" > /dev/null
|
||
log_info "Git cloning gitea.freeleaps.mathmast.com/products/freeleaps.git to $FREELEAPS_DIR"
|
||
git clone --depth 5 $FRONTEND_GIT_URL
|
||
|
||
else
|
||
pushd "$FREELEAPS_DIR" > /dev/null
|
||
# Check $WORKING_HOME/freeleaps exists and it is a git repository, if not git clone it
|
||
if ! git rev-parse --is-inside-work-tree &>/dev/null; then
|
||
popd > /dev/null # Exit from $FREELEAPS_DIR
|
||
rm -rf "$FREELEAPS_DIR" # Remove $FREELEAPS_DIR
|
||
rmdir "$FREELEAPS_DIR" # Remove $FREELEAPS_DIR
|
||
|
||
# Git clone freeleaps.com:3443/products/freeleaps.git
|
||
log_info "Cloning repository again: $FRONTEND_GIT_URL"
|
||
uid=$(id -u)
|
||
gid=$(id -g)
|
||
sudo chown -R ${uid}:${gid} "$WORKING_HOME"
|
||
|
||
git clone --depth 5 "$FRONTEND_GIT_URL"
|
||
else
|
||
log_info "Git pulling gitea.freeleaps.mathmast.com/products/freeleaps.git"
|
||
git pull
|
||
fi
|
||
|
||
popd > /dev/null
|
||
fi
|
||
else
|
||
|
||
if ! echo "$USE_CUSTOM_REPOSITORY" | grep -Eq '^(https:\/\/|git@|git:\/\/|file:\/\/\/)[^ ]+\.git$'; then
|
||
exit_with_message " Invalid custom repository URL. Please provide a valid URL." 1
|
||
fi
|
||
|
||
# Check if the custom repository is a git repository
|
||
# Test if the user can access the custom repository
|
||
log_info "Testing access to custom repository..."
|
||
if ! git ls-remote "$USE_CUSTOM_REPOSITORY" &>/dev/null; then
|
||
exit_with_message " Failed to access custom repository. Please check the repository URL." 1
|
||
fi
|
||
|
||
ECHO_USE_CUSTOM_REPOSITORY=$(echo "$USE_CUSTOM_REPOSITORY" | sed 's/\(https:\/\/[^:]*\):[^@]*@/\1:****@/')
|
||
|
||
CUSTOM_FOLDER_NAME=$(basename "$USE_CUSTOM_REPOSITORY" .git)
|
||
CUSTOM_DIR="$WORKING_HOME/$CUSTOM_FOLDER_NAME"
|
||
if [ ! -d "$CUSTOM_DIR" ]; then
|
||
pushd "$WORKING_HOME" > /dev/null
|
||
log_info "Git cloning custom repository: $ECHO_USE_CUSTOM_REPOSITORY"
|
||
git clone --depth 5 "$USE_CUSTOM_REPOSITORY"
|
||
else
|
||
pushd "$CUSTOM_DIR" > /dev/null
|
||
# Check $WORKING_HOME/custom exists and it is a git repository, if not git clone it
|
||
if ! git rev-parse --is-inside-work-tree &>/dev/null; then
|
||
popd > /dev/null # Exit from $CUSTOM_DIR
|
||
rm -rf "$CUSTOM_DIR" # Remove $CUSTOM_DIR
|
||
rmdir "$CUSTOM_DIR" # Remove $CUSTOM_DIR
|
||
|
||
# Git clone custom repository
|
||
log_info "Cloning repository again: $ECHO_USE_CUSTOM_REPOSITORY"
|
||
uid=$(id -u)
|
||
gid=$(id -g)
|
||
sudo chown -R ${uid}:${gid} "$WORKING_HOME"
|
||
|
||
git clone --depth 5 "$USE_CUSTOM_REPOSITORY"
|
||
else
|
||
log_info "Git pulling custom repository"
|
||
git pull
|
||
fi
|
||
|
||
popd > /dev/null
|
||
fi
|
||
fi
|
||
|
||
pushd $DOVBOX_CLI_DIR > /dev/null
|
||
|
||
# -------------------------------------------------------------------
|
||
# 6. linbwang: pull and start other components
|
||
# -------------------------------------------------------------------
|
||
|
||
log_info "[INIT] Starting Freeleaps services... Use Local component $USE_LOCAL_COMPONENT_VAL"
|
||
|
||
export ARCH="$ARCH"
|
||
export WORKING_HOME="$WORKING_HOME"
|
||
|
||
# Save $USE_CUSTOM_REPOSITORY url to .custom-repository file
|
||
echo "$USE_CUSTOM_REPOSITORY" > "$WORKING_HOME/.custom-repository"
|
||
|
||
|
||
# If USE_CUSTOM_REPOSITORY is not empty, initialize the custom repository completed
|
||
if [[ -n "$USE_CUSTOM_REPOSITORY" ]]; then
|
||
# Remove the ':' and password from USE_CUSTOM_REPOSITORY
|
||
|
||
|
||
echo
|
||
echo "==========================================================="
|
||
echo
|
||
log_info "[INIT] Custom repository initialization completed."
|
||
log_info "Custom repository is located at: ${WORKING_HOME}/${CUSTOM_FOLDER_NAME}"
|
||
log_info "Custom repository URL: $ECHO_USE_CUSTOM_REPOSITORY"
|
||
log_info "Custom repository is ready for use."
|
||
echo
|
||
echo "==========================================================="
|
||
echo
|
||
|
||
exit 0
|
||
fi
|
||
|
||
# Check if docker-compose command exists
|
||
log_info "Cehck if docker-compose command exists"
|
||
# Check if docker-compose is installed
|
||
local DC_CMD
|
||
if command -v docker-compose >/dev/null 2>&1; then
|
||
DC_CMD="docker-compose"
|
||
# 如果没有找到 docker-compose,再检查 docker compose(v2 插件)
|
||
elif docker compose version >/dev/null 2>&1; then
|
||
DC_CMD="docker compose"
|
||
else
|
||
DC_CMD=""
|
||
log_error "docker-compose is not installed."
|
||
fi
|
||
if [[ "$DC_CMD" == "" ]]; then
|
||
exit_with_message "Please install docker-compose or docker compose (v2) and try again." 1
|
||
fi
|
||
|
||
# If USE_LOCAL_COMPONENT is true, then use local components
|
||
if [[ $USE_LOCAL_COMPONENT_VAL == true ]]; then
|
||
log_info ' = Using local components for Freeleaps services.'
|
||
|
||
export DEVSVC_IMAGE_TAG="$component_tag"
|
||
export CONTENT_IMAGE_TAG="$component_tag"
|
||
export CENTRAL_STORAGE_IMAGE_TAG="$component_tag"
|
||
export AUTHENTICATION_IMAGE_TAG="$component_tag"
|
||
export NOTIFICATION_IMAGE_TAG="$component_tag"
|
||
export CHAT_IMAGE_TAG="$component_tag"
|
||
|
||
# Check if gitea_data_backup.tar.gz exists at current script directory, if not exit
|
||
if [[ ! -f "gitea_data_backup.tar.gz" ]]; then
|
||
exit_with_message " gitea_data_backup.tar.gz not found. Please make sure it exists in the current directory." 1
|
||
fi
|
||
|
||
# Sudo force sudo tar -xzvf gitea_data_backup.tar.gz
|
||
sudo tar -xzvf gitea_data_backup.tar.gz
|
||
|
||
# Check if data/git, data/gitea, data/ssh directories exist after extracting gitea_data_backup.tar.gz
|
||
if [[ ! -d "data/git" || ! -d "data/gitea" || ! -d "data/ssh" ]]; then
|
||
exit_with_message " Failed to extract gitea data backup, please check the backup file." 1
|
||
fi
|
||
|
||
|
||
# Copy gitea data to the gitea container
|
||
GITEA_HOST_DIR="${WORKING_HOME}/freeleaps2-gitea"
|
||
|
||
# Remove existing data directories
|
||
sudo rm -rf ${GITEA_HOST_DIR}/git
|
||
sudo rm -rf ${GITEA_HOST_DIR}/gitea
|
||
sudo rm -rf ${GITEA_HOST_DIR}/ssh
|
||
|
||
# Move data directories to the gitea container
|
||
sudo mv data/git ${GITEA_HOST_DIR}/
|
||
sudo mv data/gitea ${GITEA_HOST_DIR}/
|
||
sudo mv data/ssh ${GITEA_HOST_DIR}/
|
||
|
||
# Change the current user of the gitea data directories
|
||
uid=$(id -u)
|
||
gid=$(id -g)
|
||
sudo chown -R ${uid}:${gid} ${GITEA_HOST_DIR}
|
||
log_info "Gitea data copying is done"
|
||
|
||
# Check if gitea data directories exist in the gitea container
|
||
if [[ ! -d "${GITEA_HOST_DIR}/gitea" ]]; then
|
||
exit_with_message " Failed to copy gitea data, please check the data directories." 1
|
||
fi
|
||
|
||
|
||
mkdir -p ${WORKING_HOME}/logs
|
||
|
||
# for each component create log directory
|
||
for component in "${start_components[@]}"; do
|
||
if [[ ! -d "${WORKING_HOME}/logs/${component}" ]]; then
|
||
mkdir -p "${WORKING_HOME}/logs/${component}"
|
||
fi
|
||
done
|
||
# Check if FORCE_INIT is set, if not just docker compose up or docker-compose up --force
|
||
|
||
|
||
# Start Gitea, MongoDB, RabbitMQ and other components containers
|
||
log_info "start Gitea, MongoDB, RabbitMQ and other components containers"
|
||
|
||
if [[ -z "$FORCE_INIT" ]]; then
|
||
log_info "Starting Gitea, MongoDB, RabbitMQ and other components containers..."
|
||
$DC_CMD -f docker-compose.yaml up -d mongodb rabbitmq gitea redis "${start_components[@]}"
|
||
else
|
||
log_info "Force starting Gitea, MongoDB, RabbitMQ and other components containers..."
|
||
$DC_CMD -f docker-compose.yaml up --force-recreate -d mongodb rabbitmq gitea redis "${start_components[@]}"
|
||
fi
|
||
|
||
gitea_container_id=$(docker ps --no-trunc -a --filter "name=^freeleaps2-gitea$" --format "{{.ID}}")
|
||
echo "$gitea_container_id" > "$WORKING_HOME/.gitea-instance"
|
||
|
||
mongo_container_id=$(docker ps --no-trunc -a --filter "name=^freeleaps2-mongodb$" --format "{{.ID}}")
|
||
echo "$mongo_container_id" > "$WORKING_HOME/.mongodb-instance"
|
||
|
||
rabbitmq_container_id=$(docker ps --no-trunc -a --filter "name=^freeleaps2-rabbitmq$" --format "{{.ID}}")
|
||
echo "$rabbitmq_container_id" > "$WORKING_HOME/.rabbitmq-instance"
|
||
|
||
redis_container_id=$(docker ps --no-trunc -a --filter "name=^freeleaps2-redis$" --format "{{.ID}}")
|
||
echo "$redis_container_id" > "$WORKING_HOME/.redis-instance"
|
||
|
||
|
||
# Get all components container ids and save to .component-instance file
|
||
for component in "${start_components[@]}"; do
|
||
tmp_container_id=$(docker ps --no-trunc -a --filter "name=^$component$" --format "{{.ID}}")
|
||
echo "$tmp_container_id" > "$WORKING_HOME/.${component}-instance"
|
||
done
|
||
|
||
log_info "${component} container created: $component_container_id"
|
||
|
||
# Check all components are started
|
||
for component in "${start_components[@]}"; do
|
||
if [[ -z "$(docker ps -a --format '{{.Names}}' | grep "^$component\$")" ]]; then
|
||
exit_with_message " Failed to start $component container. Please check the logs for more information." 1
|
||
fi
|
||
done
|
||
else
|
||
echo '============================================================'
|
||
log_info 'Using online components for Freeleaps services.'
|
||
echo '============================================================'
|
||
# Start Gitea, MongoDB, RabbitMQ containers
|
||
if [[ -z "$FORCE_INIT" ]]; then
|
||
log_info "Starting Gitea, MongoDB, RabbitMQ and other components containers..."
|
||
$DC_CMD -f docker-compose.yaml up -d gitea mongodb rabbitmq redis
|
||
else
|
||
log_info "Force starting Gitea, MongoDB, RabbitMQ and other components containers..."
|
||
$DC_CMD -f docker-compose.yaml up --force-recreate -d gitea mongodb rabbitmq redis
|
||
fi
|
||
|
||
# Save MongoDB and RabbitMQ container ids to .mongodb-instance and .rabbitmq-instance
|
||
mongo_container_id=$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-mongodb\$")
|
||
echo "$mongo_container_id" > "$WORKING_HOME/.mongodb-instance"
|
||
|
||
rabbitmq_container_id=$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-rabbitmq\$")
|
||
echo "$rabbitmq_container_id" > "$WORKING_HOME/.rabbitmq-instance"
|
||
|
||
redis_container_id=$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-redis\$")
|
||
echo "$redis_container_id" > "$WORKING_HOME/.redis-instance"
|
||
fi
|
||
|
||
# Save $USE_LOCAL_COMPONENT false/true to $WORKING_HOME/.use-local-component
|
||
echo "$USE_LOCAL_COMPONENT" > "$WORKING_HOME/.use-local-component"
|
||
|
||
pushd $WORKING_HOME
|
||
|
||
IS_START_FRONTEND=false
|
||
|
||
|
||
|
||
# Make a user input (Y/N) to continue pull freeleaps.com code and start if N then exit
|
||
echo
|
||
read -p "Do you want to continue to pull freeleaps.com code and start the services? (Y/N): " user_input
|
||
echo
|
||
|
||
# Initialize the compile environment
|
||
init_compile_env
|
||
|
||
if [[ "$user_input" == "N" || "$user_input" == "n" ]]; then
|
||
|
||
# Echo as init job completed and exit
|
||
reset_freeleaps_repo
|
||
echo
|
||
echo "==========================================================="
|
||
log_info "DevBox init completed successfully!"
|
||
log_info "DevBox Environment Details:"
|
||
log_info "DevBox container name: $DEVBOX_NAME"
|
||
log_info "DevBox container ID: $WORKING_HOME/.devbox-instance"
|
||
echo "==========================================================="
|
||
echo
|
||
exit 0
|
||
fi
|
||
|
||
IS_START_FRONTEND=true
|
||
|
||
|
||
# Run banckend service and frontend service in the container
|
||
compile_backend_service
|
||
compile_frontend_service
|
||
|
||
reset_freeleaps_repo
|
||
|
||
# -------------------------------------------------------------------
|
||
# 10. Final notification
|
||
# -------------------------------------------------------------------
|
||
echo
|
||
echo "==========================================================="
|
||
echo "DevBox init completed successfully!"
|
||
echo "DevBox Environment Details:"
|
||
echo "1. Code repository is located at: ${WORKING_HOME}/freeleaps"
|
||
echo "2. Open up the frontend by visiting: http://localhost:${DEVBOX_FRONTEND_PORT}"
|
||
echo "3. Log files can be viewed at:"
|
||
echo " - Backend logs: ${WORKING_HOME}/logs/backend.logs"
|
||
echo " - Frontend logs: ${WORKING_HOME}/logs/frontend.logs"
|
||
echo "DevBox container ID: $WORKING_HOME/.devbox-instance"
|
||
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
|
||
log_info "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 CLEAR_ALL="$(get_arg '--clear-all')"
|
||
|
||
# print the parameters
|
||
log_info "Deinitialization parameters:"
|
||
log_info " WORKING_HOME = $WORKING_HOME"
|
||
log_info " CLEAR_LOGS = $CLEAR_LOGS"
|
||
log_info " CLEAR_REPO = $CLEAR_REPO"
|
||
log_info " CLEAR_ALL = $CLEAR_ALL"
|
||
|
||
log_info "Starting DevBox deinitialization..."
|
||
|
||
# Stop and remove DevBox container
|
||
|
||
if [[ -f "$WORKING_HOME/.devbox-instance" ]]; then
|
||
local container_id
|
||
container_id=$(cat "$WORKING_HOME/.devbox-instance")
|
||
log_info "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"
|
||
else
|
||
log_info "DevBox container is not running."
|
||
if [[ -n "$(docker ps -a --format '{{.Names}}' | grep "^devbox\$")" ]]; then
|
||
# Get the container ID of the DevBox container
|
||
log_info "DevBox container is stopped."
|
||
local container_id
|
||
container_id=$(docker ps -a --format '{{.Names}}' | grep "^devbox\$")
|
||
|
||
log_info "Stopping and removing DevBox container: $container_id"
|
||
docker stop "$container_id" &>/dev/null || true
|
||
docker rm "$container_id" &>/dev/null || true
|
||
fi
|
||
fi
|
||
|
||
# Check if devbox container is running
|
||
if [[ -n "$(docker ps -a --format '{{.Names}}' | grep "^devbox\$")" ]]; then
|
||
# Get the container ID of the DevBox container
|
||
log_info "DevBox container is stopped."
|
||
local container_id
|
||
container_id=$(docker ps -a --format '{{.Names}}' | grep "^devbox\$")
|
||
|
||
exit_with_message " Failed to stop and remove DevBox container when deinitializing. Please try deinit again or manually stop and remove the container." 1
|
||
fi
|
||
|
||
if [[ -f "$WORKING_HOME/.gitea-instance" ]]; then
|
||
local gitea_container_id
|
||
gitea_container_id=$(cat "$WORKING_HOME/.gitea-instance")
|
||
log_info "Stopping and removing Gitea container: $gitea_container_id"
|
||
docker stop "$gitea_container_id" &>/dev/null || true
|
||
docker rm "$gitea_container_id" &>/dev/null || true
|
||
|
||
# Check if the Gitea container is still running, then use docker compose down to stop and remove the container
|
||
if [[ -n "$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-gitea\$")" ]]; then
|
||
log_info "Using docker-compose down to stop and remove Gitea container."
|
||
$DC_CMD -f docker-compose.yaml down gitea
|
||
fi
|
||
|
||
rm -f "$WORKING_HOME/.gitea-instance"
|
||
|
||
elif [[ -n "$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-gitea\$")" ]]; then
|
||
# If the Gitea container is still running, stop and remove it
|
||
log_info "Gitea container is stopped."
|
||
local gitea_container_id
|
||
gitea_container_id=$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-gitea\$")
|
||
|
||
log_info "Stopping and removing Gitea container: $gitea_container_id"
|
||
docker stop "$gitea_container_id" &>/dev/null || true
|
||
docker rm "$gitea_container_id" &>/dev/null || true
|
||
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")
|
||
log_info "Stopping and removing MongoDB container: $mongodb_container_id"
|
||
docker stop "$mongodb_container_id" &>/dev/null || true
|
||
docker rm "$mongodb_container_id" &>/dev/null || true
|
||
|
||
# Check if the MongoDB container is still running, then use docker compose down to stop and remove the container
|
||
if [[ -n "$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-mongodb\$")" ]]; then
|
||
log_info "Using docker-compose down to stop and remove MongoDB container."
|
||
$DC_CMD -f docker-compose.yaml down mongodb
|
||
fi
|
||
|
||
rm -f "$WORKING_HOME/.mongodb-instance"
|
||
|
||
elif [[ -n "$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-mongodb\$")" ]]; then
|
||
# If the MongoDB container is still running, stop and remove it
|
||
log_info "MongoDB container is stopped."
|
||
local mongodb_container_id
|
||
mongodb_container_id=$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-mongodb\$")
|
||
|
||
log_info "Stopping and removing MongoDB container: $mongodb_container_id"
|
||
docker stop "$mongodb_container_id" &>/dev/null || true
|
||
docker rm "$mongodb_container_id" &>/dev/null || true
|
||
fi
|
||
|
||
if [[ -f "$WORKING_HOME/.redis-instance" ]]; then
|
||
local redis_container_id
|
||
redis_container_id=$(cat "$WORKING_HOME/.redis-instance")
|
||
log_info "Stopping and removing Redis container: $redis_container_id"
|
||
docker stop "$redis_container_id" &>/dev/null || true
|
||
docker rm "$redis_container_id" &>/dev/null || true
|
||
|
||
# Check if the Redis container is still running, then use docker compose down to stop and remove the container
|
||
if [[ -n "$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-redis\$")" ]]; then
|
||
log_info "Using docker-compose down to stop and remove Redis container."
|
||
$DC_CMD -f docker-compose.yaml down redis
|
||
fi
|
||
|
||
rm -f "$WORKING_HOME/.redis-instance"
|
||
elif [[ -n "$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-redis\$")" ]]; then
|
||
# If the Redis container is still running, stop and remove it
|
||
log_info "Redis container is stopped."
|
||
local redis_container_id
|
||
redis_container_id=$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-redis\$")
|
||
|
||
log_info "Stopping and removing Redis container: $redis_container_id"
|
||
docker stop "$redis_container_id" &>/dev/null || true
|
||
docker rm "$redis_container_id" &>/dev/null || true
|
||
|
||
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")
|
||
log_info "Stopping and removing RabbitMQ container: $rabbitmq_container_id"
|
||
docker stop "$rabbitmq_container_id" &>/dev/null || true
|
||
docker rm "$rabbitmq_container_id" &>/dev/null || true
|
||
|
||
# Check if the RabbitMQ container is still running, then use docker compose down to stop and remove the container
|
||
if [[ -n "$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-rabbitmq\$")" ]]; then
|
||
log_info "Using docker-compose down to stop and remove RabbitMQ container."
|
||
$DC_CMD -f docker-compose.yaml down rabbitmq
|
||
fi
|
||
|
||
rm -f "$WORKING_HOME/.rabbitmq-instance"
|
||
elif [[ -n "$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-rabbitmq\$")" ]]; then
|
||
# If the RabbitMQ container is still running, stop and remove it
|
||
log_info "RabbitMQ container is stopped."
|
||
local rabbitmq_container_id
|
||
rabbitmq_container_id=$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-rabbitmq\$")
|
||
|
||
log_info "Stopping and removing RabbitMQ container: $rabbitmq_container_id"
|
||
docker stop "$rabbitmq_container_id" &>/dev/null || true
|
||
docker rm "$rabbitmq_container_id" &>/dev/null || true
|
||
fi
|
||
|
||
# Stop and remove other components
|
||
local components=("${DEVBOX_COMPONENTS[@]}")
|
||
for component in "${components[@]}"; do
|
||
if [[ -f "$WORKING_HOME/.${component}-instance" ]]; then
|
||
local component_container_id
|
||
component_container_id=$(cat "$WORKING_HOME/.${component}-instance")
|
||
log_info "Stopping and removing ${component} container: $component_container_id"
|
||
docker stop "$component_container_id" &>/dev/null || true
|
||
docker rm "$component_container_id" &>/dev/null || true
|
||
|
||
# Check if the component is still running, then use docker compose down to stop and remove the container
|
||
if [[ -n "$(docker ps -a --format '{{.Names}}' | grep "^$component\$")" ]]; then
|
||
log_info "Using docker-compose down to stop and remove $component container."
|
||
$DC_CMD -f docker-compose.yaml down "$component"
|
||
fi
|
||
|
||
rm -f "$WORKING_HOME/.${component}-instance"
|
||
elif [[ -n "$(docker ps -a --format '{{.Names}}' | grep "^$component\$")" ]]; then
|
||
# If the component is still running, stop and remove it
|
||
log_info "${component} container is stopped."
|
||
local component_container_id
|
||
component_container_id=$(docker ps -a --format '{{.Names}}' | grep "^$component\$")
|
||
|
||
log_info "Stopping and removing ${component} container: $component_container_id"
|
||
docker stop "$component_container_id" &>/dev/null || true
|
||
docker rm "$component_container_id" &>/dev/null || true
|
||
fi
|
||
done
|
||
|
||
|
||
# Clear the DevBox container logs
|
||
if [[ "$CLEAR_LOGS" == "true" ]]; then
|
||
log_info "Clearing logs in $WORKING_HOME/logs..."
|
||
if [[ -d "$WORKING_HOME/logs" ]]; then
|
||
uid=$(id -u)
|
||
gid=$(id -g)
|
||
sudo chown -R ${uid}:${gid} "$WORKING_HOME/logs"
|
||
rm -rf "$WORKING_HOME/logs" 2>/dev/null || true
|
||
mkdir -p "$WORKING_HOME/logs" 2>/dev/null || true
|
||
fi
|
||
else
|
||
log_info "Skipping log clearing."
|
||
fi
|
||
|
||
# Clear the source repository
|
||
if [[ "$CLEAR_REPO" == "true" && -d "$WORKING_HOME/freeleaps" ]]; then
|
||
log_info "Deleting source repository at $WORKING_HOME/freeleaps"
|
||
uid=$(id -u)
|
||
gid=$(id -g)
|
||
sudo chown -R ${uid}:${gid} "$WORKING_HOME/freeleaps"
|
||
rm -rf "$WORKING_HOME/freeleaps" 2>/dev/null || true
|
||
rmdir "$WORKING_HOME/freeleaps" 2>/dev/null || true
|
||
else
|
||
log_info "Skipping repository deletion."
|
||
fi
|
||
|
||
if [[ "$CLEAR_LOGS" == "true" ]]; then
|
||
# Check if logs directory is removed
|
||
if [[ -d "$WORKING_HOME/logs" ]]; then
|
||
log_warn " $WORKING_HOME/logs still exists after removal."
|
||
rm -rf "$WORKING_HOME/logs"
|
||
else
|
||
log_info "Logs directory removed successfully."
|
||
fi
|
||
fi
|
||
|
||
if [[ "$CLEAR_ALL" == "true" ]]; then
|
||
# Check Y/N to remove the working home directory
|
||
echo
|
||
read -p "Do you want to delete the working home directory? This will permanently remove all your local code and environment. (Y/N): " user_input
|
||
echo
|
||
if [[ "$user_input" == "Y" || "$user_input" == "y" ]]; then
|
||
REMOVE_WORKING_HOME=true
|
||
|
||
# Remove the working home directory
|
||
log_info "Removing working home directory: $WORKING_HOME"
|
||
if [[ -d "$WORKING_HOME" ]]; then
|
||
uid=$(id -u)
|
||
gid=$(id -g)
|
||
sudo chown -R ${uid}:${gid} "$WORKING_HOME"
|
||
rm -rf "$WORKING_HOME" 2>/dev/null || true
|
||
rmdir "$WORKING_HOME" 2>/dev/null || true
|
||
fi
|
||
log_info "Working home directory removed successfully."
|
||
else
|
||
REMOVE_WORKING_HOME=false
|
||
log_info "Skipping working home directory removal."
|
||
fi
|
||
fi
|
||
|
||
# Sleep 5 seconds to allow the services to stop, for each second echo 5 seconds increase from 1 to 5 in each second by -
|
||
echo -n "[INFO] $(date '+%Y-%m-%d %H:%M:%S') Stopping services"
|
||
for i in {1..10}; do
|
||
echo -n "."
|
||
sleep 0.5
|
||
done
|
||
|
||
echo
|
||
|
||
# Remove the use-local-component file
|
||
rm -f "$WORKING_HOME/.use-local-component"
|
||
|
||
exit_with_message "DevBox deinitialization completed." 0
|
||
}
|
||
|
||
# :command.function
|
||
devbox_start_command() {
|
||
|
||
local COMPONENT="$(get_arg '--component')"
|
||
local WORKING_HOME="$(get_arg '--working-home' "${HOME}/devbox")"
|
||
local FREELEAPS_ENDPOINT="$(get_arg '--freeleaps-endpoint')"
|
||
if [[ "$FREELEAPS_ENDPOINT" == "all" ]]; then
|
||
export START_FRONTEND=true
|
||
export START_BACKEND=true
|
||
elif [[ "$FREELEAPS_ENDPOINT" == "frontend" ]]; then
|
||
export START_FRONTEND=true
|
||
export START_BACKEND=false
|
||
elif [[ "$FREELEAPS_ENDPOINT" == "backend" ]]; then
|
||
export START_FRONTEND=false
|
||
export START_BACKEND=true
|
||
else
|
||
# Default behavior can be adjusted if needed
|
||
export START_FRONTEND=false
|
||
export START_BACKEND=false
|
||
fi
|
||
|
||
# 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
|
||
exit_with_message " DevBox container is not running. Please run 'devbox init' first." 1
|
||
fi
|
||
|
||
local devbox_container_id=$(cat "$devbox_container_id_file_path")
|
||
|
||
# Check if use local component
|
||
if [[ -f "$WORKING_HOME/.use-local-component" ]]; then
|
||
USE_LOCAL_COMPONENT=$(cat "$WORKING_HOME/.use-local-component")
|
||
else
|
||
USE_LOCAL_COMPONENT="false"
|
||
fi
|
||
|
||
if [[ "$(lower "$USE_LOCAL_COMPONENT")" == "true" ]]; then
|
||
log_info "Using local components for Freeleaps services."
|
||
USE_LOCAL_COMPONENT="true"
|
||
else
|
||
log_info "Using online components for Freeleaps services."
|
||
USE_LOCAL_COMPONENT="false"
|
||
fi
|
||
|
||
if [[ "$USE_LOCAL_COMPONENT" == "true" ]]; then
|
||
# If no component is specified, start all components
|
||
if [[ -z "$COMPONENT" ]]; then
|
||
COMPONENTS=("mongodb" "rabbitmq" "gitea" "redis" "devbox")
|
||
COMPONENTS+=("${DEVBOX_COMPONENTS[@]}")
|
||
else
|
||
COMPONENTS=("$COMPONENT")
|
||
fi
|
||
else
|
||
# If no component is specified, start all components
|
||
if [[ -z "$COMPONENT" ]]; then
|
||
COMPONENTS=("mongodb" "rabbitmq" "gitea" "redis" "devbox")
|
||
else
|
||
# Check if the component is a local component from DEVBOX_COMPONENT
|
||
found=false
|
||
for item in "${DEVBOX_COMPONENTS[@]}"; do
|
||
if [ "$item" = "$COMPONENT" ]; then
|
||
found=true
|
||
break
|
||
fi
|
||
done
|
||
|
||
if [ "$found" = true ]; then
|
||
exit_with_message "Remote component $COMPONENT cannot be restarted, please use local components." 1
|
||
fi
|
||
|
||
COMPONENTS=("$COMPONENT")
|
||
fi
|
||
fi
|
||
|
||
BASIC_COMPONENTS=("mongodb" "rabbitmq" "gitea" "redis" "devbox")
|
||
for comp in "${COMPONENTS[@]}"; do
|
||
should_start=false
|
||
|
||
# Check if it's in BASIC_COMPONENTS
|
||
for basic in "${BASIC_COMPONENTS[@]}"; do
|
||
if [ "$comp" = "$basic" ]; then
|
||
should_start=true
|
||
break
|
||
fi
|
||
done
|
||
|
||
# Check if it's in DEVBOX_COMPONENTS
|
||
if [ "$should_start" = false ]; then
|
||
for dev in "${DEVBOX_COMPONENTS[@]}"; do
|
||
if [ "$comp" = "$dev" ]; then
|
||
should_start=true
|
||
break
|
||
fi
|
||
done
|
||
fi
|
||
|
||
if [ "$should_start" = true ]; then
|
||
log_info "Starting $comp service..."
|
||
local component_container_id_file_path="${WORKING_HOME}/.${comp}-instance"
|
||
|
||
if [ ! -f "$component_container_id_file_path" ]; then
|
||
log_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
|
||
log_info "$comp container is not running, starting container..."
|
||
if ! docker start "${component_container_id}"; then
|
||
log_error "Failed to start $comp container."
|
||
else
|
||
log_info "$comp container started successfully."
|
||
fi
|
||
else
|
||
log_info "$comp container is already running."
|
||
fi
|
||
fi
|
||
else
|
||
exit_with_message " Unknown component: $comp, please check the component name." 1
|
||
fi
|
||
done
|
||
|
||
|
||
|
||
# Check if $FREELEAPS_ENDPOINT is not empty and start the frontend and backend services
|
||
if [[ "$FREELEAPS_ENDPOINT" != "" ]]; then
|
||
# Sleep for 10 seconds to allow the services to start and echo 10 seconds increase from 1 to 10 in each second
|
||
for i in {1..20}; do
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${devbox_container_id}\$"; then
|
||
break
|
||
fi
|
||
echo -n "-"
|
||
sleep 1
|
||
done
|
||
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${devbox_container_id}\$"; then
|
||
log_info "Starting Freeleaps frontend and backend services..."
|
||
# Check if start backend service
|
||
if [[ "${START_BACKEND}" == "true" ]]; then
|
||
compile_backend_service
|
||
fi
|
||
|
||
# Start the frontend service
|
||
if [[ "${START_FRONTEND}" == "true" ]]; then
|
||
compile_frontend_service
|
||
fi
|
||
else
|
||
exit_with_message " DevBox container is not running, please run 'devbox init' first." 1
|
||
fi
|
||
fi
|
||
|
||
success_message=" Freeleaps services started successfully. "
|
||
|
||
frontend_port=$(cat "${WORKING_HOME}/.devbox-frontend-port")
|
||
if [[ "${START_FRONTEND}" == "true" && "${START_BACKEND}" == "true" ]]; then
|
||
success_message=" Frontend and backend services started successfully. Open up the frontend by visiting: http://localhost:${frontend_port}"
|
||
elif [[ "${START_FRONTEND}" == "true" ]]; then
|
||
success_message=" Frontend service started successfully. Open up the frontend by visiting: http://localhost:${frontend_port}"
|
||
elif [[ "${START_BACKEND}" == "true" ]]; then
|
||
success_message=" Backend service started successfully."
|
||
fi
|
||
|
||
exit_with_message "$success_message" 0
|
||
|
||
}
|
||
|
||
# :command.function
|
||
devbox_stop_command() {
|
||
local COMPONENT="$(get_arg '--component')"
|
||
local WORKING_HOME="$(get_arg '--working-home' "${HOME}/devbox")"
|
||
local FREELEAPS_ENDPOINT="$(get_arg '--freeleaps-endpoint')"
|
||
|
||
if [[ "$FREELEAPS_ENDPOINT" == "all" ]]; then
|
||
export STOP_FRONTEND=true
|
||
export STOP_BACKEND=true
|
||
elif [[ "$FREELEAPS_ENDPOINT" == "frontend" ]]; then
|
||
export STOP_FRONTEND=true
|
||
export STOP_BACKEND=false
|
||
elif [[ "$FREELEAPS_ENDPOINT" == "backend" ]]; then
|
||
export STOP_FRONTEND=false
|
||
export STOP_BACKEND=true
|
||
else
|
||
# Default behavior can be adjusted if needed
|
||
export STOP_FRONTEND=false
|
||
export STOP_BACKEND=false
|
||
fi
|
||
|
||
if [[ -f "${WORKING_HOME}/.devbox-instance" ]]; then
|
||
local devbox_container_id
|
||
devbox_container_id=$(cat "${WORKING_HOME}/.devbox-instance")
|
||
|
||
# If the DevBox container is not running, exit
|
||
if ! docker ps --no-trunc --format '{{.ID}}' | grep -q "^${devbox_container_id}\$"; then
|
||
exit_with_message " DevBox container is not running, please run 'devbox init' first." 1
|
||
fi
|
||
|
||
# Check if STOP_BACKEND is true, stop the backend service
|
||
if [[ "${STOP_BACKEND}" == "true" ]]; then
|
||
if [[ -f "${WORKING_HOME}/.backend.pid" ]]; then
|
||
stop_backend_service
|
||
else
|
||
log_info "Backend service is not running."
|
||
fi
|
||
fi
|
||
|
||
# Check if STOP_FRONTEND is true, stop the frontend service
|
||
if [[ "${STOP_FRONTEND}" == "true" ]]; then
|
||
if [[ -f "${WORKING_HOME}/.frontend.pid" ]]; then
|
||
stop_frontend_service
|
||
else
|
||
log_info "Frontend service is not running."
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# if any of STOP_FRONTEND and STOP_BACKEND is true, then completed stop process
|
||
if [[ "${STOP_FRONTEND}" == "true" || "${STOP_BACKEND}" == "true" ]]; then
|
||
|
||
stoped_freeleaps_service_names=()
|
||
if [[ "${STOP_FRONTEND}" == "true" ]]; then
|
||
stoped_freeleaps_service_names+=("frontend")
|
||
fi
|
||
|
||
if [[ "${STOP_BACKEND}" == "true" ]]; then
|
||
stoped_freeleaps_service_names+=("backend")
|
||
fi
|
||
|
||
|
||
# Combine the stoped_freeleaps_service_names array to a string with "and" if there are more than one service
|
||
if [[ "${#stoped_freeleaps_service_names[@]}" -gt 1 ]]; then
|
||
stoped_freeleaps_service_names="frontend and backend"
|
||
else
|
||
stoped_freeleaps_service_names="${stoped_freeleaps_service_names[0]}"
|
||
fi
|
||
|
||
|
||
exit_message="Stopped Freeleaps $stoped_freeleaps_service_names services successfully."
|
||
exit_with_message "$exit_message" 0
|
||
fi
|
||
|
||
|
||
# If the DevBox container is not running, exit
|
||
if [[ -z "$COMPONENT" ]]; then
|
||
COMPONENTS=("mongodb" "rabbitmq" "gitea" "redis" "devbox")
|
||
COMPONENTS+=("${DEVBOX_COMPONENTS[@]}")
|
||
else
|
||
COMPONENTS=("$COMPONENT")
|
||
fi
|
||
|
||
# Stop the specified components
|
||
BASIC_COMPONENTS=("mongodb" "rabbitmq" "gitea" "redis")
|
||
|
||
for comp in "${COMPONENTS[@]}"; do
|
||
if [ "$comp" = "devbox" ]; then
|
||
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
|
||
log_info "Stopping devbox..."
|
||
docker stop "$container_id" &>/dev/null || true
|
||
rm -f "${WORKING_HOME}/.backend.pid"
|
||
rm -f "${WORKING_HOME}/.frontend.pid"
|
||
else
|
||
log_info "DevBox container is not running."
|
||
fi
|
||
else
|
||
log_info "Backend service is not running."
|
||
fi
|
||
continue
|
||
fi
|
||
|
||
should_stop=false
|
||
|
||
for basic in "${BASIC_COMPONENTS[@]}"; do
|
||
if [ "$comp" = "$basic" ]; then
|
||
should_stop=true
|
||
break
|
||
fi
|
||
done
|
||
|
||
if [ "$should_stop" = false ]; then
|
||
for dev in "${DEVBOX_COMPONENTS[@]}"; do
|
||
if [ "$comp" = "$dev" ]; then
|
||
should_stop=true
|
||
break
|
||
fi
|
||
done
|
||
fi
|
||
|
||
if [ "$should_stop" = true ]; then
|
||
if [ -f "${WORKING_HOME}/.${comp}-instance" ]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.${comp}-instance")
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then
|
||
log_info "Stopping $comp service..."
|
||
docker stop "$container_id" &>/dev/null || true
|
||
else
|
||
log_info "$comp service is not running."
|
||
fi
|
||
else
|
||
log_info "$comp service is not running."
|
||
fi
|
||
else
|
||
exit_with_message " Unknown component: $comp, please check the component name." 1
|
||
fi
|
||
done
|
||
|
||
|
||
exit_with_message "Stopped Freeleaps services successfully. " 0
|
||
|
||
}
|
||
|
||
# :command.function
|
||
devbox_status_command() {
|
||
|
||
log_info "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
|
||
exit_with_message " DevBox container is not running. Please run 'devbox init' first." 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
|
||
exit_with_message " DevBox container is not running. Please run 'devbox init' first." 1
|
||
fi
|
||
|
||
# If no component is specified, check all components
|
||
if [[ -z "$COMPONENT" ]]; then
|
||
COMPONENTS=("mongodb" "rabbitmq" "gitea" "redis" "devbox")
|
||
COMPONENTS+=("${DEVBOX_COMPONENTS[@]}")
|
||
else
|
||
COMPONENTS=("$COMPONENT")
|
||
fi
|
||
|
||
# Check the status of the specified components
|
||
BASIC_COMPONENTS=("mongodb" "rabbitmq" "gitea" "redis")
|
||
ALL_COMPONENTS=("${BASIC_COMPONENTS[@]}" "${DEVBOX_COMPONENTS[@]}" "devbox")
|
||
|
||
for comp in "${COMPONENTS[@]}"; do
|
||
case_checked=false
|
||
# devsvc, notification, content...
|
||
if [ "$case_checked" = false ]; then
|
||
for svc in "${ALL_COMPONENTS[@]}"; do
|
||
if [ "$comp" = "$svc" ]; then
|
||
log_info "Checking $comp service status..."
|
||
if [ -f "${WORKING_HOME}/.${comp}-instance" ]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.${comp}-instance")
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "^${container_id}\$"; then
|
||
log_info "[RESULT]: $comp service is running."
|
||
else
|
||
log_info "[RESULT]: $comp service is not running."
|
||
fi
|
||
else
|
||
log_info "[RESULT]: $comp service is not running."
|
||
fi
|
||
case_checked=true
|
||
break
|
||
fi
|
||
done
|
||
fi
|
||
|
||
# unknown
|
||
if [ "$case_checked" = false ]; then
|
||
exit_with_message " Unknown component: $comp, please check the component name." 1
|
||
fi
|
||
done
|
||
|
||
exit_with_message " DevBox services status checked successfully." 0
|
||
}
|
||
|
||
# :command.function
|
||
devbox_restart_command() {
|
||
log_info "Restarting DevBox services..."
|
||
local COMPONENT="$(get_arg '--component')"
|
||
local WORKING_HOME="$(get_arg '--working-home' "${HOME}/devbox")"
|
||
local FREELEAPS_ENDPOINT="$(get_arg '--freeleaps-endpoint')"
|
||
|
||
# Check if --freeleaps-endpoint is not empty and start the frontend and backend services
|
||
restart_services=()
|
||
if [[ "$FREELEAPS_ENDPOINT" == "all" ]]; then
|
||
export START_FRONTEND=true
|
||
export START_BACKEND=true
|
||
restart_services=("frontend" "backend")
|
||
elif [[ "$FREELEAPS_ENDPOINT" == "frontend" ]]; then
|
||
export START_FRONTEND=true
|
||
export START_BACKEND=false
|
||
restart_services=("frontend")
|
||
elif [[ "$FREELEAPS_ENDPOINT" == "backend" ]]; then
|
||
export START_FRONTEND=false
|
||
export START_BACKEND=true
|
||
restart_services=("backend")
|
||
else
|
||
# Default behavior can be adjusted if needed
|
||
export START_FRONTEND=false
|
||
export START_BACKEND=false
|
||
fi
|
||
|
||
# Check if --freeleaps-endpoint is not empty and start the frontend and backend services
|
||
if [[ "$FREELEAPS_ENDPOINT" != "" ]]; then
|
||
|
||
devbox_container_id=$(cat "${WORKING_HOME}/.devbox-instance")
|
||
log_info "docker ps --no-trunc --format ${devbox_container_id} "
|
||
if docker ps --no-trunc --format '{{.ID}}' | grep -q "${devbox_container_id}\$"; then
|
||
log_info "Starting Freeleaps frontend and backend services..."
|
||
# Check if start backend service
|
||
if [[ "${START_BACKEND}" == "true" ]]; then
|
||
stop_backend_service
|
||
compile_backend_service
|
||
fi
|
||
|
||
# Start the frontend service
|
||
if [[ "${START_FRONTEND}" == "true" ]]; then
|
||
stop_frontend_service
|
||
compile_frontend_service
|
||
fi
|
||
else
|
||
exit_with_message " DevBox container is not running." 1
|
||
fi
|
||
|
||
frontend_port=$(cat "${WORKING_HOME}/.devbox-frontend-port")
|
||
success_message="Freeleaps $restart_services services restarted successfully."
|
||
if [[ "${START_FRONTEND}" == "true" ]]; then
|
||
success_message+=" Open up the frontend by visiting: http://localhost:${frontend_port}"
|
||
fi
|
||
exit_with_message "$success_message" 0
|
||
fi
|
||
|
||
# Check devbox container file path
|
||
local devbox_container_id_file_path="${WORKING_HOME}/.devbox-instance"
|
||
if [[ ! -f "$devbox_container_id_file_path" ]]; then
|
||
exit_with_message " DevBox container is not running. Please run 'devbox init' first." 1
|
||
fi
|
||
|
||
local devbox_container_id=$(cat "$devbox_container_id_file_path")
|
||
|
||
# Check if current environment is using local components
|
||
USE_LOCAL_COMPONENT=$(cat "${WORKING_HOME}/.use-local-component" 2>/dev/null || true)
|
||
if [[ "$USE_LOCAL_COMPONENT" == "true" ]]; then
|
||
log_info "Using local components..."
|
||
if [[ -z "$COMPONENT" ]]; then
|
||
COMPONENTS=("mongodb" "rabbitmq" "gitea" "redis" "devbox")
|
||
COMPONENTS+=("${DEVBOX_COMPONENTS[@]}")
|
||
else
|
||
COMPONENTS=("$COMPONENT")
|
||
fi
|
||
else
|
||
log_info "Using remote components..."
|
||
if [[ -z "$COMPONENT" ]]; then
|
||
COMPONENTS=("mongodb" "rabbitmq" "gitea" "redis" "devbox")
|
||
else
|
||
found=false
|
||
for item in "${DEVBOX_COMPONENTS[@]}"; do
|
||
if [ "$item" = "$COMPONENT" ]; then
|
||
found=true
|
||
break
|
||
fi
|
||
done
|
||
|
||
if [ "$found" = true ]; then
|
||
exit_with_message "Remote component $COMPONENT cannot be restarted, please use local components." 1
|
||
fi
|
||
|
||
COMPONENTS=("$COMPONENT")
|
||
fi
|
||
fi
|
||
|
||
# Stop the specified components
|
||
BASIC_COMPONENTS=("mongodb" "rabbitmq" "gitea" "redis")
|
||
ALL_COMPONENTS=("${BASIC_COMPONENTS[@]}" "${DEVBOX_COMPONENTS[@]}" "devbox")
|
||
|
||
# Stop the specified components
|
||
for comp in "${COMPONENTS[@]}"; do
|
||
if [ "$comp" = "devbox" ]; then
|
||
if [ -f "${WORKING_HOME}/.devbox-instance" ]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.devbox-instance")
|
||
log_info "Stopping devbox service..."
|
||
docker stop "$container_id" &>/dev/null || true
|
||
|
||
rm -f "${WORKING_HOME}/.backend.pid"
|
||
rm -f "${WORKING_HOME}/.frontend.pid"
|
||
else
|
||
log_info "Devbox is not running."
|
||
fi
|
||
continue
|
||
fi
|
||
|
||
should_stop=false
|
||
for known in "${BASIC_COMPONENTS[@]}" "${DEVBOX_COMPONENTS[@]}"; do
|
||
if [ "$comp" = "$known" ]; then
|
||
should_stop=true
|
||
break
|
||
fi
|
||
done
|
||
|
||
if [ "$should_stop" = true ]; then
|
||
if [ -f "${WORKING_HOME}/.${comp}-instance" ]; then
|
||
local container_id
|
||
container_id=$(cat "${WORKING_HOME}/.${comp}-instance")
|
||
log_info "Stopping $comp service..."
|
||
docker stop "$container_id" &>/dev/null || true
|
||
else
|
||
log_info "$comp service is not running."
|
||
fi
|
||
else
|
||
exit_with_message " Unknown component: $comp, please check the component name." 1
|
||
fi
|
||
done
|
||
|
||
# Sleep 5 seconds to allow the services to stop, for each second echo 5 seconds increase from 1 to 5 in each second by -
|
||
for comp in "${COMPONENTS[@]}"; do
|
||
is_known=false
|
||
for known in "${ALL_COMPONENTS[@]}"; do
|
||
if [ "$comp" = "$known" ]; then
|
||
is_known=true
|
||
break
|
||
fi
|
||
done
|
||
|
||
if [ "$is_known" = true ]; then
|
||
log_info "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
|
||
log_info "$comp service is not running."
|
||
fi
|
||
else
|
||
exit_with_message " Unknown component: $comp, please check the component name." 1
|
||
fi
|
||
done
|
||
|
||
|
||
exit_with_message " DevBox services restarted successfully." 0
|
||
}
|
||
|
||
# :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 $#
|
||
;;
|
||
|
||
"")
|
||
devbox_init_guidance >&2
|
||
action="init"
|
||
devbox_init_parse_requirements "$@"
|
||
shift $#
|
||
;;
|
||
|
||
*)
|
||
# pass * parameter to devbox_init_guidance
|
||
devbox_init_guidance $action >&2
|
||
|
||
action="init"
|
||
shift
|
||
devbox_init_parse_requirements "$@"
|
||
shift $#
|
||
;;
|
||
|
||
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 | -o)
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--os' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--os requires an argument: --os OS" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
# :flag.case
|
||
--arch | -a)
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--arch' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--arch requires an argument: --arch ARCH" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
# :flag.case
|
||
--devbox-container-name | -n)
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devbox-container-name' "$2"
|
||
shift 2
|
||
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 | -p)
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devbox-container-port' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--devbox-container-port requires an argument: --devbox-container-port DEVBOX_CONTAINER_PORT" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
--devbox-frontend-port | -q)
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devbox-frontend-port' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--devbox-frontend-port requires an argument: --devbox-frontend-port DEVBOX_FRONTEND_PORT" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
--devbox-backend-port | -b)
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devbox-backend-port' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--devbox-backend-port requires an argument: --devbox-backend-port DEVBOX_BACKEND_PORT" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
# :flag.case
|
||
--devbox-image-repo | -r)
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devbox-image-repo' "$2"
|
||
shift 2
|
||
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 | -i)
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devbox-image-name' "$2"
|
||
shift 2
|
||
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 | -t)
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--devbox-image-tag' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--devbox-image-tag requires an argument: --devbox-image-tag DEVBOX_IMAGE_TAG" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
# :flag.case
|
||
--working-home | -w)
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--working-home' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--working-home requires an argument: --working-home WORKING_HOME" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
# :flag.case
|
||
--freeleaps-username | -u)
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--freeleaps-username' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--freeleaps-username requires an argument: --freeleaps-username FREELEAPS_USERNAME" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
# :flag.case
|
||
--freeleaps-password | -x)
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--freeleaps-password' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--freeleaps-password requires an argument: --freeleaps-password FREELEAPS_PASSWORD" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
--use-custom-repository | -c)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--use-custom-repository' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--use-custom-repository requires an argument: --use-custom-repository USE_CUSTOM_REPOSITORY" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
# :flag.case
|
||
--use-local-component | -l)
|
||
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
|
||
;;
|
||
--freeleaps-components | -m)
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--freeleaps-components' "$2"
|
||
shift 2
|
||
else
|
||
printf "%s\n" "--freeleaps-components requires an argument: --freeleaps-components FREELEAPS_COMPONENTS" >&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.default_assignments
|
||
if [ -z "$(get_arg '--os')" ]; then
|
||
add_arg '--os' "auto"
|
||
fi
|
||
|
||
if [ -z "$(get_arg '--arch')" ]; then
|
||
add_arg '--arch' "auto"
|
||
fi
|
||
|
||
# :command.default_assignments
|
||
current_arch=$(get_arg '--arch')
|
||
if [ "$current_arch" = "auto" ]; then
|
||
detected_arch=$(uname -m)
|
||
if [ "$detected_arch" = "x86_64" ]; then
|
||
current_arch="amd64"
|
||
elif [ "$detected_arch" = "aarch64" ] || [ "$detected_arch" = "arm64" ] ; then
|
||
current_arch="arm64"
|
||
else
|
||
echo "ERROR: Unsupported architecture detected: $detected_arch"
|
||
exit 1
|
||
fi
|
||
# Update the arch argument accordingly
|
||
add_arg '--arch' "$current_arch"
|
||
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 '--use-custom-repository')" ]; then
|
||
add_arg '--use-custom-repository' ""
|
||
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 | -w)
|
||
|
||
# :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 | -l)
|
||
|
||
# :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 | -r)
|
||
|
||
# :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
|
||
;;
|
||
|
||
--clear-all | -a)
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--clear-all' "$2"
|
||
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--clear-all requires an argument: --clear-all CLEAR_ALL" >&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
|
||
if [ -z "$(get_arg '--clear-all')" ]; then
|
||
add_arg '--clear-all' "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 | -c)
|
||
|
||
# :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
|
||
;;
|
||
|
||
--freeleaps-endpoint | -e)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--freeleaps-endpoint' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--freeleaps-endpoint requires an argument: --freeleaps-endpoint FREELEAPS_ENDPOINT" >&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 '--freeleaps-endpoint')" ]; then
|
||
add_arg '--freeleaps-endpoint' ""
|
||
fi
|
||
|
||
}
|
||
|
||
# :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 | -c)
|
||
|
||
# :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
|
||
;;
|
||
|
||
--freeleaps-endpoint | -e)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--freeleaps-endpoint' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--freeleaps-endpoint requires an argument: --freeleaps-endpoint all/backend/frontend" >&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
|
||
# :flag.case
|
||
--component | -c)
|
||
|
||
# :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_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
|
||
# :flag.case
|
||
--component | -c)
|
||
|
||
# :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
|
||
;;
|
||
--freeleaps-endpoint | -e)
|
||
|
||
# :flag.case_arg
|
||
if [[ -n ${2+x} ]]; then
|
||
add_arg '--freeleaps-endpoint' "$2"
|
||
shift
|
||
shift
|
||
else
|
||
printf "%s\n" "--freeleaps-endpoint requires an argument: --freeleaps-endpoint all/backend/frontend" >&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 '--freeleaps-endpoint')" ]; then
|
||
add_arg '--freeleaps-endpoint' ""
|
||
fi
|
||
|
||
}
|
||
|
||
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 "$@"
|