From c9212123ec6e099af9255e0c758f0c0966d3d796 Mon Sep 17 00:00:00 2001 From: Kronk74 Date: Sun, 12 Jan 2025 22:22:49 +0100 Subject: [PATCH 1/4] feat: Add binary check requirements and more debug messages --- run-seedbox.sh | 52 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/run-seedbox.sh b/run-seedbox.sh index c8cc400..b5317d4 100755 --- a/run-seedbox.sh +++ b/run-seedbox.sh @@ -11,6 +11,37 @@ check_utilities SKIP_PULL=0 DEBUG=0 +echo "[$0] ***** Checking required tools... *****" +REQUIRED_TOOLS=("docker" "docker-compose" "yq" "jq") + +for tool in "${REQUIRED_TOOLS[@]}"; do + if ! command -v $tool &> /dev/null; then + echo "[$0] ERROR: $tool is not installed. Please install $tool and try again." + exit 1 + fi +done + +# Check if versions of required tools are correct +check_version() { + local tool=$1 + local required_version=$2 + local current_version=$($tool --version | grep -oP '\d+\.\d+') + if [[ $(echo -e "$current_version\n$required_version" | sort -V | head -n1) != "$required_version" ]]; then + echo "[$0] ERROR: $tool version $required_version or higher is required. Current version is $current_version." + exit 1 + fi +} + +# Define required versions for each tool +declare -A REQUIRED_VERSIONS +REQUIRED_VERSIONS=( ["docker"]="20.10" ["docker-compose"]="1.29" ["yq"]="4.6" ["jq"]="1.6" ) + +# Check versions +echo "[$0] ***** Checking version of required tools... *****" +for tool in "${!REQUIRED_VERSIONS[@]}"; do + check_version $tool ${REQUIRED_VERSIONS[$tool]} +done + for i in "$@"; do case $i in --no-pull) @@ -58,6 +89,7 @@ if [[ ! -f docker-compose.yaml ]]; then fi # Check if there are obsolete config still in .env but should be moved to .env.custom +echo-debug "[$0] ***** Checking obsolete configs... *****" if [[ $(grep "^MYSQL_.*" .env | wc -l) != 0 || $(grep "^WIREGUARD_.*" .env | wc -l) != 0 || $(grep "^NEXTCLOUD_.*" .env | wc -l) != 0 || $(grep "^PORTAINER_.*" .env | wc -l) != 0 || $(grep "^FLOOD_PASSWORD.*" .env | wc -l) != 0 || $(grep "^CALIBRE_PASSWORD.*" .env | wc -l) != 0 || $(grep "^PAPERLESS_.*" .env | wc -l) != 0 ]]; then echo "/!\ Some obsolete config has been detected in your .env." echo "It should be moved in .env.custom as they apply to specific app (this is new since v2.2 update - see documentation)." @@ -90,6 +122,7 @@ if [[ $(grep "^MYSQL_.*" .env | wc -l) != 0 || $(grep "^WIREGUARD_.*" .env | wc fi # Create/update http_auth file according to values in .env file +echo-debug "[$0] ***** Updating HTTP Auth file... *****" source .env echo "${HTTP_USER}:${HTTP_PASSWORD}" > traefik/http_auth @@ -101,6 +134,7 @@ fi # Input => $1 = app name (exemple traefik) # Output => env/app_name.env written with correct variables (exemple: env/traefik.env) extract_custom_env_file() { + echo-debug "[$0] Extracting custom env file for $1..." # sed explanation: # 1 => Remove all lines starting with a comment (#) # 2 => Remove all empty lines @@ -110,7 +144,9 @@ extract_custom_env_file() { } ## Traefik Certificate Resolver tweaks +echo-debug "[$0] ***** Updating Traefik Certificate Resolver... *****" if [[ ! -z ${TRAEFIK_CUSTOM_ACME_RESOLVER} ]]; then + echo-debug "[$0] Custom ACME resolver detected. Updating Traefik configuration..." if [[ ! -f .env.custom ]]; then echo "[$0] Error. You need to have a .env.custom in order to use TRAEFIK_CUSTOM_ACME_RESOLVER variable." exit 1 @@ -144,8 +180,14 @@ fi echo "[$0] ***** Checking configuration... *****" -yq eval -o json config.yaml > config.json +{ # try + yq eval -o json config.yaml > config.json +} || { # catch + echo "[$0] ERROR: config.yaml is not a valid YAML file. Please check it and try again." + exit 1 +} +echo-debug "[$0] ***** Checking for outdated config... *****" if [[ "${CHECK_FOR_OUTDATED_CONFIG}" == true ]]; then nb_services=$(cat config.json | jq '.services | length') nb_services_sample=$(yq eval -o json config.sample.yaml | jq '.services | length') @@ -172,17 +214,20 @@ check_result_service() { # Check if a service ($1) has been enabled in the config file is_service_enabled() { + echo-debug "[$0] Checking if service $1 is enabled..." local nb=$(cat config.json | jq --arg service $1 '[.services[] | select(.name==$service and .enabled==true)] | length') check_result_service $1 $nb } # Check if a service ($1) has been enabled AND has vpn enabled in the config file has_vpn_enabled() { + echo-debug "[$0] Checking if service $1 has VPN enabled..." local nb=$(cat config.json | jq --arg service $1 '[.services[] | select(.name==$service and .enabled==true and .vpn==true)] | length') check_result_service $1 $nb } # Check if some services have vpn enabled, that gluetun itself is enabled +echo-debug "[$0] Checking if gluetun is enabled when VPN is enabled for some services..." nb_vpn=$(cat config.json | jq '[.services[] | select(.enabled==true and .vpn==true)] | length') if [[ ${nb_vpn} -gt 0 ]] && ! is_service_enabled gluetun; then echo "[$0] ERROR. ${nb_vpn} VPN-enabled services have been enabled BUT gluetun has not been enabled. Please check your config.yaml file." @@ -193,6 +238,7 @@ fi # => If deluge vpn is enabled => gluetun # => If deluge vpn is disabled => deluge if is_service_enabled flood; then + echo "[$0] Flood is enabled. Checking Deluge status..." # Check that if flood is enabled, deluge should also be enabled if ! is_service_enabled deluge; then echo "[$0] ERROR. Flood is enabled but Deluge is not. Please either enable Deluge or disable Flood as Flood depends on Deluge." @@ -207,18 +253,21 @@ if is_service_enabled flood; then fi # Check that if calibre-web is enabled, calibre should also be enabled +echo-debug "[$0] Checking Calibre and Calibre-web status..." if is_service_enabled calibre-web && ! is_service_enabled calibre; then echo "[$0] ERROR. Calibre-web is enabled but Calibre is not. Please either enable Calibre or disable Calibre-web as Calibre-web depends on Calibre." exit 1 fi # Check that if nextcloud is enabled, mariadb should also be enabled +echo-debug "[$0] Checking Nextcloud and MariaDB status..." if is_service_enabled nextcloud && ! is_service_enabled mariadb; then echo "[$0] ERROR. Nextcloud is enabled but MariaDB is not. Please either enable MariaDB or disable Nextcloud as Nextcloud depends on MariaDB." exit 1 fi # Apply other arbitrary custom Traefik config files +echo-debug "[$0] Applying custom Traefik config files..." rm -f $f traefik/custom/custom-* for f in `find samples/custom-traefik -maxdepth 1 -mindepth 1 -type f | grep -E "\.yml$|\.yaml$" | sort`; do echo "[$0] Applying custom Traefik config $f..." @@ -226,6 +275,7 @@ for f in `find samples/custom-traefik -maxdepth 1 -mindepth 1 -type f | grep -E done # Detect Synology devices for Netdata compatibility +echo-debug "[$0] Detecting Synology devices for Netdata compatibility..." if is_service_enabled netdata; then if [[ $(uname -a | { grep synology || true; } | wc -l) -eq 1 ]]; then export OS_RELEASE_FILEPATH="/etc/VERSION" From 9aec80297ead588a2af34a49c1b3dbdca9e26310 Mon Sep 17 00:00:00 2001 From: Kronk74 Date: Sun, 12 Jan 2025 22:39:58 +0100 Subject: [PATCH 2/4] feat: Move requirements checks to check_utilities function --- run-seedbox.sh | 33 +-------------------------------- tools/tools.sh | 43 +++++++++++++++++++++++++++++-------------- 2 files changed, 30 insertions(+), 46 deletions(-) diff --git a/run-seedbox.sh b/run-seedbox.sh index b5317d4..33e33c8 100755 --- a/run-seedbox.sh +++ b/run-seedbox.sh @@ -11,37 +11,6 @@ check_utilities SKIP_PULL=0 DEBUG=0 -echo "[$0] ***** Checking required tools... *****" -REQUIRED_TOOLS=("docker" "docker-compose" "yq" "jq") - -for tool in "${REQUIRED_TOOLS[@]}"; do - if ! command -v $tool &> /dev/null; then - echo "[$0] ERROR: $tool is not installed. Please install $tool and try again." - exit 1 - fi -done - -# Check if versions of required tools are correct -check_version() { - local tool=$1 - local required_version=$2 - local current_version=$($tool --version | grep -oP '\d+\.\d+') - if [[ $(echo -e "$current_version\n$required_version" | sort -V | head -n1) != "$required_version" ]]; then - echo "[$0] ERROR: $tool version $required_version or higher is required. Current version is $current_version." - exit 1 - fi -} - -# Define required versions for each tool -declare -A REQUIRED_VERSIONS -REQUIRED_VERSIONS=( ["docker"]="20.10" ["docker-compose"]="1.29" ["yq"]="4.6" ["jq"]="1.6" ) - -# Check versions -echo "[$0] ***** Checking version of required tools... *****" -for tool in "${!REQUIRED_VERSIONS[@]}"; do - check_version $tool ${REQUIRED_VERSIONS[$tool]} -done - for i in "$@"; do case $i in --no-pull) @@ -550,7 +519,7 @@ rm -f .env.concat echo "[$0] ***** Clean unused images and volumes... *****" docker image prune -af -docker volume prune -f +docker volume prune -f echo "[$0] ***** Done! *****" exit 0 \ No newline at end of file diff --git a/tools/tools.sh b/tools/tools.sh index a87b794..d56709b 100755 --- a/tools/tools.sh +++ b/tools/tools.sh @@ -5,19 +5,34 @@ ############################################################################## check_utilities () { - # Check that jq is installed - if ! which jq >/dev/null; then - echo "[$0] jq does not exist. Install it from here: https://stedolan.github.io/jq/download/" - echo "[$0] Please install jq version 1.5 or above." - echo "[$0] Also, please make sure it is in the PATH." - exit 1 - fi + echo "[$0] ***** Checking required tools... *****" + REQUIRED_TOOLS=("docker" "docker compose" "yq" "jq") - # Check that yq is installed - if ! which yq >/dev/null; then - echo "[$0] yq does not exist. Install it from here: https://github.com/mikefarah/yq/releases" - echo "[$0] Please install yq version 4 or above." - echo "[$0] Also, please make sure it is in the PATH." - exit 1 - fi + for tool in "${REQUIRED_TOOLS[@]}"; do + if ! command -v $tool &> /dev/null; then + echo "[$0] ERROR: $tool is not installed. Please install $tool and try again." + exit 1 + fi + done + + # Check if versions of required tools are correct + check_version() { + local tool=$1 + local required_version=$2 + local current_version=$($tool --version | grep -oP '\d+\.\d+') + if [[ $(echo -e "$current_version\n$required_version" | sort -V | head -n1) != "$required_version" ]]; then + echo "[$0] ERROR: $tool version $required_version or higher is required. Current version is $current_version." + exit 1 + fi + } + + # Define required versions for each tool + declare -A REQUIRED_VERSIONS + REQUIRED_VERSIONS=( ["docker"]="20.10" ["docker-compose"]="1.29" ["yq"]="4.6" ["jq"]="1.6" ) + + # Check versions + echo "[$0] ***** Checking version of required tools... *****" + for tool in "${!REQUIRED_VERSIONS[@]}"; do + check_version $tool ${REQUIRED_VERSIONS[$tool]} + done } \ No newline at end of file From ba4845fcd96154c8f3717882ecd9928e7f5e399f Mon Sep 17 00:00:00 2001 From: Kronk74 Date: Sun, 19 Jan 2025 11:44:16 +0100 Subject: [PATCH 3/4] fix: docker compose binary in check requirements script --- run-seedbox.sh | 7 ++++--- tools/tools.sh | 24 ++++++++++++++---------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/run-seedbox.sh b/run-seedbox.sh index 33e33c8..f1243f2 100755 --- a/run-seedbox.sh +++ b/run-seedbox.sh @@ -5,9 +5,6 @@ set -e # Load common functions source tools/tools.sh -# Check that required tools are installed -check_utilities - SKIP_PULL=0 DEBUG=0 @@ -99,6 +96,9 @@ if [[ ! -d env ]]; then mkdir -p env fi +# Check that required tools are installed +check_utilities + # Sanitize and extract variable (without prefixes) from .env.custom file # Input => $1 = app name (exemple traefik) # Output => env/app_name.env written with correct variables (exemple: env/traefik.env) @@ -268,6 +268,7 @@ ALL_SERVICES="-f docker-compose.yaml" GLOBAL_ENV_FILE=".env" # Parse the config.yaml master configuration file +echo-debug "[$0] ***** Parsing the config.yaml master configuration file ... *****" for json in $(yq eval -o json config.yaml | jq -c ".services[]"); do name=$(echo $json | jq -r .name) enabled=$(echo $json | jq -r .enabled) diff --git a/tools/tools.sh b/tools/tools.sh index d56709b..3acf607 100755 --- a/tools/tools.sh +++ b/tools/tools.sh @@ -6,21 +6,25 @@ check_utilities () { echo "[$0] ***** Checking required tools... *****" - REQUIRED_TOOLS=("docker" "docker compose" "yq" "jq") - - for tool in "${REQUIRED_TOOLS[@]}"; do - if ! command -v $tool &> /dev/null; then - echo "[$0] ERROR: $tool is not installed. Please install $tool and try again." - exit 1 - fi - done # Check if versions of required tools are correct check_version() { local tool=$1 local required_version=$2 + + local required_major_version=$(echo $required_version | cut -d'.' -f1) + local required_minor_version=$(echo $required_version | cut -d'.' -f2) + local current_version=$($tool --version | grep -oP '\d+\.\d+') - if [[ $(echo -e "$current_version\n$required_version" | sort -V | head -n1) != "$required_version" ]]; then + local current_major_version=$(echo $current_version | cut -d'.' -f1) + local current_minor_version=$(echo $current_version | cut -d'.' -f2) + + if [[ $current_major_version -lt $required_major_version ]]; then + echo "[$0] ERROR: $tool version $required_version or higher is required. Current version is $current_version." + exit 1 + fi + + if [[ $current_major_version -eq $required_major_version && $current_minor_version -lt $required_minor_version ]]; then echo "[$0] ERROR: $tool version $required_version or higher is required. Current version is $current_version." exit 1 fi @@ -28,7 +32,7 @@ check_utilities () { # Define required versions for each tool declare -A REQUIRED_VERSIONS - REQUIRED_VERSIONS=( ["docker"]="20.10" ["docker-compose"]="1.29" ["yq"]="4.6" ["jq"]="1.6" ) + REQUIRED_VERSIONS=( ["docker"]="20.10" [$DOCKER_COMPOSE_BINARY]="2.27" ["yq"]="4.0" ["jq"]="1.5" ) # Check versions echo "[$0] ***** Checking version of required tools... *****" From e25ec3fa7ac4a27fc3c13a9a43eb65cf982c47b9 Mon Sep 17 00:00:00 2001 From: Kronk74 Date: Sun, 19 Jan 2025 12:37:58 +0100 Subject: [PATCH 4/4] feat: Purpose a new way of managing the seedbox --- run-seedbox.sh => prepare-configs.sh | 44 ------------- seedbox.sh | 95 ++++++++++++++++++++++++++++ tools/tools.sh | 10 +++ 3 files changed, 105 insertions(+), 44 deletions(-) rename run-seedbox.sh => prepare-configs.sh (95%) create mode 100755 seedbox.sh diff --git a/run-seedbox.sh b/prepare-configs.sh similarity index 95% rename from run-seedbox.sh rename to prepare-configs.sh index f1243f2..c8b7f0f 100755 --- a/run-seedbox.sh +++ b/prepare-configs.sh @@ -5,34 +5,6 @@ set -e # Load common functions source tools/tools.sh -SKIP_PULL=0 -DEBUG=0 - -for i in "$@"; do - case $i in - --no-pull) - SKIP_PULL=1 - ;; - --debug) - DEBUG=1 - ;; - *) - echo "[$0] ❌ ERROR: unknown parameter \"$i\"" - exit 1 - ;; - esac -done - -cleanup_on_exit() { - rm -f rules.props *-vpn.props *-envfile.props config.json - [[ -d env ]] && rm -f env/*.tmp -} -trap cleanup_on_exit EXIT - -echo-debug() { - if [[ ${DEBUG} == "1" ]]; then echo "$@"; fi -} - ############################################################################################### ####################################### Load variables ######################################## ############################################################################################### @@ -508,19 +480,3 @@ echo-debug "[$0] Here is the list of all files which are going to be processed: echo "[$0] ***** Config OK. Launching services... *****" -if [[ "${SKIP_PULL}" != "1" ]]; then - echo "[$0] ***** Pulling all images... *****" - ${DOCKER_COMPOSE_BINARY} ${ALL_SERVICES} pull -fi - -echo "[$0] ***** Recreating containers if required... *****" -${DOCKER_COMPOSE_BINARY} --env-file ${GLOBAL_ENV_FILE} ${ALL_SERVICES} up -d --remove-orphans -echo "[$0] ***** Done updating containers *****" -rm -f .env.concat - -echo "[$0] ***** Clean unused images and volumes... *****" -docker image prune -af -docker volume prune -f - -echo "[$0] ***** Done! *****" -exit 0 \ No newline at end of file diff --git a/seedbox.sh b/seedbox.sh new file mode 100755 index 0000000..3b76dfd --- /dev/null +++ b/seedbox.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +run_seedbox() { + + SKIP_PULL=0 + + for i in "$@"; do + case $i in + --no-pull) + SKIP_PULL=1 + ;; + --prune) + PRUNE=1 + ;; + -h|--help) + echo "[$0] Usage: $0 run [--no-pull|--prune]" + exit 0 + ;; + esac + done + + if [[ "${SKIP_PULL}" != "1" ]]; then + echo "[$0] ***** Pulling all images... *****" + ${DOCKER_COMPOSE_BINARY} ${ALL_SERVICES} pull + fi + + echo "[$0] ***** Recreating containers if required... *****" + ${DOCKER_COMPOSE_BINARY} --env-file ${GLOBAL_ENV_FILE} ${ALL_SERVICES} up -d --remove-orphans + echo "[$0] ***** Done updating containers *****" + rm -f .env.concat + + echo "[$0] ***** Clean unused images and volumes... *****" + if [[ "${PRUNE}" == "1" ]]; then + docker image prune -af + docker volume prune -f + fi + + echo "[$0] ***** Done! *****" + exit 0 +} + +stop_seedbox() { + + for i in "$@"; do + case $i in + --prune) + PRUNE=1 + ;; + -h|--help) + echo "[$0] Usage: $0 run [--prune]" + exit 0 + ;; + esac + done + + echo "[$0] ***** Stopping containers... *****" + ${DOCKER_COMPOSE_BINARY} --env-file ${GLOBAL_ENV_FILE} ${ALL_SERVICES} down + rm -f .env.concat + + if [[ "${PRUNE}" == "1" ]]; then + echo "[$0] ***** Clean unused images and volumes... *****" + docker image prune -af + docker volume prune -f + fi + + echo "[$0] ***** Done! *****" + exit 0 +} + +DEBUG=0 + +for i in "$@"; do + case $i in + --debug) + DEBUG=1 + ;; + esac +done + +source prepare-configs.sh + +case $1 in + run) + run_seedbox + ;; + stop) + stop_seedbox + ;; + *) + echo "[$0] ❌ ERROR: unknown parameter \"$1\"" + echo "[$0] Usage: $0 {run|stop}" + exit 1 + ;; +esac + diff --git a/tools/tools.sh b/tools/tools.sh index 3acf607..a74c36e 100755 --- a/tools/tools.sh +++ b/tools/tools.sh @@ -4,6 +4,16 @@ ############################### UTIL FUNCTIONS ############################### ############################################################################## +cleanup_on_exit() { + rm -f rules.props *-vpn.props *-envfile.props config.json + [[ -d env ]] && rm -f env/*.tmp +} +trap cleanup_on_exit EXIT + +echo-debug() { + if [[ ${DEBUG} == "1" ]]; then echo "$@"; fi +} + check_utilities () { echo "[$0] ***** Checking required tools... *****"