From eef48ea6e210fed85ad2a9654d78fa9a22c28107 Mon Sep 17 00:00:00 2001 From: Tianyong Qiu Date: Fri, 28 Feb 2025 16:58:46 +0800 Subject: [PATCH 1/8] Update for fix docker checking steps --- devbox/devbox.local/cli/devbox | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/devbox/devbox.local/cli/devbox b/devbox/devbox.local/cli/devbox index 9f37a08..233c8fd 100644 --- a/devbox/devbox.local/cli/devbox +++ b/devbox/devbox.local/cli/devbox @@ -684,8 +684,19 @@ devbox_init_command() { # ------------------------------------------------------------------- # 3.1 Docker Check if ! command -v docker &>/dev/null; then - echo "ERROR: docker is not installed or not in PATH." - exit 1 + # ------------------------------------------------------------------- + # 3.1.1.install docker and check docker running + # ------------------------------------------------------------------- + if ! install_docker; then + echo "ERROR: Failed to install Docker or Docker service is not running." + exit 1 + fi + + if ! check_docker_running; then + echo "ERROR: Docker service is not running." + exit 1 + fi + fi # 3.2 Check disk space @@ -724,19 +735,7 @@ devbox_init_command() { fi fi - # ------------------------------------------------------------------- - # 5.install docker and check docker running - # ------------------------------------------------------------------- - if ! install_docker; then - echo "ERROR: Failed to install Docker or Docker service is not running." - exit 1 - fi - - if ! check_docker_running; then - echo "ERROR: Docker service is not running." - exit 1 - fi - + # ------------------------------------------------------------------- # 5.1 pull and start DevBox container # ------------------------------------------------------------------- From e1370f96b1212ab40bc9fc95a81eb2f9bd73f3f0 Mon Sep 17 00:00:00 2001 From: Tianyong Qiu Date: Fri, 28 Feb 2025 17:03:17 +0800 Subject: [PATCH 2/8] Update for docker installation --- devbox/devbox.local/cli/devbox | 114 +++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 49 deletions(-) diff --git a/devbox/devbox.local/cli/devbox b/devbox/devbox.local/cli/devbox index 233c8fd..594a9cb 100644 --- a/devbox/devbox.local/cli/devbox +++ b/devbox/devbox.local/cli/devbox @@ -323,66 +323,82 @@ inspect_args() { install_docker() { - echo "[INFO] Checking Docker installation..." + echo "==> Installing Docker..." - # Check if Docker CLI is installed - if ! command -v docker >/dev/null 2>&1; then - echo "[ERROR] Docker CLI is not installed." - return 1 + # Check if Docker is already installed + if command -v docker &>/dev/null; then + echo "==> Docker is already installed." + return 0 fi - echo "[INFO] Docker CLI is installed. Checking daemon..." + # 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 - # Check if Docker daemon is running - if docker info >/dev/null 2>&1; then - echo "[OK] Docker daemon is running." + if [ -f get-docker.sh ]; then + sudo sh get-docker.sh + rm -f get-docker.sh return 0 + fi fi - # Check if running on WSL - if grep -qi microsoft /proc/version; then - echo "[INFO] Detected WSL environment. Skipping service startup." - if [ -S /var/run/docker.sock ]; then - echo "[OK] Docker socket found (/var/run/docker.sock)." - return 0 - else - echo "[ERROR] Docker socket /var/run/docker.sock not found." - echo "[SOLUTION] Please start Docker Desktop on Windows and enable WSL integration, then mount /var/run/docker.sock into the container." - return 1 - fi + # 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 - # Check if running on macOS - if [[ "$OSTYPE" == "linux-gnu"* ]]; then - echo "[INFO] Running on Linux. Attempting to start Docker service..." - if command -v systemctl >/dev/null 2>&1; then - echo "[INFO] Starting Docker with systemctl..." - sudo systemctl start docker - sleep 2 - if systemctl is-active --quiet docker; then - echo "[OK] Docker service started successfully via systemctl." - return 0 - else - echo "[ERROR] Failed to start Docker using systemctl." - return 1 - fi - elif command -v service >/dev/null 2>&1; then - echo "[INFO] systemctl not found, trying to start Docker using service..." - sudo service docker start - sleep 2 - if docker info >/dev/null 2>&1; then - echo "[OK] Docker service started successfully via service command." - return 0 - else - echo "[ERROR] Failed to start Docker using service command." - return 1 - fi - else - echo "[ERROR] Neither systemctl nor service command found. Please start Docker manually." - return 1 - fi + 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 + + echo "ERROR: Unable to install Docker automatically. Please install Docker manually." return 1 } From 17f806e6605cc79eea33417215a8cac631b0e927 Mon Sep 17 00:00:00 2001 From: Tianyong Qiu Date: Mon, 3 Mar 2025 10:32:12 +0800 Subject: [PATCH 3/8] Update for encoding git repo password and username --- devbox/devbox.local/cli/devbox | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/devbox/devbox.local/cli/devbox b/devbox/devbox.local/cli/devbox index 594a9cb..d13f5b1 100644 --- a/devbox/devbox.local/cli/devbox +++ b/devbox/devbox.local/cli/devbox @@ -456,6 +456,12 @@ declare -g local_components_ports_keys=("devsvc" "notification" "content" "centr local_components_ports_values=("8007" "8003" "8013" "8005" "8012" "8004") + +# used for repository username and password encoding +url_encode() { + echo "$1" | sed 's/@/%40/g' +} + # Get the port number for a local component get_port() { local comp="$1" @@ -713,6 +719,11 @@ devbox_init_command() { exit 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 @@ -827,9 +838,11 @@ devbox_init_command() { exit 1 fi + ENCODEING_FREELEAPS_USERNAME=$(url_encode "$FREELEAPS_USERNAME") + ENCODEING_FREELEAPS_PASSWORD=$(url_encode "$FREELEAPS_PASSWORD") # Test if the user can access the freeleaps.com repository echo "==> Testing access to freeleaps.com repository..." - if ! git ls-remote "https://$FREELEAPS_USERNAME:$FREELEAPS_PASSWORD@freeleaps.com:3443/products/freeleaps.git" &>/dev/null; then + if ! git ls-remote "https://$ENCODEING_FREELEAPS_USERNAME:$ENCODEING_FREELEAPS_PASSWORD@freeleaps.com:3443/products/freeleaps.git" &>/dev/null; then echo "ERROR: Failed to access freeleaps.com repository. Please check your username and password." echo "==> [INIT] DevBox environment initialization completed successfully, but access to the freeleaps.com repository failed." exit 1 @@ -838,7 +851,7 @@ devbox_init_command() { DOVBOX_CLI_DIR=$(pwd) FREELEAPS_DIR="$WORKING_HOME/freeleaps" - FRONTEND_GIT_URL="https://$FREELEAPS_USERNAME:$FREELEAPS_PASSWORD@freeleaps.com:3443/products/freeleaps.git" + FRONTEND_GIT_URL="https://$ENCODEING_FREELEAPS_USERNAME:$ENCODEING_FREELEAPS_PASSWORD@freeleaps.com:3443/products/freeleaps.git" # Check if freeleaps2-frontend exists, if not git clone it if [ ! -d "$FREELEAPS_DIR" ]; then pushd "$WORKING_HOME" > /dev/null From 7a5ee3be23d86760e5b54607d452daf759ffc822 Mon Sep 17 00:00:00 2001 From: timqiu <9145422+cocoonwind@user.noreply.gitee.com> Date: Thu, 6 Mar 2025 16:32:20 +0800 Subject: [PATCH 4/8] Update for adding USE_CUSTOM_REPOSITORY parameter --- devbox/devbox.local/cli/devbox | 789 +++++++++++++++++++++------------ 1 file changed, 508 insertions(+), 281 deletions(-) diff --git a/devbox/devbox.local/cli/devbox b/devbox/devbox.local/cli/devbox index d13f5b1..f061d0a 100644 --- a/devbox/devbox.local/cli/devbox +++ b/devbox/devbox.local/cli/devbox @@ -80,8 +80,8 @@ devbox_init_usage() { 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-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" @@ -105,9 +105,10 @@ devbox_init_usage() { printf " --authentication-image-repo -V [Optional] : Specifies the repository for authentication component.\n" printf " --authentication-image-name -L [Optional] : Specifies the image name for authentication component.\n" printf " --authentication-image-tag -W [Optional] : Specifies the image tag for authentication component. Default: latest.\n" - printf " --chat-image-repo -B [Optional] : Specifies the repository for chat component.\n" + printf " --use-custom-repository -C [Optional] : Specifies the custom git repository for source code.\n" + printf " --chat-image-repo -M [Optional] : Specifies the repository for chat component.\n" printf " --chat-image-name -N [Optional] : Specifies the image name for chat component.\n" - printf " --chat-image-tag -T [Optional] : Specifies the image tag for chat component. Default: latest.\n" + printf " --chat-image-tag -O [Optional] : Specifies the image tag for chat component. Default: latest.\n" printf " --force -f [Optional] : Force initialization even if resources already exist.\n\n" @@ -134,6 +135,7 @@ devbox_deinit_usage() { 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" @@ -143,6 +145,8 @@ devbox_deinit_usage() { 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 @@ -244,17 +248,21 @@ 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 =~ ^(--[a-zA-Z0-9_\-]+)=(.+)$ ]]; then + elif [[ $arg =~ $regex ]]; then input+=("${BASH_REMATCH[1]}") input+=("${BASH_REMATCH[2]}") - elif [[ $arg =~ ^(-[a-zA-Z0-9])=(.+)$ ]]; then + elif [[ $arg =~ $regex2 ]]; then input+=("${BASH_REMATCH[1]}") input+=("${BASH_REMATCH[2]}") - elif [[ $arg =~ ^-([a-zA-Z0-9][a-zA-Z0-9]+)$ ]]; then + elif [[ $arg =~ $regex3 ]]; then flags="${BASH_REMATCH[1]}" for ((i = 0; i < ${#flags}; i++)); do input+=("-${flags:i:1}") @@ -450,9 +458,7 @@ check_docker_running() { } # Define the local components and their corresponding ports -# local_components_ports_keys=("devsvc" "notification" "content" "central_storage" "chat" "authentication") - -declare -g local_components_ports_keys=("devsvc" "notification" "content" "central_storage" "chat" "authentication") +local_components_ports_keys=("devsvc" "notification" "content" "central_storage" "chat" "authentication") local_components_ports_values=("8007" "8003" "8013" "8005" "8012" "8004") @@ -527,7 +533,7 @@ devbox_init_command() { local CHAT_IMAGE="$args_chat_image_image" # --chat-image-image local CHAT_TAG="$args_chat_image_tag" # --chat-image-tag - local CUSTOM_GIT_REPO="$args_custom_git_repo" # --custom-git-repo + local USE_CUSTOM_REPOSITORY="$args_use_custom_repository" # --use-custom-repository # --force flag to overwrite existing resources local FORCE_INIT="${args_force}" @@ -563,8 +569,7 @@ devbox_init_command() { local CHAT_REPO="$(get_arg '--chat-image-repo')" local CHAT_IMAGE="$(get_arg '--chat-image-name')" local CHAT_TAG="$(get_arg '--chat-image-tag')" - - local CUSTOM_GIT_REPO="$(get_arg '--custom-git-repo')" + local USE_CUSTOM_REPOSITORY="$(get_arg '--use-custom-repository')" local FORCE_INIT="$(get_arg '--force')" @@ -767,9 +772,17 @@ devbox_init_command() { # 5.1 pull and start DevBox container # ------------------------------------------------------------------- local devbox_full_image="${DEVBOX_REPO}/${DEVBOX_IMAGE}:${DEVBOX_TAG}" - echo "==> Pulling DevBox image: $devbox_full_image" - if ! docker pull "$devbox_full_image"; then - echo "ERROR: Failed to pull DevBox image: $devbox_full_image" + + # 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 + echo "==> DevBox image $devbox_full_image already exists." + else + echo "==> Pulling DevBox image $devbox_full_image..." + docker pull "$devbox_full_image" + fi + else + echo "ERROR: DevBox image repository, name, or tag is not specified." exit 1 fi @@ -829,7 +842,7 @@ devbox_init_command() { # 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"] + echo "$DEVBOX_BACKEND_PORT" > "$WORKING_HOME/.devbox-backend-port" # Check if username and password are set if [[ -z "$FREELEAPS_USERNAME" || -z "$FREELEAPS_PASSWORD" ]]; then @@ -838,46 +851,91 @@ devbox_init_command() { exit 1 fi - ENCODEING_FREELEAPS_USERNAME=$(url_encode "$FREELEAPS_USERNAME") - ENCODEING_FREELEAPS_PASSWORD=$(url_encode "$FREELEAPS_PASSWORD") - # Test if the user can access the freeleaps.com repository - echo "==> Testing access to freeleaps.com repository..." - if ! git ls-remote "https://$ENCODEING_FREELEAPS_USERNAME:$ENCODEING_FREELEAPS_PASSWORD@freeleaps.com:3443/products/freeleaps.git" &>/dev/null; then - echo "ERROR: Failed to access freeleaps.com repository. Please check your username and password." - echo "==> [INIT] DevBox environment initialization completed successfully, but access to the freeleaps.com repository failed." - exit 1 - fi DOVBOX_CLI_DIR=$(pwd) + + # 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 + echo "==> Testing access to freeleaps.com repository..." + if ! git ls-remote "https://$ENCODEING_FREELEAPS_USERNAME:$ENCODEING_FREELEAPS_PASSWORD@freeleaps.com:3443/products/freeleaps.git" &>/dev/null; then + echo "ERROR: Failed to access freeleaps.com repository. Please check your username and password." + echo "==> [INIT] DevBox environment initialization completed successfully, but access to the freeleaps.com repository failed." + exit 1 + fi - FREELEAPS_DIR="$WORKING_HOME/freeleaps" - FRONTEND_GIT_URL="https://$ENCODEING_FREELEAPS_USERNAME:$ENCODEING_FREELEAPS_PASSWORD@freeleaps.com:3443/products/freeleaps.git" - # Check if freeleaps2-frontend exists, if not git clone it - if [ ! -d "$FREELEAPS_DIR" ]; then - pushd "$WORKING_HOME" > /dev/null - echo "Git cloning freeleaps.com:3443/products/freeleaps.git 1" - git clone --depth 5 $FRONTEND_GIT_URL - else - echo "Git pulling 2" - 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 - echo "Cloning repository again: $FRONTEND_GIT_URL" - sudo chown -R "$OWNER_GROUP" "$WORKING_HOME" - git clone --depth 5 "$FRONTEND_GIT_URL" - else - echo "Git pulling freeleaps.com:3443/products/freeleaps.git" - git pull + FREELEAPS_DIR="$WORKING_HOME/freeleaps" + FRONTEND_GIT_URL="https://$ENCODEING_FREELEAPS_USERNAME:$ENCODEING_FREELEAPS_PASSWORD@freeleaps.com:3443/products/freeleaps.git" + # Check if freeleaps2-frontend exists, if not git clone it + if [ ! -d "$FREELEAPS_DIR" ]; then + pushd "$WORKING_HOME" > /dev/null + echo "Git cloning freeleaps.com:3443/products/freeleaps.git 1" + git clone --depth 5 $FRONTEND_GIT_URL + else + echo "Git pulling 2" + 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 + echo "Cloning repository again: $FRONTEND_GIT_URL" + sudo chown -R "$OWNER_GROUP" "$WORKING_HOME" + git clone --depth 5 "$FRONTEND_GIT_URL" + else + echo "Git pulling freeleaps.com:3443/products/freeleaps.git" + git pull + fi + + popd > /dev/null + fi + else + if [[ ! $USE_CUSTOM_REPOSITORY =~ ^(https:\/\/|git@|git:\/\/|file:\/\/\/)[^ ]+\.git$ ]]; then + echo "ERROR: Invalid custom repository URL. Please provide a valid URL." + echo "==> [INIT] DevBox environment initialization completed successfully, but access to the custom repository failed." + exit 1 fi - popd > /dev/null - fi + # Test if the user can access the custom repository + echo "==> Testing access to custom repository..." + if ! git ls-remote "$USE_CUSTOM_REPOSITORY" &>/dev/null; then + echo "ERROR: Failed to access custom repository. Please check the repository URL." + echo "==> [INIT] DevBox environment initialization completed successfully, but access to the custom repository failed." + exit 1 + fi + 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 + echo "Git cloning custom repository: $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 + echo "Cloning repository again: $USE_CUSTOM_REPOSITORY" + sudo chown -R "$OWNER_GROUP" "$WORKING_HOME" + git clone --depth 5 "$USE_CUSTOM_REPOSITORY" + else + echo "Git pulling custom repository" + git pull + fi + + popd > /dev/null + fi + fi + pushd $DOVBOX_CLI_DIR > /dev/null # ------------------------------------------------------------------- @@ -889,8 +947,24 @@ echo "==> [INIT] Starting Freeleaps services... Use Local component $USE_LOCAL_C 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 + echo + echo "===========================================================" + echo "==> [INIT] Custom repository initialization completed." + echo "==> Custom repository is located at: ${WORKING_HOME}/${CUSTOM_FOLDER_NAME}" + echo "==> Custom repository URL: $USE_CUSTOM_REPOSITORY" + echo "==> Custom repository is ready for use." + echo "===========================================================" + echo + + exit 0 +fi + # Check if [[ $USE_LOCAL_COMPONENT_VAL == true ]]; then @@ -946,18 +1020,11 @@ if [[ $USE_LOCAL_COMPONENT_VAL == true ]]; then mkdir -p ${WORKING_HOME}/logs - mkdir -p ${WORKING_HOME}/logs/devsvc - mkdir -p ${WORKING_HOME}/logs/content - mkdir -p ${WORKING_HOME}/logs/central_storage - mkdir -p ${WORKING_HOME}/logs/authentication - mkdir -p ${WORKING_HOME}/logs/notification - mkdir -p ${WORKING_HOME}/logs/chat - # for each component create log directory for component in "${start_components[@]}"; do - if [[ ! -d "${WORKING_HOME}/log/${component}" ]]; then - mkdir -p "${WORKING_HOME}/log/${component}" + if [[ ! -d "${WORKING_HOME}/logs/${component}" ]]; then + mkdir -p "${WORKING_HOME}/logs/${component}" fi done @@ -973,7 +1040,6 @@ if [[ $USE_LOCAL_COMPONENT_VAL == true ]]; then rabbitmq_container_id=$(docker ps --no-trunc -a --filter "name=^freeleaps2-rabbitmq$" --format "{{.ID}}") echo "$rabbitmq_container_id" > "$WORKING_HOME/.rabbitmq-instance" - # Get all components container ids and save to .component-instance file for component in "${start_components[@]}"; do @@ -1051,7 +1117,6 @@ export USE_LOCAL_COMPONENT_VAL="${USE_LOCAL_COMPONENT_VAL}" export DEVBOX_BACKEND_PORT="${DEVBOX_BACKEND_PORT}" export DEVBOX_FRONTEND_PORT="${DEVBOX_FRONTEND_PORT}" - # Check if useing local component and update /home/devbox/freeleaps/.dev.env echo "step 2: Update /home/devbox/freeleaps/apps/.env" # Get default IP address @@ -1176,7 +1241,7 @@ pip install -r /home/devbox/freeleaps/apps/requirements.txt echo '============================================' -echo 'Start to run start_webapi.sh' +echo 'Start backend service locally' echo '============================================' ./start_webapi.sh > /home/devbox/logs/backend.logs 2>&1 & BACKEND_PID=\$! @@ -1293,8 +1358,6 @@ fi echo "Freeleaps services started successfully" EOF - - # ------------------------------------------------------------------- # 10. Final notification # ------------------------------------------------------------------- @@ -1324,15 +1387,14 @@ devbox_deinit_command() { local WORKING_HOME="$(get_arg '--working-home' "${HOME}/devbox")" local CLEAR_LOGS="$(get_arg '--clear-logs')" local CLEAR_REPO="$(get_arg '--clear-repo')" - - local FORCE="$(get_arg '--force')" + local CLEAR_ALL="$(get_arg '--clear-all')" # print the parameters echo "==> Deinitialization parameters:" echo " WORKING_HOME = $WORKING_HOME" echo " CLEAR_LOGS = $CLEAR_LOGS" echo " CLEAR_REPO = $CLEAR_REPO" - echo " FORCE = $FORCE" + echo " CLEAR_ALL = $CLEAR_ALL" echo "==> Starting DevBox deinitialization..." @@ -1429,6 +1491,25 @@ devbox_deinit_command() { fi fi + if [[ "$CLEAR_ALL" == "true" ]]; then + # Check Y/N to remove the working home directory + 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 + if [[ "$user_input" == "Y" || "$user_input" == "y" ]]; then + REMOVE_WORKING_HOME=true + + # Remove the working home directory + echo "==> Removing working home directory: $WORKING_HOME" + sudo chown -R $(whoami):$(whoami) "$WORKING_HOME" + rm -rf "$WORKING_HOME" 2>/dev/null || true + rmdir "$WORKING_HOME" 2>/dev/null || true + + echo "==> Working home directory removed successfully." + else + REMOVE_WORKING_HOME=false + echo "==> 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 - for i in {1..5}; do echo -n "=" @@ -1438,7 +1519,7 @@ devbox_deinit_command() { # Remove the use-local-component file rm -f "$WORKING_HOME/.use-local-component" - echo "> DevBox deinitialization completed." + echo "==> DevBox deinitialization completed." } # :command.function @@ -1447,6 +1528,22 @@ 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 + + echo "FREELEAPS_ENDPOINT: $FREELEAPS_ENDPOINT, START_FRONTEND: $START_FRONTEND, START_BACKEND: $START_BACKEND" # Check if the DevBox container is running local devbox_container_id_file_path="${WORKING_HOME}/.devbox-instance" @@ -1526,8 +1623,8 @@ devbox_start_command() { done - - if [[ "$FREELEAPS_ENDPOINT" == "true" ]]; then +# 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 @@ -1541,119 +1638,137 @@ devbox_start_command() { echo "==> Starting Freeleaps frontend and backend services..." # Start the backend and frontend services docker exec -i "$devbox_container_id" bash < /home/devbox/logs/backend.logs 2>&1 & -BACKEND_PID=\$! - -# Save BACKEND_PID to a file \${WORKING_HOME}/.backend.pid: Stores the process id of backend process. -echo "\$BACKEND_PID" > /home/devbox/.backend.pid - -# Check if the backend service started successfully -sleep 10 -if ! ps -p "\$BACKEND_PID" &>/dev/null; then - echo "ERROR: Backend service failed to start." - exit 1 -fi - -# Test backend and frontend services -echo "Testing backend and frontend services..." - -# Test the backend service -echo "Testing backend service..." -attempt=0 -max_attempts=10 -while [ \$attempt -lt \$max_attempts ]; do - http_code=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$SERVICE_API_ACCESS_PORT/docs") - if [ "\$http_code" -eq 200 ]; then - break + # CHeck if the virtual environment is created + if [ ! -f "venv_t/bin/activate" ]; then + echo "ERROR: The virtual environment cannot be created" + exit 1 fi - attempt=\$((attempt+1)) - sleep 5 -done -if [ \$attempt -eq \$max_attempts ]; then - echo "ERROR: Backend service is not available after \$max_attempts attempts." - exit 1 + echo '============================================' + echo ' Start to activate virtual environment' + echo '============================================' + source venv_t/bin/activate + source /home/devbox/freeleaps/apps/.env + + # Verify the virtual environment is activated + if [[ "\$VIRTUAL_ENV" != "" ]]; then + echo "Virtual environment activate: \$VIRTUAL_ENV" + else + echo "ERROR: The virtual environment cannot be startup \$VIRTUAL_ENV" + exit 1 + fi + + # 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 & + BACKEND_PID=\$! + + # Save BACKEND_PID to a file \${WORKING_HOME}/.backend.pid: Stores the process id of backend process. + echo "\$BACKEND_PID" > /home/devbox/.backend.pid + + # Check if the backend service started successfully + sleep 10 + if ! ps -p "\$BACKEND_PID" &>/dev/null; then + echo "ERROR: Backend service failed to start." + exit 1 + fi + + # Test the backend service + echo "Testing backend service..." + + attempt=0 + max_attempts=10 + while [ \$attempt -lt \$max_attempts ]; do + http_code=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$SERVICE_API_ACCESS_PORT/docs") + if [ "\$http_code" -eq 200 ]; then + break + fi + attempt=\$((attempt+1)) + sleep 5 + done + + if [ \$attempt -eq \$max_attempts ]; then + echo "ERROR: Backend service is not available after \$max_attempts attempts." + exit 1 + fi + + echo "Backend service is available (HTTP \$http_code)" fi - # Start the frontend service +if [[ "${START_FRONTEND}" == "true" ]]; then -echo '============================================' -echo ' Start frontend service locally' -echo '============================================' -pushd /home/devbox/freeleaps/frontend + echo '============================================' + echo ' Start frontend service locally' + echo '============================================' + pushd /home/devbox/freeleaps/frontend -npm run dev > /home/devbox/logs/frontend.logs 2>&1 & -FRONTEND_PID=\$! + # Check if the frontend service is already running according to the package.json and pnpm-lock.yaml files timestamps + if [[ ! -d "node_modules" || "package.json" -nt "node_modules" || "pnpm-lock.yaml" -nt "node_modules" ]]; then + echo "==> Installing/Updating frontend dependencies..." -echo "\$FRONTEND_PID" > /home/devbox/.frontend.pid + # Clean up old dependencies + rm -rf node_modules -# Check if the frontend service started successfully -sleep 10 -if ! ps -p "\$FRONTEND_PID" &>/dev/null; then - echo "ERROR: Frontend service failed to start." - exit 1 -fi - - -# Test the frontend service - -WEB_APP_ACCESS_PORT=\$(cat /home/devbox/.devbox-frontend-port) - -echo "Testing frontend service... PORT: \$WEB_APP_ACCESS_PORT" -attempt=0 -max_attempts=10 -while [ \$attempt -lt \$max_attempts ]; do - HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$WEB_APP_ACCESS_PORT/") - # Check HTTP Code 200 - if [ "\$HTTP_CODE" -eq 200 ]; then - echo "Frontend is available (HTTP \$HTTP_CODE)" - break - else - echo "Attempt \$((attempt+1)): Frontend not available (HTTP \$HTTP_CODE). Waiting..." - attempt=\$((attempt+1)) - sleep 10 + # Install dependencies + pnpm install --prefer-offline --frozen-lockfile || { + echo "ERROR: Failed to install dependencies" + exit 1 + } fi -done -if [ \$attempt -eq \$max_attempts ]; then - echo "ERROR: Frontend service is not available after \$max_attempts attempts." - exit 1 -fi + npm run dev > /home/devbox/logs/frontend.logs 2>&1 & + FRONTEND_PID=\$! -echo "Backend and frontend services started successfully." + echo "\$FRONTEND_PID" > /home/devbox/.frontend.pid + + # Check if the frontend service started successfully + sleep 10 + if ! ps -p "\$FRONTEND_PID" &>/dev/null; then + echo "ERROR: Frontend service failed to start." + exit 1 + fi + + + # Test the frontend service + WEB_APP_ACCESS_PORT=\$(cat /home/devbox/.devbox-frontend-port) + + + echo "Testing frontend service... PORT: \$WEB_APP_ACCESS_PORT" + attempt=0 + max_attempts=10 + while [ \$attempt -lt \$max_attempts ]; do + HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$WEB_APP_ACCESS_PORT/") + echo "HTTP_CODE: \$HTTP_CODE" + # Check HTTP Code 200 + if [ "\$HTTP_CODE" -eq 200 ]; then + echo "Frontend is available (HTTP \$HTTP_CODE)" + break + else + echo "Attempt \$((attempt+1)): Frontend not available (HTTP \$HTTP_CODE). Waiting..." + attempt=\$((attempt+1)) + sleep 10 + fi + done + + if [ \$attempt -eq \$max_attempts ]; then + echo "ERROR: Frontend service is not available after \$max_attempts attempts." + exit 1 + fi + + +fi + +echo "Freeleaps services started successfully" EOF else echo "ERROR: DevBox container is not running." @@ -1831,6 +1946,21 @@ devbox_restart_command() { 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 devbox container file path local devbox_container_id_file_path="${WORKING_HOME}/.devbox-instance" if [[ ! -f "$devbox_container_id_file_path" ]]; then @@ -1919,7 +2049,8 @@ devbox_restart_command() { esac done -if [[ "$FREELEAPS_ENDPOINT" == "true" ]]; then +# 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 @@ -1930,119 +2061,138 @@ if [[ "$FREELEAPS_ENDPOINT" == "true" ]]; then done # Start the backend and frontend services docker exec -i "$devbox_container_id" bash < /home/devbox/logs/backend.logs 2>&1 & -BACKEND_PID=\$! - -# Save BACKEND_PID to a file \${WORKING_HOME}/.backend.pid: Stores the process id of backend process. -echo "\$BACKEND_PID" > /home/devbox/.backend.pid - -# Check if the backend service started successfully -sleep 10 -if ! ps -p "\$BACKEND_PID" &>/dev/null; then - echo "ERROR: Backend service failed to start." - exit 1 -fi - -# Test backend and frontend services -echo "Testing backend and frontend services..." - -# Test the backend service -echo "Testing backend service..." -attempt=0 -max_attempts=10 -while [ \$attempt -lt \$max_attempts ]; do - http_code=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$SERVICE_API_ACCESS_PORT/docs") - if [ "\$http_code" -eq 200 ]; then - break + # CHeck if the virtual environment is created + if [ ! -f "venv_t/bin/activate" ]; then + echo "ERROR: The virtual environment cannot be created" + exit 1 fi - attempt=\$((attempt+1)) - sleep 5 -done -if [ \$attempt -eq \$max_attempts ]; then - echo "ERROR: Backend service is not available after \$max_attempts attempts." - exit 1 -fi + echo '============================================' + echo ' Start to activate virtual environment' + echo '============================================' + source venv_t/bin/activate + source /home/devbox/freeleaps/apps/.env - -# Start the frontend service - -echo '============================================' -echo ' Start frontend service locally' -echo '============================================' -pushd /home/devbox/freeleaps/frontend - -npm run dev > /home/devbox/logs/frontend.logs 2>&1 & -FRONTEND_PID=\$! - -echo "\$FRONTEND_PID" > /home/devbox/.frontend.pid - -# Check if the frontend service started successfully -sleep 10 -if ! ps -p "\$FRONTEND_PID" &>/dev/null; then - echo "ERROR: Frontend service failed to start." - exit 1 -fi - - -# Test the frontend service -WEB_APP_ACCESS_PORT=\$(cat /home/devbox/.devbox-frontend-port) - -echo "Testing frontend service..." -attempt=0 -max_attempts=10 -while [ \$attempt -lt \$max_attempts ]; do - http_code=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$WEB_APP_ACCESS_PORT/") - if [ "\$http_code" -eq 200 ]; then - echo "Frontend service is available (HTTP \$http_code)" - break + # Verify the virtual environment is activated + if [[ "\$VIRTUAL_ENV" != "" ]]; then + echo "Virtual environment activate: \$VIRTUAL_ENV" else - echo "Attempt \$((attempt+1)): Frontend not available (HTTP \$http_code). Waiting..." - attempt=\$((attempt+1)) - sleep 10 + echo "ERROR: The virtual environment cannot be startup \$VIRTUAL_ENV" + exit 1 fi -done -if [ \$attempt -eq \$max_attempts ]; then - echo "ERROR: Frontend service is not available after \$max_attempts attempts." - exit 1 + # 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 & + BACKEND_PID=\$! + + # Save BACKEND_PID to a file \${WORKING_HOME}/.backend.pid: Stores the process id of backend process. + echo "\$BACKEND_PID" > /home/devbox/.backend.pid + + # Check if the backend service started successfully + sleep 10 + if ! ps -p "\$BACKEND_PID" &>/dev/null; then + echo "ERROR: Backend service failed to start." + exit 1 + fi + + # Test backend and frontend services + echo "Testing backend and frontend services..." + + # Test the backend service + echo "Testing backend service..." + attempt=0 + max_attempts=10 + while [ \$attempt -lt \$max_attempts ]; do + http_code=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$SERVICE_API_ACCESS_PORT/docs") + if [ "\$http_code" -eq 200 ]; then + break + fi + attempt=\$((attempt+1)) + sleep 5 + done + + if [ \$attempt -eq \$max_attempts ]; then + echo "ERROR: Backend service is not available after \$max_attempts attempts." + exit 1 + fi + +fi + + +if [[ "${START_FRONTEND}" == "true" ]]; then + # Start the frontend service + + echo '============================================' + echo ' Start frontend service locally' + echo '============================================' + pushd /home/devbox/freeleaps/frontend + + npm run dev > /home/devbox/logs/frontend.logs 2>&1 & + FRONTEND_PID=\$! + + echo "\$FRONTEND_PID" > /home/devbox/.frontend.pid + + # Check if the frontend service started successfully + sleep 10 + if ! ps -p "\$FRONTEND_PID" &>/dev/null; then + echo "ERROR: Frontend service failed to start." + exit 1 + fi + + + # Test the frontend service + WEB_APP_ACCESS_PORT=\$(cat /home/devbox/.devbox-frontend-port) + + # Check if the frontend service is already running according to the package.json and pnpm-lock.yaml files timestamps + if [[ ! -d "node_modules" || "package.json" -nt "node_modules" || "pnpm-lock.yaml" -nt "node_modules" ]]; then + echo "==> Installing/Updating frontend dependencies..." + + # Clean up old dependencies + rm -rf node_modules + + # Install dependencies + pnpm install --prefer-offline --frozen-lockfile || { + echo "ERROR: Failed to install dependencies" + exit 1 + } + fi + + echo "Testing frontend service..." + attempt=0 + max_attempts=10 + while [ \$attempt -lt \$max_attempts ]; do + http_code=\$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:\$WEB_APP_ACCESS_PORT/") + if [ "\$http_code" -eq 200 ]; then + echo "Frontend service is available (HTTP \$http_code)" + break + else + echo "Attempt \$((attempt+1)): Frontend not available (HTTP \$http_code). Waiting..." + attempt=\$((attempt+1)) + sleep 10 + fi + done + + if [ \$attempt -eq \$max_attempts ]; then + echo "ERROR: Frontend service is not available after \$max_attempts attempts." + exit 1 + fi fi -echo "Backend and frontend services started successfully." +echo "Freeleaps services started successfully" EOF fi @@ -2253,7 +2403,7 @@ devbox_init_parse_requirements() { fi ;; # :flag.case - --devbox-image-repo | -R) + --devbox-image-repo | -D) # :flag.case_arg if [[ -n ${2+x} ]]; then add_arg '--devbox-image-repo' "$2" @@ -2275,7 +2425,7 @@ devbox_init_parse_requirements() { fi ;; # :flag.case - --devbox-image-tag | -T) + --devbox-image-tag | -g) # :flag.case_arg if [[ -n ${2+x} ]]; then add_arg '--devbox-image-tag' "$2" @@ -2318,6 +2468,15 @@ devbox_init_parse_requirements() { 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 | -u) if [[ -n ${2+x} ]]; then @@ -2329,7 +2488,7 @@ devbox_init_parse_requirements() { fi ;; # :flag.case - --devsvc-image-repo | -D) + --devsvc-image-repo | -t) # :flag.case_arg if [[ -n ${2+x} ]]; then add_arg '--devsvc-image-repo' "$2" @@ -2483,7 +2642,7 @@ devbox_init_parse_requirements() { fi ;; # :flag.case - --chat-image-repo | -B) + --chat-image-repo | -R) if [[ -n ${2+x} ]]; then add_arg '--chat-image-repo' "$2" shift 2 @@ -2540,6 +2699,22 @@ devbox_init_parse_requirements() { 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" ]; 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 @@ -2569,19 +2744,55 @@ devbox_init_parse_requirements() { fi if [ -z "$(get_arg '--devsvc-image-tag')" ]; then - add_arg '--devsvc-image-tag' "latest-linux-arm64" + if [ "$current_arch" == "arm64" ]; then + add_arg '--devsvc-image-tag' "latest-linux-arm64" + else + add_arg '--devsvc-image-tag' "latest-linux-amd64" + fi fi if [ -z "$(get_arg '--content-image-tag')" ]; then - add_arg '--content-image-tag' "latest-linux-arm64" + if [ "$current_arch" == "arm64" ]; then + add_arg '--content-image-tag' "latest-linux-arm64" + else + add_arg '--content-image-tag' "latest-linux-amd64" + fi fi if [ -z "$(get_arg '--central_storage-image-tag')" ]; then - add_arg '--central_storage-image-tag' "latest-linux-arm64" + if [ "$current_arch" == "arm64" ]; then + add_arg '--central_storage-image-tag' "latest-linux-arm64" + else + add_arg '--central_storage-image-tag' "latest-linux-amd64" + fi + fi + + if [ -z "$(get_arg '--chat-image-tag')" ]; then + if [ "$current_arch" == "arm64" ]; then + add_arg '--chat-image-tag' "latest-linux-arm64" + else + add_arg '--chat-image-tag' "latest-linux-amd64" + fi + fi + + if [ -z "$(get_arg '--notification-image-tag')" ]; then + if [ "$current_arch" == "arm64" ]; then + add_arg '--notification-image-tag' "latest-linux-arm64" + else + add_arg '--notification-image-tag' "latest-linux-amd64" + fi fi if [ -z "$(get_arg '--authentication-image-tag')" ]; then - add_arg '--authentication-image-tag' "latest-linux-arm64" + if [ "$current_arch" == "arm64" ]; then + add_arg '--authentication-image-tag' "latest-linux-arm64" + else + add_arg '--authentication-image-tag' "latest-linux-amd64" + fi + fi + + if [ -z "$(get_arg '--use-custom-repository')" ]; then + add_arg '--use-custom-repository' "" fi if [ -z "$(get_arg '--working-home')" ]; then @@ -2661,6 +2872,19 @@ devbox_deinit_parse_requirements() { 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 @@ -2687,6 +2911,9 @@ devbox_deinit_parse_requirements() { 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 } @@ -2762,7 +2989,7 @@ devbox_start_parse_requirements() { # :command.default_assignments if [ -z "$(get_arg '--freeleaps-endpoint')" ]; then - add_arg '--freeleaps-endpoint' "false" + add_arg '--freeleaps-endpoint' "" fi } @@ -2931,7 +3158,7 @@ devbox_restart_parse_requirements() { shift shift else - printf "%s\n" "--freeleaps-endpoint requires an argument: --freeleaps-endpoint FREELEAPS_ENDPOINT" >&2 + printf "%s\n" "--freeleaps-endpoint requires an argument: --freeleaps-endpoint all/backend/frontend" >&2 exit 1 fi ;; @@ -2954,7 +3181,7 @@ devbox_restart_parse_requirements() { # :command.default_assignments if [ -z "$(get_arg '--freeleaps-endpoint')" ]; then - add_arg '--freeleaps-endpoint' "false" + add_arg '--freeleaps-endpoint' "" fi } From 3b0be08c55fab1e78aa5bdffcbb4af807acd215d Mon Sep 17 00:00:00 2001 From: timqiu <9145422+cocoonwind@user.noreply.gitee.com> Date: Fri, 7 Mar 2025 10:32:01 +0800 Subject: [PATCH 5/8] update for docker compose typo for redis image --- devbox/devbox.local/cli/devbox | 9 ++++----- .../devbox.local/cli/docker-compose.dev.arm64.new.yaml | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/devbox/devbox.local/cli/devbox b/devbox/devbox.local/cli/devbox index 457c57d..4789b29 100644 --- a/devbox/devbox.local/cli/devbox +++ b/devbox/devbox.local/cli/devbox @@ -895,12 +895,12 @@ devbox_init_command() { popd > /dev/null fi else - if [[ ! $USE_CUSTOM_REPOSITORY =~ ^(https:\/\/|git@|git:\/\/|file:\/\/\/)[^ ]+\.git$ ]]; then - echo "ERROR: Invalid custom repository URL. Please provide a valid URL." - echo "==> [INIT] DevBox environment initialization completed successfully, but access to the custom repository failed." - exit 1 + if ! echo "$USE_CUSTOM_REPOSITORY" | grep -Eq '^(https:\/\/|git@|git:\/\/|file:\/\/\/)[^ ]+\.git$'; then + echo "ERROR: Invalid custom repository URL. Please provide a valid URL." + exit 1 fi + # Test if the user can access the custom repository echo "==> Testing access to custom repository..." if ! git ls-remote "$USE_CUSTOM_REPOSITORY" &>/dev/null; then @@ -1093,7 +1093,6 @@ 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 diff --git a/devbox/devbox.local/cli/docker-compose.dev.arm64.new.yaml b/devbox/devbox.local/cli/docker-compose.dev.arm64.new.yaml index 3ef6e4d..8ffa650 100644 --- a/devbox/devbox.local/cli/docker-compose.dev.arm64.new.yaml +++ b/devbox/devbox.local/cli/docker-compose.dev.arm64.new.yaml @@ -64,7 +64,7 @@ services: redis: platform: linux/${ARCH:-arm64} container_name: freeleaps2-redis - image: rabbitmq:latest + image: redis:latest restart: always ports: - 6379:6379 From 3d483a3b99ead1914bee34fa5c209f53320e01a4 Mon Sep 17 00:00:00 2001 From: timqiu <9145422+cocoonwind@user.noreply.gitee.com> Date: Mon, 10 Mar 2025 00:58:30 +0800 Subject: [PATCH 6/8] Update for all checkout file reset when init. stop/start, restart --- devbox/devbox.local/cli/devbox | 578 ++++++++++++--------------------- 1 file changed, 209 insertions(+), 369 deletions(-) diff --git a/devbox/devbox.local/cli/devbox b/devbox/devbox.local/cli/devbox index 4789b29..c7bf460 100644 --- a/devbox/devbox.local/cli/devbox +++ b/devbox/devbox.local/cli/devbox @@ -49,6 +49,7 @@ get_arg() { } + # :command.usage devbox_usage() { printf "Command\n" @@ -82,34 +83,16 @@ devbox_init_usage() { 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-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 -F [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 -u [Optional] : Check if using local component or online dev environment. Default: false.\n" - printf " --devsvc-image-repo -D [Optional] : Specifies the repository for devsvc component.\n" - printf " --devsvc-image-name -M [Optional] : Specifies the image name for devsvc component.\n" - printf " --devsvc-image-tag -G [Optional] : Specifies the image tag for devsvc component. Default: latest.\n" - printf " --notification-image-repo -Y [Optional] : Specifies the repository for notification component.\n" - printf " --notification-image-name -K [Optional] : Specifies the image name for notification component.\n" - printf " --notification-image-tag -Z [Optional] : Specifies the image tag for notification component. Default: latest.\n" - printf " --content-image-repo -C [Optional] : Specifies the repository for content component.\n" - printf " --content-image-name -E [Optional] : Specifies the image name for content component.\n" - printf " --content-image-tag -H [Optional] : Specifies the image tag for content component. Default: latest.\n" - printf " --central_storage-image-repo -S [Optional] : Specifies the repository for central_storage component.\n" - printf " --central_storage-image-name -J [Optional] : Specifies the image name for central_storage component.\n" - printf " --central_storage-image-tag -Q [Optional] : Specifies the image tag for central_storage component. Default: latest.\n" - printf " --authentication-image-repo -V [Optional] : Specifies the repository for authentication component.\n" - printf " --authentication-image-name -L [Optional] : Specifies the image name for authentication component.\n" - printf " --authentication-image-tag -W [Optional] : Specifies the image tag for authentication component. Default: latest.\n" - printf " --use-custom-repository -C [Optional] : Specifies the custom git repository for source code.\n" - printf " --chat-image-repo -M [Optional] : Specifies the repository for chat component.\n" - printf " --chat-image-name -N [Optional] : Specifies the image name for chat component.\n" - printf " --chat-image-tag -O [Optional] : Specifies the image tag for chat component. Default: latest.\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" @@ -457,6 +440,31 @@ check_docker_running() { return 1 } +build_local_image() { + local dockerfile_path="$1" + echo "==> [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 + echo "ERROR: Image build failed: $WORKING_HOME/build.log" + exit 1 + fi + + # Check if the image is built successfully + if ! docker inspect $devbox_full_image | grep -q 'amd64'; then + echo "ERROR:" + exit 1 + fi +} + # Define the local components and their corresponding ports local_components_ports_keys=("devsvc" "notification" "content" "central_storage" "chat" "authentication") @@ -481,6 +489,18 @@ get_port() { echo "$port" } +# Build the local image +build_local_image() { + local dockerfile_path="$1" + echo "==> [BUILD] Building local image..." + docker buildx build \ + --platform linux/amd64 \ + --build-arg BUILDARCH="x86-64-v3" \ + -t $devbox_full_image \ + -f "$dockerfile_path" . +} + + # :command.command_functions # :command.function devbox_init_command() { @@ -508,30 +528,7 @@ devbox_init_command() { local USE_LOCAL_COMPONENT="$args_use_local_component" # --use-local-component - local DEVSVC_REPO="$args_devsvc_image_repo" # --devsvc-image-repo - local DEVSVC_IMAGE="$args_devsvc_image_image" # --devsvc-image-image - local DEVSVC_TAG="$args_devsvc_image_tag" # --devsvc-image-tag - - - local CONTENT_REPO="$args_content_image_repo" # --content-image-repo - local CONTENT_IMAGE="$args_content_image_image" # --content-image-image - local CONTENT_TAG="$args_content_image_tag" # --content-image-tag - - local CENTRAL_STORAGE_REPO="$args_central_storage_image_repo" # --central_storage-image-repo - local CENTRAL_STORAGE_IMAGE="$args_central_storage_image_image" # --central_storage-image-image - local CENTRAL_STORAGE_TAG="$args_central_storage_image_tag" # --central_storage-image-tag - - local AUTHENTICATION_REPO="$args_authentication_image_repo" # --authentication-image-repo - local AUTHENTICATION_IMAGE="$args_authentication_image_image" # --authentication-image-image - local AUTHENTICATION_TAG="$args_authentication_image_tag" # --authentication-image-tag - - local NOTIFICATION_REPO="$args_notification_image_repo" # --notification-image-repo - local NOTIFICATION_IMAGE="$args_notification_image_image" # --notification-image-image - local NOTIFICATION_TAG="$args_notification_image_tag" # --notification-image-tag - - local CHAT_REPO="$args_chat_image_repo" # --chat-image-repo - local CHAT_IMAGE="$args_chat_image_image" # --chat-image-image - local CHAT_TAG="$args_chat_image_tag" # --chat-image-tag + local FREELEAPS_COMPONENTS="$args_freeleaps_components" # --freeleaps-components local USE_CUSTOM_REPOSITORY="$args_use_custom_repository" # --use-custom-repository @@ -551,24 +548,8 @@ devbox_init_command() { local FREELEAPS_USERNAME="$(get_arg '--freeleaps-username')" local FREELEAPS_PASSWORD="$(get_arg '--freeleaps-password')" local USE_LOCAL_COMPONENT="$(get_arg '--use-local-component')" - local DEVSVC_REPO="$(get_arg '--devsvc-image-repo')" - local DEVSVC_IMAGE="$(get_arg '--devsvc-image-name')" - local DEVSVC_TAG="$(get_arg '--devsvc-image-tag')" - local CONTENT_REPO="$(get_arg '--content-image-repo')" - local CONTENT_IMAGE="$(get_arg '--content-image-name')" - local CONTENT_TAG="$(get_arg '--content-image-tag')" - local CENTRAL_STORAGE_REPO="$(get_arg '--central_storage-image-repo')" - local CENTRAL_STORAGE_IMAGE="$(get_arg '--central_storage-image-name')" - local CENTRAL_STORAGE_TAG="$(get_arg '--central_storage-image-tag')" - local AUTHENTICATION_REPO="$(get_arg '--authentication-image-repo')" - local AUTHENTICATION_IMAGE="$(get_arg '--authentication-image-name')" - local AUTHENTICATION_TAG="$(get_arg '--authentication-image-tag')" - local NOTIFICATION_REPO="$(get_arg '--notification-image-repo')" - local NOTIFICATION_IMAGE="$(get_arg '--notification-image-name')" - local NOTIFICATION_TAG="$(get_arg '--notification-image-tag')" - local CHAT_REPO="$(get_arg '--chat-image-repo')" - local CHAT_IMAGE="$(get_arg '--chat-image-name')" - local CHAT_TAG="$(get_arg '--chat-image-tag')" + + local FREELEAPS_COMPONENTS="$(get_arg '--freeleaps-components')" local USE_CUSTOM_REPOSITORY="$(get_arg '--use-custom-repository')" local FORCE_INIT="$(get_arg '--force')" @@ -588,57 +569,48 @@ devbox_init_command() { is_pull_all_components=false fi - echo "==> Checking parameters..." - for component in "${components[@]}"; do - if [[ -n "$(get_arg "--${component}-image-repo")" ]]; then - is_pull_all_components=false - start_components+=("${component}") - fi + # split FREELEAPS_COMPONENTS + freeleaps_components=() + if [[ -n "$FREELEAPS_COMPONENTS" ]]; then + freeleaps_components=($(echo "$FREELEAPS_COMPONENTS" | tr ',' ' ')) + fi - # Check ARCH match default component tag value and justify the default Image tag value - if [[ "$ARCH" == "amd64" && "$component" == "devsvc" ]]; then - DEVSVC_TAG="latest-linux-amd64" - elif [[ "$ARCH" == "arm64" && "$component" == "devsvc" ]]; then - DEVSVC_TAG="latest-linux-arm64" + # 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 + echo "ERROR: Invalid component: $component" + exit 1 fi + done - if [[ "$ARCH" == "amd64" && "$component" == "content" ]]; then - CONTENT_TAG="latest-linux-amd64" - elif [[ "$ARCH" == "arm64" && "$component" == "content" ]]; then - CONTENT_TAG="latest-linux-arm64" - fi - - if [[ "$ARCH" == "amd64" && "$component" == "central_storage" ]]; then - CENTRAL_STORAGE_TAG="latest-linux-amd64" - elif [[ "$ARCH" == "arm64" && "$component" == "central_storage" ]]; then - CENTRAL_STORAGE_TAG="latest-linux-arm64" - fi - - if [[ "$ARCH" == "amd64" && "$component" == "authentication" ]]; then - AUTHENTICATION_TAG="latest-linux-amd64" - elif [[ "$ARCH" == "arm64" && "$component" == "authentication" ]]; then - AUTHENTICATION_TAG="latest-linux-arm64" - fi - - if [[ "$ARCH" == "amd64" && "$component" == "notification" ]]; then - NOTIFICATION_TAG="latest-linux-amd64" - elif [[ "$ARCH" == "arm64" && "$component" == "notification" ]]; then - NOTIFICATION_TAG="latest-linux-arm64" - fi - - if [[ "$ARCH" == "amd64" && "$component" == "chat" ]]; then - CHAT_TAG="latest-linux-amd64" - elif [[ "$ARCH" == "arm64" && "$component" == "chat" ]]; then - CHAT_TAG="latest-linux-arm64" - fi - done + start_components=("${freeleaps_components[@]}") + else + start_components=("${components[@]}") + fi + component_tag="latest-linux-arm64" + if [[ "$ARCH" == "amd64" ]]; then + component_tag="latest-linux-amd64" + fi # If is_pull_all_components is true, then pull all components if [[ "$is_pull_all_components" == true ]]; then start_components=("${components[@]}") + echo "==> Pulling all components..." + echo "==> start components: ${start_components[@]}" fi + # Remove duplicated components + start_components=($(echo "${start_components[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) + echo " ===================================================== " echo "Parameters:" echo " OS = $OS" @@ -654,24 +626,7 @@ devbox_init_command() { echo " FREELEAPS_USERNAME= $FREELEAPS_USERNAME" echo " (FREELEAPS_PASSWORD is hidden for security)" echo " USE_LOCAL_COMPONENT= $USE_LOCAL_COMPONENT" - echo " DEVSVC_REPO = $DEVSVC_REPO" - echo " DEVSVC_IMAGE = $DEVSVC_IMAGE" - echo " DEVSVC_TAG = $DEVSVC_TAG" - echo " CONTENT_REPO = $CONTENT_REPO" - echo " CONTENT_IMAGE = $CONTENT_IMAGE" - echo " CONTENT_TAG = $CONTENT_TAG" - echo " CENTRAL_STORAGE_REPO = $CENTRAL_STORAGE_REPO" - echo " CENTRAL_STORAGE_IMAGE= $CENTRAL_STORAGE_IMAGE" - echo " CENTRAL_STORAGE_TAG = $CENTRAL_STORAGE_TAG" - echo " AUTHENTICATION_REPO = $AUTHENTICATION_REPO" - echo " AUTHENTICATION_IMAGE= $AUTHENTICATION_IMAGE" - echo " AUTHENTICATION_TAG = $AUTHENTICATION_TAG" - echo " NOTIFICATION_REPO = $NOTIFICATION_REPO" - echo " NOTIFICATION_IMAGE= $NOTIFICATION_IMAGE" - echo " NOTIFICATION_TAG = $NOTIFICATION_TAG" - echo " CHAT_REPO = $CHAT_REPO" - echo " CHAT_IMAGE = $CHAT_IMAGE" - echo " CHAT_TAG = $CHAT_TAG" + echo " FREELEAPS_COMPONENTS= ${start_components[@]}" echo " FORCE_INIT = $FORCE_INIT" echo @@ -690,15 +645,20 @@ devbox_init_command() { fi # Check ARCH match current device + ARCH_MICRO="" if [[ "$ARCH" == "auto" ]]; then ARCH="$(uname -m)" if [[ "$ARCH" == "x86_64" ]]; then - ARCH="amd64" + # Check if the CPU supports AVX2 + if grep -q avx2 /proc/cpuinfo; then + ARCH="amd64" + ARCH_MICRO="v3" + echo "==> Detected AMD64 architecture." + else + ARCH="amd64" + fi elif [[ "$ARCH" == "aarch64" ]]; then ARCH="arm64" - else - echo "ERROR: Unsupported architecture: $ARCH" - exit 1 fi fi @@ -752,6 +712,7 @@ devbox_init_command() { exit 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 all start_components if [[ "${#start_components[@]}" -gt 0 ]]; then @@ -768,9 +729,7 @@ devbox_init_command() { fi - # ------------------------------------------------------------------- - # 5.1 pull and start DevBox container - # ------------------------------------------------------------------- + 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 @@ -970,12 +929,12 @@ if [[ $USE_LOCAL_COMPONENT_VAL == true ]]; then echo ' ===> Using local components for Freeleaps services.' - export DEVSVC_IMAGE_TAG="$DEVSVC_TAG" - export CONTENT_IMAGE_TAG="$CONTENT_TAG" - export CENTRAL_STORAGE_IMAGE_TAG="$CENTRAL_STORAGE_TAG" - export AUTHENTICATION_IMAGE_TAG="$AUTHENTICATION_TAG" - export NOTIFICATION_IMAGE_TAG="$NOTIFICATION_TAG" - export CHAT_IMAGE_TAG="$CHAT_TAG" + 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 @@ -1032,6 +991,9 @@ if [[ $USE_LOCAL_COMPONENT_VAL == true ]]; then echo "===> start Gitea, MongoDB, RabbitMQ and other components containers" docker-compose -f docker-compose.dev.arm64.new.yaml up -d mongodb rabbitmq gitea redis "${start_components[@]}" + echo "===> start components is $start_components" + + gitea_container_id=$(docker ps --no-trunc -a --filter "name=^freeleaps2-gitea$" --format "{{.ID}}") echo "$gitea_container_id" > "$WORKING_HOME/.gitea-instance" @@ -1060,13 +1022,19 @@ if [[ $USE_LOCAL_COMPONENT_VAL == true ]]; then OWNER_GROUP=$(stat -c "%U:%G" "${WORKING_HOME}") fi + # Check all components are started + for component in "${start_components[@]}"; do + if [[ -z "$(docker ps -a --format '{{.Names}}' | grep "^$component\$")" ]]; then + echo "ERROR: Failed to start $component container." + exit 1 + fi + done else echo '============================================' echo ' ===> Using online components for Freeleaps services.' echo '============================================' # Start Gitea, MongoDB, RabbitMQ containers docker-compose -f docker-compose.dev.arm64.new.yaml up -d mongodb rabbitmq redis - echo "===> start components is $start_components" # Save MongoDB and RabbitMQ container ids to .mongodb-instance and .rabbitmq-instance mongo_container_id=$(docker ps -a --format '{{.Names}}' | grep "^freeleaps2-mongodb\$") @@ -1079,13 +1047,6 @@ else echo "$redis_container_id" > "$WORKING_HOME/.redis-instance" fi -# Check all components are started -for component in "${start_components[@]}"; do - if [[ -z "$(docker ps -a --format '{{.Names}}' | grep "^$component\$")" ]]; then - echo "ERROR: Failed to start $component container." - exit 1 - fi -done # Save $USE_LOCAL_COMPONENT false/true to $WORKING_HOME/.use-local-component @@ -1285,6 +1246,10 @@ if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then exit 1 fi +rm -rf /home/devbox/freeleaps/apps/backend_env.sh || true + +echo "WebAPI service started successfully" + echo '============================================' echo ' Start frontend service locally' @@ -1330,7 +1295,6 @@ FRONTEND_PID=\$! echo "npm run dev has been started with PID: \$FRONTEND_PID" echo "\$FRONTEND_PID" > /home/devbox/.frontend.pid - echo '============================================' # Wait for the frontend service to start @@ -1361,6 +1325,11 @@ if [ \$ATTEMPT -eq \$MAX_ATTEMPTS ]; then fi +pushd /home/devbox/freeleaps +git config --global --add safe.directory /home/devbox/freeleaps +git reset --hard + + echo "Freeleaps services started successfully" EOF @@ -1505,10 +1474,11 @@ devbox_deinit_command() { # Remove the working home directory echo "==> Removing working home directory: $WORKING_HOME" - sudo chown -R $(whoami):$(whoami) "$WORKING_HOME" - rm -rf "$WORKING_HOME" 2>/dev/null || true - rmdir "$WORKING_HOME" 2>/dev/null || true - + if [[ -d "$WORKING_HOME" ]]; then + sudo chown -R $(whoami):$(whoami) "$WORKING_HOME" + rm -rf "$WORKING_HOME" 2>/dev/null || true + rmdir "$WORKING_HOME" 2>/dev/null || true + fi echo "==> Working home directory removed successfully." else REMOVE_WORKING_HOME=false @@ -1648,9 +1618,11 @@ if [[ "$FREELEAPS_ENDPOINT" != "" ]]; then # Check if start backend service if [[ "${START_BACKEND}" == "true" ]]; then # Start the backend service + echo '============================================' echo ' Start backend service locally' echo '============================================' + pushd /home/devbox/freeleaps/apps # CHeck if the virtual environment is created @@ -1718,6 +1690,12 @@ if [[ "${START_FRONTEND}" == "true" ]]; then echo '============================================' pushd /home/devbox/freeleaps/frontend + # echo "==> Starting frontend service..." + baseline_file=\$(mktemp) + echo "==> Creating a baseline file for the frontend service..." + git status -s > "\$baseline_file" + echo "==> Baseline file created: \$baseline_file" + # Check if the frontend service is already running according to the package.json and pnpm-lock.yaml files timestamps if [[ ! -d "node_modules" || "package.json" -nt "node_modules" || "pnpm-lock.yaml" -nt "node_modules" ]]; then echo "==> Installing/Updating frontend dependencies..." @@ -1726,7 +1704,7 @@ if [[ "${START_FRONTEND}" == "true" ]]; then rm -rf node_modules # Install dependencies - pnpm install --prefer-offline --frozen-lockfile || { + pnpm install --prefer-offline || { echo "ERROR: Failed to install dependencies" exit 1 } @@ -1771,8 +1749,26 @@ if [[ "${START_FRONTEND}" == "true" ]]; then exit 1 fi + current_file=\$(mktemp) + git status -s > "\$current_file" -fi + echo "==> Checking for modified files in the frontend service..." + while read -r line; do + # Print the file name + echo "\$line" + file=\$(echo "\$line" | awk '{print \$2}') + echo "File: \$file" + # Check if the file is not in the baseline file + if ! grep -q "[[:space:]]\$file\$" "\$baseline_file"; then + echo "==> File \$file has been modified. Resetting..." + git reset HEAD "\$file" + git checkout -- "\$file" + fi + done < \$current_file + + # Remove the temporary files + rm "\$baseline_file" "\$current_file" +fi echo "Freeleaps services started successfully" EOF @@ -1782,9 +1778,6 @@ EOF fi fi - - - echo "==> DevBox services started successfully." } @@ -2069,8 +2062,6 @@ if [[ "$FREELEAPS_ENDPOINT" != "" ]]; then docker exec -i "$devbox_container_id" bash < Starting frontend service..." + baseline_file=\$(mktemp) + echo "==> Creating a baseline file for the frontend service..." + git status -s > "\$baseline_file" + echo "==> Baseline file created: \$baseline_file" + + # Check if the frontend service is already running according to the package.json and pnpm-lock.yaml files timestamps + if [[ ! -d "node_modules" || "package.json" -nt "node_modules" || "pnpm-lock.yaml" -nt "node_modules" ]]; then + echo "==> Installing/Updating frontend dependencies..." + + # Clean up old dependencies + rm -rf node_modules + + # Install dependencies + pnpm install --prefer-offline || { + echo "ERROR: Failed to install dependencies" + exit 1 + } + fi + npm run dev > /home/devbox/logs/frontend.logs 2>&1 & FRONTEND_PID=\$! @@ -2163,21 +2172,7 @@ if [[ "${START_FRONTEND}" == "true" ]]; then # Test the frontend service WEB_APP_ACCESS_PORT=\$(cat /home/devbox/.devbox-frontend-port) - # Check if the frontend service is already running according to the package.json and pnpm-lock.yaml files timestamps - if [[ ! -d "node_modules" || "package.json" -nt "node_modules" || "pnpm-lock.yaml" -nt "node_modules" ]]; then - echo "==> Installing/Updating frontend dependencies..." - - # Clean up old dependencies - rm -rf node_modules - - # Install dependencies - pnpm install --prefer-offline --frozen-lockfile || { - echo "ERROR: Failed to install dependencies" - exit 1 - } - fi - - echo "Testing frontend service..." + echo "Testing frontend service... PORT: \$WEB_APP_ACCESS_PORT" attempt=0 max_attempts=10 while [ \$attempt -lt \$max_attempts ]; do @@ -2196,6 +2191,26 @@ if [[ "${START_FRONTEND}" == "true" ]]; then echo "ERROR: Frontend service is not available after \$max_attempts attempts." exit 1 fi + + current_file=\$(mktemp) + git status -s > "\$current_file" + + echo "==> Checking for modified files in the frontend service..." + while read -r line; do + # Print the file name + echo "\$line" + file=\$(echo "\$line" | awk '{print \$2}') + echo "File: \$file" + # Check if the file is not in the baseline file + if ! grep -q "[[:space:]]\$file\$" "\$baseline_file"; then + echo "==> File \$file has been modified. Resetting..." + git reset HEAD "\$file" + git checkout -- "\$file" + fi + done < \$current_file + + # Remove the temporary files + rm "\$baseline_file" "\$current_file" fi echo "Freeleaps services started successfully" @@ -2367,7 +2382,7 @@ devbox_init_parse_requirements() { fi ;; # :flag.case - --devbox-container-name | -N) + --devbox-container-name | -n) # :flag.case_arg if [[ -n ${2+x} ]]; then add_arg '--devbox-container-name' "$2" @@ -2378,7 +2393,7 @@ devbox_init_parse_requirements() { fi ;; # :flag.case - --devbox-container-port | -P) + --devbox-container-port | -p) # :flag.case_arg if [[ -n ${2+x} ]]; then add_arg '--devbox-container-port' "$2" @@ -2388,7 +2403,7 @@ devbox_init_parse_requirements() { exit 1 fi ;; - --devbox-frontend-port | -F) + --devbox-frontend-port | -f) # :flag.case_arg if [[ -n ${2+x} ]]; then add_arg '--devbox-frontend-port' "$2" @@ -2398,7 +2413,7 @@ devbox_init_parse_requirements() { exit 1 fi ;; - --devbox-backend-port | -B) + --devbox-backend-port | -b) # :flag.case_arg if [[ -n ${2+x} ]]; then add_arg '--devbox-backend-port' "$2" @@ -2409,7 +2424,7 @@ devbox_init_parse_requirements() { fi ;; # :flag.case - --devbox-image-repo | -D) + --devbox-image-repo | -r) # :flag.case_arg if [[ -n ${2+x} ]]; then add_arg '--devbox-image-repo' "$2" @@ -2420,7 +2435,7 @@ devbox_init_parse_requirements() { fi ;; # :flag.case - --devbox-image-name | -I) + --devbox-image-name | -i) # :flag.case_arg if [[ -n ${2+x} ]]; then add_arg '--devbox-image-name' "$2" @@ -2431,7 +2446,7 @@ devbox_init_parse_requirements() { fi ;; # :flag.case - --devbox-image-tag | -g) + --devbox-image-tag | -t) # :flag.case_arg if [[ -n ${2+x} ]]; then add_arg '--devbox-image-tag' "$2" @@ -2453,7 +2468,7 @@ devbox_init_parse_requirements() { fi ;; # :flag.case - --freeleaps-username | -U) + --freeleaps-username | -u) # :flag.case_arg if [[ -n ${2+x} ]]; then add_arg '--freeleaps-username' "$2" @@ -2464,7 +2479,7 @@ devbox_init_parse_requirements() { fi ;; # :flag.case - --freeleaps-password | -X) + --freeleaps-password | -x) # :flag.case_arg if [[ -n ${2+x} ]]; then add_arg '--freeleaps-password' "$2" @@ -2484,7 +2499,7 @@ devbox_init_parse_requirements() { fi ;; # :flag.case - --use-local-component | -u) + --use-local-component | -l) if [[ -n ${2+x} ]]; then add_arg '--use-local-component' "$2" shift 2 @@ -2493,187 +2508,12 @@ devbox_init_parse_requirements() { exit 1 fi ;; - # :flag.case - --devsvc-image-repo | -t) - # :flag.case_arg + --freeleaps-components | -m) if [[ -n ${2+x} ]]; then - add_arg '--devsvc-image-repo' "$2" + add_arg '--freeleaps-components' "$2" shift 2 else - printf "%s\n" "--devsvc-image-repo requires an argument: --devsvc-image-repo DEVSVC_IMAGE_REPO" >&2 - exit 1 - fi - ;; - # :flag.case - --devsvc-image-name | -M) - # :flag.case_arg - if [[ -n ${2+x} ]]; then - add_arg '--devsvc-image-name' "$2" - shift 2 - else - printf "%s\n" "--devsvc-image-name requires an argument: --devsvc-image-name DEVSVC_IMAGE_NAME" >&2 - exit 1 - fi - ;; - # :flag.case - --devsvc-image-tag | -G) - # :flag.case_arg - if [[ -n ${2+x} ]]; then - add_arg '--devsvc-image-tag' "$2" - shift 2 - else - printf "%s\n" "--devsvc-image-tag requires an argument: --devsvc-image-tag DEVSVC_IMAGE_TAG" >&2 - exit 1 - fi - ;; - # :flag.case - --notification-image-repo | -Y) - # :flag.case_arg - if [[ -n ${2+x} ]]; then - add_arg '--notification-image-repo' "$2" - shift 2 - else - printf "%s\n" "--notification-image-repo requires an argument: --notification-image-repo NOTIFICATION_IMAGE_REPO" >&2 - exit 1 - fi - ;; - --notification-image-name | -K) - # :flag.case_arg - if [[ -n ${2+x} ]]; then - add_arg '--notification-image-name' "$2" - shift 2 - else - printf "%s\n" "--notification-image-name requires an argument: --notification-image-name NOTIFICATION_IMAGE_NAME" >&2 - exit 1 - fi - ;; - --notification-image-tag | -Z) - # :flag.case_arg - if [[ -n ${2+x} ]]; then - add_arg '--notification-image-tag' "$2" - shift 2 - else - printf "%s\n" "--notification-image-tag requires an argument: --notification-image-tag NOTIFICATION_IMAGE_TAG" >&2 - exit 1 - fi - ;; - # :flag.case - --content-image-repo | -C) - if [[ -n ${2+x} ]]; then - add_arg '--content-image-repo' "$2" - shift 2 - else - printf "%s\n" "--content-image-repo requires an argument: --content-image-repo FREELEAPS_CONTENT_IMAGE_REPO" >&2 - exit 1 - fi - ;; - # :flag.case - --content-image-name | -E) - if [[ -n ${2+x} ]]; then - add_arg '--content-image-name' "$2" - shift 2 - else - printf "%s\n" "--content-image-name requires an argument: --content-image-name FREELEAPS_CONTENT_IMAGE_NAME" >&2 - exit 1 - fi - ;; - # :flag.case - --content-image-tag | -H) - if [[ -n ${2+x} ]]; then - add_arg '--content-image-tag' "$2" - shift 2 - else - printf "%s\n" "--content-image-tag requires an argument: --content-image-tag FREELEAPS_CONTENT_IMAGE_TAG" >&2 - exit 1 - fi - ;; - # :flag.case - --central_storage-image-repo | -S) - if [[ -n ${2+x} ]]; then - add_arg '--central_storage-image-repo' "$2" - shift 2 - else - printf "%s\n" "--central_storage-image-repo requires an argument: --central_storage-image-repo FREELEAPS_CENTRAL_STORAGE_IMAGE_REPO" >&2 - exit 1 - fi - ;; - # :flag.case - --central_storage-image-name | -J) - if [[ -n ${2+x} ]]; then - add_arg '--central_storage-image-name' "$2" - shift 2 - else - printf "%s\n" "--central_storage-image-name requires an argument: --central_storage-image-name FREELEAPS_CENTRAL_STORAGE_IMAGE_NAME" >&2 - exit 1 - fi - ;; - # :flag.case - --central_storage-image-tag | -Q) - if [[ -n ${2+x} ]]; then - add_arg '--central_storage-image-tag' "$2" - shift 2 - else - printf "%s\n" "--central_storage-image-tag requires an argument: --central_storage-image-tag FREELEAPS_CENTRAL_STORAGE_IMAGE_TAG" >&2 - exit 1 - fi - ;; - # :flag.case - --authentication-image-repo | -V) - if [[ -n ${2+x} ]]; then - add_arg '--authentication-image-repo' "$2" - shift 2 - else - printf "%s\n" "--authentication-image-repo requires an argument: --authentication-image-repo FREELEAPS_AUTHENTICATION_IMAGE_REPO" >&2 - exit 1 - fi - ;; - # :flag.case - --authentication-image-name | -L) - if [[ -n ${2+x} ]]; then - add_arg '--authentication-image-name' "$2" - shift 2 - else - printf "%s\n" "--authentication-image-name requires an argument: --authentication-image-name FREELEAPS_AUTHENTICATION_IMAGE_NAME" >&2 - exit 1 - fi - ;; - # :flag.case - --authentication-image-tag | -W) - if [[ -n ${2+x} ]]; then - add_arg '--authentication-image-tag' "$2" - shift 2 - else - printf "%s\n" "--authentication-image-tag requires an argument: --authentication-image-tag FREELEAPS_AUTHENTICATION_IMAGE_TAG" >&2 - exit 1 - fi - ;; - # :flag.case - --chat-image-repo | -R) - if [[ -n ${2+x} ]]; then - add_arg '--chat-image-repo' "$2" - shift 2 - else - printf "%s\n" "--chat-image-repo requires an argument: --chat-image-repo FREELEAPS_CHAT_IMAGE_REPO" >&2 - exit 1 - fi - ;; - # :flag.case - --chat-image-name | -N) - if [[ -n ${2+x} ]]; then - add_arg '--chat-image-name' "$2" - shift 2 - else - printf "%s\n" "--chat-image-name requires an argument: --chat-image-name FREELEAPS_CHAT_IMAGE_NAME" >&2 - exit 1 - fi - ;; - # :flag.case - --chat-image-tag | -T) - if [[ -n ${2+x} ]]; then - add_arg '--chat-image-tag' "$2" - shift 2 - else - printf "%s\n" "--chat-image-tag requires an argument: --chat-image-tag FREELEAPS_CHAT_IMAGE_TAG" >&2 + printf "%s\n" "--freeleaps-components requires an argument: --freeleaps-components FREELEAPS_COMPONENTS" >&2 exit 1 fi ;; From 86226130b680751c6ca2131df0f10b9ef334e314 Mon Sep 17 00:00:00 2001 From: timqiu <9145422+cocoonwind@user.noreply.gitee.com> Date: Mon, 10 Mar 2025 10:29:50 +0800 Subject: [PATCH 7/8] Update for redis cleanup when deinit --- devbox/devbox.local/cli/devbox | 81 +++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/devbox/devbox.local/cli/devbox b/devbox/devbox.local/cli/devbox index c7bf460..dc5cc6e 100644 --- a/devbox/devbox.local/cli/devbox +++ b/devbox/devbox.local/cli/devbox @@ -853,46 +853,46 @@ devbox_init_command() { popd > /dev/null fi - else - if ! echo "$USE_CUSTOM_REPOSITORY" | grep -Eq '^(https:\/\/|git@|git:\/\/|file:\/\/\/)[^ ]+\.git$'; then - echo "ERROR: Invalid custom repository URL. Please provide a valid URL." + else + if ! echo "$USE_CUSTOM_REPOSITORY" | grep -Eq '^(https:\/\/|git@|git:\/\/|file:\/\/\/)[^ ]+\.git$'; then + echo "ERROR: Invalid custom repository URL. Please provide a valid URL." + exit 1 + fi + + # Check if the custom repository is a git repository + # Test if the user can access the custom repository + echo "==> Testing access to custom repository..." + if ! git ls-remote "$USE_CUSTOM_REPOSITORY" &>/dev/null; then + echo "ERROR: Failed to access custom repository. Please check the repository URL." + echo "==> [INIT] DevBox environment initialization completed successfully, but access to the custom repository failed." exit 1 - fi + fi + 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 + echo "Git cloning custom repository: $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 - # Test if the user can access the custom repository - echo "==> Testing access to custom repository..." - if ! git ls-remote "$USE_CUSTOM_REPOSITORY" &>/dev/null; then - echo "ERROR: Failed to access custom repository. Please check the repository URL." - echo "==> [INIT] DevBox environment initialization completed successfully, but access to the custom repository failed." - exit 1 - fi + # Git clone custom repository + echo "Cloning repository again: $USE_CUSTOM_REPOSITORY" + sudo chown -R "$OWNER_GROUP" "$WORKING_HOME" + git clone --depth 5 "$USE_CUSTOM_REPOSITORY" + else + echo "Git pulling custom repository" + git pull + fi - 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 - echo "Git cloning custom repository: $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 - echo "Cloning repository again: $USE_CUSTOM_REPOSITORY" - sudo chown -R "$OWNER_GROUP" "$WORKING_HOME" - git clone --depth 5 "$USE_CUSTOM_REPOSITORY" - else - echo "Git pulling custom repository" - git pull - fi - - popd > /dev/null - fi + popd > /dev/null + fi fi pushd $DOVBOX_CLI_DIR > /dev/null @@ -1410,6 +1410,15 @@ devbox_deinit_command() { rm -f "$WORKING_HOME/.mongodb-instance" fi + if [[ -f "$WORKING_HOME/.redis-instance" ]]; then + local redis_container_id + redis_container_id=$(cat "$WORKING_HOME/.redis-instance") + echo "==> Stopping and removing Redis container: $redis_container_id" + docker stop "$redis_container_id" &>/dev/null || true + docker rm "$redis_container_id" &>/dev/null || true + rm -f "$WORKING_HOME/.redis-instance" + fi + # Stop and remove RabbitMQ container if [[ -f "$WORKING_HOME/.rabbitmq-instance" ]]; then local rabbitmq_container_id From 48ecc5c14241318e5c53bc485dbd69f198801887 Mon Sep 17 00:00:00 2001 From: timqiu <9145422+cocoonwind@user.noreply.gitee.com> Date: Mon, 10 Mar 2025 10:43:21 +0800 Subject: [PATCH 8/8] Update for init help of --devbox-frontend-port -F to --devbox-frontend-port -f --- devbox/devbox.local/cli/devbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devbox/devbox.local/cli/devbox b/devbox/devbox.local/cli/devbox index dc5cc6e..b0f1c0c 100644 --- a/devbox/devbox.local/cli/devbox +++ b/devbox/devbox.local/cli/devbox @@ -86,7 +86,7 @@ devbox_init_usage() { 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 -F [Optional] : Specifies the container port for DevBox frontend access. Default: 5173.\n" + printf " --devbox-frontend-port -f [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"