From 0ce28302bd769a86a62def217735a2599005aa2a Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Thu, 20 Feb 2025 21:42:11 +0100 Subject: [PATCH 01/17] implemented checking deploy file --- deploy/multideploy.sh | 114 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 deploy/multideploy.sh diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh new file mode 100644 index 00000000..ba57afa1 --- /dev/null +++ b/deploy/multideploy.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env sh + +# MULTIDEPLOY_CONFIG="default" + +######## Public functions ##################### + +MULTIDEPLOY_VERSION="1.0" +MULTIDEPLOY_FILENAME="multideploy.yaml" + +# domain keyfile certfile cafile fullchain pfx +multideploy_deploy() { + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + _cpfx="$6" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + _debug _cpfx "$_cpfx" + + DOMAIN_DIR=$_cdomain + if echo "$DOMAIN_PATH" | grep -q "$ECC_SUFFIX"; then + DOMAIN_DIR="$DOMAIN_DIR"_ecc + fi + _debug2 "DOMAIN_DIR" "$DOMAIN_DIR" + + _preprocess_deployfile "$DOMAIN_DIR/$MULTIDEPLOY_FILENAME" + + MULTIDEPLOY_CONFIG="${MULTIDEPLOY_CONFIG:-$(_getdeployconf MULTIDEPLOY_CONFIG)}" + if [ -z "$MULTIDEPLOY_CONFIG" ]; then + MULTIDEPLOY_CONFIG="default" + _info "MULTIDEPLOY_CONFIG is not set, so I will use 'default'." + else + _savedeployconf "MULTIDEPLOY_CONFIG" "$MULTIDEPLOY_CONFIG" + _debug2 "MULTIDEPLOY_CONFIG" "$MULTIDEPLOY_CONFIG" + fi + + # TODO: Deploy to services +} + +#################### Private functions below ##################### + +# deploy_filepath +_preprocess_deployfile() { + deploy_file="$1" + + # Check if yq is installed + if ! command -v yq >/dev/null 2>&1; then + _err "yq is not installed! Please install yq and try again." + return 1 + fi + + # Check if deploy file exists and create a default template if not + if [ -f "$deploy_file" ]; then + _debug3 "Deploy file found." + _check_deployfile "$deploy_file" "$MULTIDEPLOY_CONFIG" + else + # TODO: Replace URL with wiki link + _err "Deploy file not found. Go to https://CHANGE_URL_TO_WIKI to see how to create one." + return 1 + fi +} + +# deploy_filepath deploy_config +_check_deployfile() { + deploy_file="$1" + deploy_config="$3" + + # Check version + deploy_file_version=$(yq '.version' "$deploy_file") + if [ "$MULTIDEPLOY_VERSION" != "$deploy_file_version" ]; then + _err "As of $PROJECT_NAME $VER, the deploy file needs version $MULTIDEPLOY_VERSION! Your current deploy file is of version $deploy_file_version." + return 1 + fi + + # Check if config exists + if ! yq e ".configs[] | select(.name == \"$deploy_config\")" "$deploy_file" >/dev/null; then + _err "Config '$deploy_config' not found." + return 1 + fi + + # Extract all services from config + services=$(yq e ".configs[] | select(.name == \"$deploy_config\").services[]" "$deploy_file") + + if [ -z "$services" ]; then + _err "Config '$deploy_config' does not have any services to deploy to." + return 1 + fi + + # Check if extracted services exist in services list + for service in $services; do + if ! yq e ".services[] | select(.name == \"$service\")" "$deploy_file" >/dev/null; then + _err "Service '$service' not found." + return 1 + fi + + # Check if service has hook + if ! yq e ".services[] | select(.name == \"$service\").hook" "$deploy_file" >/dev/null; then + _err "Service '$service' does not have a hook." + return 1 + fi + + # Check if service has environment + if ! yq e ".services[] | select(.name == \"$service\").environment" "$deploy_file" >/dev/null; then + _err "Service '$service' does not an environment." + return 1 + fi + done +} From cfe32265a89e35dc627992ffb36b4e2bfd570156 Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Thu, 20 Feb 2025 21:56:28 +0100 Subject: [PATCH 02/17] fixed indents --- deploy/multideploy.sh | 174 +++++++++++++++++++++--------------------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index ba57afa1..08e0aba6 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -9,106 +9,106 @@ MULTIDEPLOY_FILENAME="multideploy.yaml" # domain keyfile certfile cafile fullchain pfx multideploy_deploy() { - _cdomain="$1" - _ckey="$2" - _ccert="$3" - _cca="$4" - _cfullchain="$5" - _cpfx="$6" - - _debug _cdomain "$_cdomain" - _debug _ckey "$_ckey" - _debug _ccert "$_ccert" - _debug _cca "$_cca" - _debug _cfullchain "$_cfullchain" - _debug _cpfx "$_cpfx" - - DOMAIN_DIR=$_cdomain - if echo "$DOMAIN_PATH" | grep -q "$ECC_SUFFIX"; then - DOMAIN_DIR="$DOMAIN_DIR"_ecc - fi - _debug2 "DOMAIN_DIR" "$DOMAIN_DIR" - - _preprocess_deployfile "$DOMAIN_DIR/$MULTIDEPLOY_FILENAME" - - MULTIDEPLOY_CONFIG="${MULTIDEPLOY_CONFIG:-$(_getdeployconf MULTIDEPLOY_CONFIG)}" - if [ -z "$MULTIDEPLOY_CONFIG" ]; then - MULTIDEPLOY_CONFIG="default" - _info "MULTIDEPLOY_CONFIG is not set, so I will use 'default'." - else - _savedeployconf "MULTIDEPLOY_CONFIG" "$MULTIDEPLOY_CONFIG" - _debug2 "MULTIDEPLOY_CONFIG" "$MULTIDEPLOY_CONFIG" - fi - - # TODO: Deploy to services + _cdomain="$1" + _ckey="$2" + _ccert="$3" + _cca="$4" + _cfullchain="$5" + _cpfx="$6" + + _debug _cdomain "$_cdomain" + _debug _ckey "$_ckey" + _debug _ccert "$_ccert" + _debug _cca "$_cca" + _debug _cfullchain "$_cfullchain" + _debug _cpfx "$_cpfx" + + DOMAIN_DIR=$_cdomain + if echo "$DOMAIN_PATH" | grep -q "$ECC_SUFFIX"; then + DOMAIN_DIR="$DOMAIN_DIR"_ecc + fi + _debug2 "DOMAIN_DIR" "$DOMAIN_DIR" + + _preprocess_deployfile "$DOMAIN_DIR/$MULTIDEPLOY_FILENAME" + + MULTIDEPLOY_CONFIG="${MULTIDEPLOY_CONFIG:-$(_getdeployconf MULTIDEPLOY_CONFIG)}" + if [ -z "$MULTIDEPLOY_CONFIG" ]; then + MULTIDEPLOY_CONFIG="default" + _info "MULTIDEPLOY_CONFIG is not set, so I will use 'default'." + else + _savedeployconf "MULTIDEPLOY_CONFIG" "$MULTIDEPLOY_CONFIG" + _debug2 "MULTIDEPLOY_CONFIG" "$MULTIDEPLOY_CONFIG" + fi + + # TODO: Deploy to services } #################### Private functions below ##################### # deploy_filepath _preprocess_deployfile() { - deploy_file="$1" - - # Check if yq is installed - if ! command -v yq >/dev/null 2>&1; then - _err "yq is not installed! Please install yq and try again." - return 1 - fi - - # Check if deploy file exists and create a default template if not - if [ -f "$deploy_file" ]; then - _debug3 "Deploy file found." - _check_deployfile "$deploy_file" "$MULTIDEPLOY_CONFIG" - else - # TODO: Replace URL with wiki link - _err "Deploy file not found. Go to https://CHANGE_URL_TO_WIKI to see how to create one." - return 1 - fi + deploy_file="$1" + + # Check if yq is installed + if ! command -v yq >/dev/null 2>&1; then + _err "yq is not installed! Please install yq and try again." + return 1 + fi + + # Check if deploy file exists and create a default template if not + if [ -f "$deploy_file" ]; then + _debug3 "Deploy file found." + _check_deployfile "$deploy_file" "$MULTIDEPLOY_CONFIG" + else + # TODO: Replace URL with wiki link + _err "Deploy file not found. Go to https://CHANGE_URL_TO_WIKI to see how to create one." + return 1 + fi } # deploy_filepath deploy_config _check_deployfile() { - deploy_file="$1" - deploy_config="$3" - - # Check version - deploy_file_version=$(yq '.version' "$deploy_file") - if [ "$MULTIDEPLOY_VERSION" != "$deploy_file_version" ]; then - _err "As of $PROJECT_NAME $VER, the deploy file needs version $MULTIDEPLOY_VERSION! Your current deploy file is of version $deploy_file_version." - return 1 + deploy_file="$1" + deploy_config="$3" + + # Check version + deploy_file_version=$(yq '.version' "$deploy_file") + if [ "$MULTIDEPLOY_VERSION" != "$deploy_file_version" ]; then + _err "As of $PROJECT_NAME $VER, the deploy file needs version $MULTIDEPLOY_VERSION! Your current deploy file is of version $deploy_file_version." + return 1 + fi + + # Check if config exists + if ! yq e ".configs[] | select(.name == \"$deploy_config\")" "$deploy_file" >/dev/null; then + _err "Config '$deploy_config' not found." + return 1 + fi + + # Extract all services from config + services=$(yq e ".configs[] | select(.name == \"$deploy_config\").services[]" "$deploy_file") + + if [ -z "$services" ]; then + _err "Config '$deploy_config' does not have any services to deploy to." + return 1 + fi + + # Check if extracted services exist in services list + for service in $services; do + if ! yq e ".services[] | select(.name == \"$service\")" "$deploy_file" >/dev/null; then + _err "Service '$service' not found." + return 1 fi - # Check if config exists - if ! yq e ".configs[] | select(.name == \"$deploy_config\")" "$deploy_file" >/dev/null; then - _err "Config '$deploy_config' not found." - return 1 + # Check if service has hook + if ! yq e ".services[] | select(.name == \"$service\").hook" "$deploy_file" >/dev/null; then + _err "Service '$service' does not have a hook." + return 1 fi - # Extract all services from config - services=$(yq e ".configs[] | select(.name == \"$deploy_config\").services[]" "$deploy_file") - - if [ -z "$services" ]; then - _err "Config '$deploy_config' does not have any services to deploy to." - return 1 + # Check if service has environment + if ! yq e ".services[] | select(.name == \"$service\").environment" "$deploy_file" >/dev/null; then + _err "Service '$service' does not an environment." + return 1 fi - - # Check if extracted services exist in services list - for service in $services; do - if ! yq e ".services[] | select(.name == \"$service\")" "$deploy_file" >/dev/null; then - _err "Service '$service' not found." - return 1 - fi - - # Check if service has hook - if ! yq e ".services[] | select(.name == \"$service\").hook" "$deploy_file" >/dev/null; then - _err "Service '$service' does not have a hook." - return 1 - fi - - # Check if service has environment - if ! yq e ".services[] | select(.name == \"$service\").environment" "$deploy_file" >/dev/null; then - _err "Service '$service' does not an environment." - return 1 - fi - done + done } From f1d214ae96d3cb181bc773e7a75e710d36f655a7 Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Thu, 20 Feb 2025 23:02:56 +0100 Subject: [PATCH 03/17] refactored getting services --- deploy/multideploy.sh | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index 08e0aba6..2a83a19f 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -85,7 +85,7 @@ _check_deployfile() { fi # Extract all services from config - services=$(yq e ".configs[] | select(.name == \"$deploy_config\").services[]" "$deploy_file") + services=$(_get_services_list "$deploy_file" "$deploy_config") if [ -z "$services" ]; then _err "Config '$deploy_config' does not have any services to deploy to." @@ -112,3 +112,29 @@ _check_deployfile() { fi done } + +# deploy_filepath deploy_config +_get_services_list() { + deploy_file="$1" + deploy_config="$2" + + services=$(yq e ".configs[] | select(.name == \"$deploy_config\").services[]" "$deploy_file") + echo "$services" +} + +# deploy_filepath service_names +_get_full_services_list() { + deploy_file="$1" + shift + service_names="$*" + + full_services="" + for service in $service_names; do + full_service=$(yq e ".services[] | select(.name == \"$service\")" "$deploy_file") + full_services="$full_services +$full_service" + done + + echo "$full_services" +} + From 18575b1eb97cba516ae2356630e81789f85eb634 Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Fri, 21 Feb 2025 10:49:08 +0100 Subject: [PATCH 04/17] fixed formatting and private var names --- deploy/multideploy.sh | 68 +++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index 2a83a19f..245c95a6 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -29,7 +29,7 @@ multideploy_deploy() { fi _debug2 "DOMAIN_DIR" "$DOMAIN_DIR" - _preprocess_deployfile "$DOMAIN_DIR/$MULTIDEPLOY_FILENAME" + _preprocess_deployfile "$DOMAIN_DIR/$MULTIDEPLOY_FILENAME" || return 1 MULTIDEPLOY_CONFIG="${MULTIDEPLOY_CONFIG:-$(_getdeployconf MULTIDEPLOY_CONFIG)}" if [ -z "$MULTIDEPLOY_CONFIG" ]; then @@ -47,7 +47,7 @@ multideploy_deploy() { # deploy_filepath _preprocess_deployfile() { - deploy_file="$1" + _deploy_file="$1" # Check if yq is installed if ! command -v yq >/dev/null 2>&1; then @@ -56,9 +56,9 @@ _preprocess_deployfile() { fi # Check if deploy file exists and create a default template if not - if [ -f "$deploy_file" ]; then + if [ -f "$_deploy_file" ]; then _debug3 "Deploy file found." - _check_deployfile "$deploy_file" "$MULTIDEPLOY_CONFIG" + _check_deployfile "$_deploy_file" "$MULTIDEPLOY_CONFIG" else # TODO: Replace URL with wiki link _err "Deploy file not found. Go to https://CHANGE_URL_TO_WIKI to see how to create one." @@ -66,48 +66,48 @@ _preprocess_deployfile() { fi } -# deploy_filepath deploy_config +# deploy_filepath _deploy_config _check_deployfile() { - deploy_file="$1" - deploy_config="$3" + _deploy_file="$1" + _deploy_config="$3" # Check version - deploy_file_version=$(yq '.version' "$deploy_file") - if [ "$MULTIDEPLOY_VERSION" != "$deploy_file_version" ]; then - _err "As of $PROJECT_NAME $VER, the deploy file needs version $MULTIDEPLOY_VERSION! Your current deploy file is of version $deploy_file_version." + _deploy_file_version=$(yq '.version' "$_deploy_file") + if [ "$MULTIDEPLOY_VERSION" != "$_deploy_file_version" ]; then + _err "As of $PROJECT_NAME $VER, the deploy file needs version $MULTIDEPLOY_VERSION! Your current deploy file is of version $_deploy_file_version." return 1 fi # Check if config exists - if ! yq e ".configs[] | select(.name == \"$deploy_config\")" "$deploy_file" >/dev/null; then - _err "Config '$deploy_config' not found." + if ! yq e ".configs[] | select(.name == \"$_deploy_config\")" "$_deploy_file" >/dev/null; then + _err "Config '$_deploy_config' not found." return 1 fi # Extract all services from config - services=$(_get_services_list "$deploy_file" "$deploy_config") + _services=$(_get_services_list "$_deploy_file" "$_deploy_config") - if [ -z "$services" ]; then - _err "Config '$deploy_config' does not have any services to deploy to." + if [ -z "$_services" ]; then + _err "Config '$_deploy_config' does not have any services to deploy to." return 1 fi # Check if extracted services exist in services list - for service in $services; do - if ! yq e ".services[] | select(.name == \"$service\")" "$deploy_file" >/dev/null; then - _err "Service '$service' not found." + for _service in $_services; do + if ! yq e ".services[] | select(.name == \"$_service\")" "$_deploy_file" >/dev/null; then + _err "Service '$_service' not found." return 1 fi # Check if service has hook - if ! yq e ".services[] | select(.name == \"$service\").hook" "$deploy_file" >/dev/null; then - _err "Service '$service' does not have a hook." + if ! yq e ".services[] | select(.name == \"$_service\").hook" "$_deploy_file" >/dev/null; then + _err "Service '$_service' does not have a hook." return 1 fi # Check if service has environment - if ! yq e ".services[] | select(.name == \"$service\").environment" "$deploy_file" >/dev/null; then - _err "Service '$service' does not an environment." + if ! yq e ".services[] | select(.name == \"$_service\").environment" "$_deploy_file" >/dev/null; then + _err "Service '$_service' does not an environment." return 1 fi done @@ -115,26 +115,26 @@ _check_deployfile() { # deploy_filepath deploy_config _get_services_list() { - deploy_file="$1" - deploy_config="$2" + _deploy_file="$1" + _deploy_config="$2" - services=$(yq e ".configs[] | select(.name == \"$deploy_config\").services[]" "$deploy_file") - echo "$services" + _services=$(yq e ".configs[] | select(.name == \"$_deploy_config\").services[]" "$_deploy_file") + echo "$_services" } # deploy_filepath service_names _get_full_services_list() { - deploy_file="$1" + _deploy_file="$1" shift - service_names="$*" + _service_names="$*" - full_services="" - for service in $service_names; do - full_service=$(yq e ".services[] | select(.name == \"$service\")" "$deploy_file") - full_services="$full_services -$full_service" + _full_services="" + for _service in $_service_names; do + _full_service=$(yq e ".services[] | select(.name == \"$_service\")" "$_deploy_file") + _full_services="$_full_services +$_full_service" done - echo "$full_services" + echo "$_full_services" } From a6060f90158a413bf572e86a0b6f90235852ca33 Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Fri, 21 Feb 2025 10:50:11 +0100 Subject: [PATCH 05/17] implemented handling envs --- deploy/multideploy.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index 245c95a6..d1642538 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -138,3 +138,25 @@ $_full_service" echo "$_full_services" } +# env_list +_export_envs() { + _env_list="$1" + + for _env in $_env_list; do + _key=$(echo "$_env" | cut -d '=' -f1) + _value=$(echo "$_env" | cut -d '=' -f2-) + _savedomainconf "$_key" "$_value" + _secure_debug3 "Saved $_key" "$_value" + done +} + +_clear_envs() { + _env_list="$1" + + for _env in $_env_list; do + _key=$(echo "$_env" | cut -d '=' -f1) + _debug3 "Deleting key" "$_key" + _cleardomainconf "SAVED_$_key" + unset "$_key" + done +} From 4fbade3d05461c4b1d43037db271dc0843567fde Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Fri, 21 Feb 2025 10:50:35 +0100 Subject: [PATCH 06/17] implemented deploying to services --- deploy/multideploy.sh | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index d1642538..caca02e2 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -40,7 +40,16 @@ multideploy_deploy() { _debug2 "MULTIDEPLOY_CONFIG" "$MULTIDEPLOY_CONFIG" fi - # TODO: Deploy to services + # Deploy to services + _services=$(_get_services_list "$DOMAIN_DIR/$MULTIDEPLOY_FILENAME" "$MULTIDEPLOY_CONFIG") + _full_services=$(_get_full_services_list "$DOMAIN_DIR/$MULTIDEPLOY_FILENAME" "$_services") + _deploy_services "$DOMAIN_DIR/$MULTIDEPLOY_FILENAME" "$_full_services" + + # Save deployhook for renewals + _debug2 "Setting Le_DeployHook" + _savedomainconf "Le_DeployHook" "multideploy" + + return 0 } #################### Private functions below ##################### @@ -160,3 +169,34 @@ _clear_envs() { unset "$_key" done } + +# deploy_filepath services_array +_deploy_services() { + _deploy_file="$1" + shift + _services="$*" + + for _service in $_services; do + _hook=$(yq e ".services[] | select(.name == \"$_service\").hook" "$_deploy_file") + _envs=$(yq e ".services[] | select(.name == \"$_service\").environment[]" "$_deploy_file") + _export_envs "$_envs" + _deploy_service "$_service" "$_hook" + _clear_envs "$_envs" + done +} + +_deploy_service() { + _name="$1" + _hook="$2" + + _debug2 "SERVICE" "$_name" + _debug2 "HOOK" "$_hook" + + _info "$(__green "Deploying") to '$_name' using '$_hook'" + if echo "$DOMAIN_PATH" | grep -q "$ECC_SUFFIX"; then + _debug2 "User wants to use ECC." + deploy "$_cdomain" "$_hook" "isEcc" + else + deploy "$_cdomain" "$_hook" + fi +} From f275f3c150c00fcd309f41d69a362609de11ccef Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Fri, 21 Feb 2025 10:50:50 +0100 Subject: [PATCH 07/17] added yq to dockerfile --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 3f400283..422001c4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,6 +13,7 @@ RUN apk --no-cache add -f \ tar \ libidn \ jq \ + yq \ cronie ENV LE_CONFIG_HOME=/acme.sh From 06e75de728a7722ed6834e03d1f87b7e173cea86 Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Fri, 21 Feb 2025 15:51:02 +0100 Subject: [PATCH 08/17] implemented checking for different kinds of deploy file --- deploy/multideploy.sh | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index caca02e2..9df2c423 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -5,7 +5,8 @@ ######## Public functions ##################### MULTIDEPLOY_VERSION="1.0" -MULTIDEPLOY_FILENAME="multideploy.yaml" +MULTIDEPLOY_FILENAME="multideploy.yml" +MULTIDEPLOY_FILENAME2="multideploy.yaml" # domain keyfile certfile cafile fullchain pfx multideploy_deploy() { @@ -56,18 +57,30 @@ multideploy_deploy() { # deploy_filepath _preprocess_deployfile() { - _deploy_file="$1" - # Check if yq is installed if ! command -v yq >/dev/null 2>&1; then _err "yq is not installed! Please install yq and try again." return 1 fi + _debug3 "yq is installed." + + # Check if deploy file exists + for file in "$@"; do + _debug3 "Checking file" "$DOMAIN_PATH/$file" + if [ -f "$DOMAIN_PATH/$file" ]; then + _debug3 "File found" + if [ -n "$found_file" ]; then + _err "Multiple deploy files found. Please keep only one deploy file." + return 1 + fi + found_file="$file" + else + _debug3 "File not found" + fi + done - # Check if deploy file exists and create a default template if not - if [ -f "$_deploy_file" ]; then - _debug3 "Deploy file found." - _check_deployfile "$_deploy_file" "$MULTIDEPLOY_CONFIG" + if [ -n "$found_file" ]; then + _check_deployfile "$DOMAIN_PATH/$found_file" "$MULTIDEPLOY_CONFIG" else # TODO: Replace URL with wiki link _err "Deploy file not found. Go to https://CHANGE_URL_TO_WIKI to see how to create one." From 6189aa5a355fd76d3fdfb0546e20b79b160fa36c Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Fri, 21 Feb 2025 15:52:02 +0100 Subject: [PATCH 09/17] added debug messages --- deploy/multideploy.sh | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index 9df2c423..3c243c04 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -30,8 +30,6 @@ multideploy_deploy() { fi _debug2 "DOMAIN_DIR" "$DOMAIN_DIR" - _preprocess_deployfile "$DOMAIN_DIR/$MULTIDEPLOY_FILENAME" || return 1 - MULTIDEPLOY_CONFIG="${MULTIDEPLOY_CONFIG:-$(_getdeployconf MULTIDEPLOY_CONFIG)}" if [ -z "$MULTIDEPLOY_CONFIG" ]; then MULTIDEPLOY_CONFIG="default" @@ -91,7 +89,10 @@ _preprocess_deployfile() { # deploy_filepath _deploy_config _check_deployfile() { _deploy_file="$1" - _deploy_config="$3" + _deploy_config="$2" + + _debug2 "Deploy file" "$_deploy_file" + _debug2 "Deploy config" "$_deploy_config" # Check version _deploy_file_version=$(yq '.version' "$_deploy_file") @@ -99,23 +100,29 @@ _check_deployfile() { _err "As of $PROJECT_NAME $VER, the deploy file needs version $MULTIDEPLOY_VERSION! Your current deploy file is of version $_deploy_file_version." return 1 fi + _debug2 "Deploy file version is compatible: $_deploy_file_version" # Check if config exists if ! yq e ".configs[] | select(.name == \"$_deploy_config\")" "$_deploy_file" >/dev/null; then _err "Config '$_deploy_config' not found." return 1 fi + _debug2 "Config found: $_deploy_config" # Extract all services from config _services=$(_get_services_list "$_deploy_file" "$_deploy_config") + _debug2 "Services" "$_services" if [ -z "$_services" ]; then _err "Config '$_deploy_config' does not have any services to deploy to." return 1 fi + _debug2 "Config has services." # Check if extracted services exist in services list for _service in $_services; do + _debug2 "Checking service" "$_service" + # Check if service exists if ! yq e ".services[] | select(.name == \"$_service\")" "$_deploy_file" >/dev/null; then _err "Service '$_service' not found." return 1 @@ -140,6 +147,10 @@ _get_services_list() { _deploy_file="$1" _deploy_config="$2" + _debug2 "Getting services list" + _debug3 "Deploy file" "$_deploy_file" + _debug3 "Deploy config" "$_deploy_config" + _services=$(yq e ".configs[] | select(.name == \"$_deploy_config\").services[]" "$_deploy_file") echo "$_services" } @@ -150,6 +161,9 @@ _get_full_services_list() { shift _service_names="$*" + _debug3 "Deploy file" "$_deploy_file" + _debug3 "Service names" "$_service_names" + _full_services="" for _service in $_service_names; do _full_service=$(yq e ".services[] | select(.name == \"$_service\")" "$_deploy_file") @@ -164,6 +178,8 @@ $_full_service" _export_envs() { _env_list="$1" + _secure_debug3 "Exporting envs" "$_env_list" + for _env in $_env_list; do _key=$(echo "$_env" | cut -d '=' -f1) _value=$(echo "$_env" | cut -d '=' -f2-) @@ -175,6 +191,8 @@ _export_envs() { _clear_envs() { _env_list="$1" + _secure_debug3 "Clearing envs" "$_env_list" + for _env in $_env_list; do _key=$(echo "$_env" | cut -d '=' -f1) _debug3 "Deleting key" "$_key" @@ -189,6 +207,9 @@ _deploy_services() { shift _services="$*" + _debug3 "Deploy file" "$_deploy_file" + _debug3 "Services" "$_services" + for _service in $_services; do _hook=$(yq e ".services[] | select(.name == \"$_service\").hook" "$_deploy_file") _envs=$(yq e ".services[] | select(.name == \"$_service\").environment[]" "$_deploy_file") From ccd9d9a79e7f61287771086318c0d92a2a89386b Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Fri, 21 Feb 2025 18:23:13 +0100 Subject: [PATCH 10/17] improved preprocessing and fixed bug with wrong param of services --- deploy/multideploy.sh | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index 3c243c04..7b4e1400 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -39,10 +39,13 @@ multideploy_deploy() { _debug2 "MULTIDEPLOY_CONFIG" "$MULTIDEPLOY_CONFIG" fi + OLDIFS=$IFS + file=$(_preprocess_deployfile "$MULTIDEPLOY_FILENAME" "$MULTIDEPLOY_FILENAME2") || return 1 + _debug3 "File" "$file" + # Deploy to services - _services=$(_get_services_list "$DOMAIN_DIR/$MULTIDEPLOY_FILENAME" "$MULTIDEPLOY_CONFIG") - _full_services=$(_get_full_services_list "$DOMAIN_DIR/$MULTIDEPLOY_FILENAME" "$_services") - _deploy_services "$DOMAIN_DIR/$MULTIDEPLOY_FILENAME" "$_full_services" + _services=$(_get_services_list "$file" "$MULTIDEPLOY_CONFIG") + _deploy_services "$file" "$_services" # Save deployhook for renewals _debug2 "Setting Le_DeployHook" @@ -84,6 +87,8 @@ _preprocess_deployfile() { _err "Deploy file not found. Go to https://CHANGE_URL_TO_WIKI to see how to create one." return 1 fi + + echo "$DOMAIN_PATH/$found_file" } # deploy_filepath _deploy_config @@ -155,25 +160,6 @@ _get_services_list() { echo "$_services" } -# deploy_filepath service_names -_get_full_services_list() { - _deploy_file="$1" - shift - _service_names="$*" - - _debug3 "Deploy file" "$_deploy_file" - _debug3 "Service names" "$_service_names" - - _full_services="" - for _service in $_service_names; do - _full_service=$(yq e ".services[] | select(.name == \"$_service\")" "$_deploy_file") - _full_services="$_full_services -$_full_service" - done - - echo "$_full_services" -} - # env_list _export_envs() { _env_list="$1" @@ -211,6 +197,7 @@ _deploy_services() { _debug3 "Services" "$_services" for _service in $_services; do + _debug2 "Service" "$_service" _hook=$(yq e ".services[] | select(.name == \"$_service\").hook" "$_deploy_file") _envs=$(yq e ".services[] | select(.name == \"$_service\").environment[]" "$_deploy_file") _export_envs "$_envs" From 8d77bef8282d268a7655805aa41414098b81a12c Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Fri, 21 Feb 2025 18:23:29 +0100 Subject: [PATCH 11/17] fixed IFS problems --- deploy/multideploy.sh | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index 7b4e1400..9e2fb1d2 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -66,6 +66,7 @@ _preprocess_deployfile() { _debug3 "yq is installed." # Check if deploy file exists + IFS=$(printf '\n') for file in "$@"; do _debug3 "Checking file" "$DOMAIN_PATH/$file" if [ -f "$DOMAIN_PATH/$file" ]; then @@ -79,6 +80,7 @@ _preprocess_deployfile() { _debug3 "File not found" fi done + IFS=$OLDIFS if [ -n "$found_file" ]; then _check_deployfile "$DOMAIN_PATH/$found_file" "$MULTIDEPLOY_CONFIG" @@ -124,6 +126,7 @@ _check_deployfile() { fi _debug2 "Config has services." + IFS=$(printf '\n') # Check if extracted services exist in services list for _service in $_services; do _debug2 "Checking service" "$_service" @@ -145,6 +148,7 @@ _check_deployfile() { return 1 fi done + IFS=$OLDIFS } # deploy_filepath deploy_config @@ -166,25 +170,27 @@ _export_envs() { _secure_debug3 "Exporting envs" "$_env_list" - for _env in $_env_list; do - _key=$(echo "$_env" | cut -d '=' -f1) - _value=$(echo "$_env" | cut -d '=' -f2-) + IFS=$(printf '\n') + echo "$_env_list" | yq e -r 'to_entries | .[] | .key + "=" + .value' | while IFS='=' read -r _key _value; do _savedomainconf "$_key" "$_value" _secure_debug3 "Saved $_key" "$_value" done + IFS=$OLDIFS } _clear_envs() { _env_list="$1" _secure_debug3 "Clearing envs" "$_env_list" + env_pairs=$(echo "$_env_list" | yq e -r 'to_entries | .[] | .key + "=" + .value') - for _env in $_env_list; do - _key=$(echo "$_env" | cut -d '=' -f1) + IFS=$(printf '\n') + echo "$env_pairs" | while IFS='=' read -r _key _value; do _debug3 "Deleting key" "$_key" _cleardomainconf "SAVED_$_key" unset "$_key" done + IFS="$OLDIFS" } # deploy_filepath services_array @@ -196,14 +202,17 @@ _deploy_services() { _debug3 "Deploy file" "$_deploy_file" _debug3 "Services" "$_services" + IFS=$(printf '\n') for _service in $_services; do _debug2 "Service" "$_service" _hook=$(yq e ".services[] | select(.name == \"$_service\").hook" "$_deploy_file") _envs=$(yq e ".services[] | select(.name == \"$_service\").environment[]" "$_deploy_file") + _export_envs "$_envs" _deploy_service "$_service" "$_hook" _clear_envs "$_envs" done + IFS=$OLDIFS } _deploy_service() { From a9c2435c88488f6c1360c17649abfe610f9f358d Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Fri, 21 Feb 2025 18:31:24 +0100 Subject: [PATCH 12/17] added docs --- deploy/multideploy.sh | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index 9e2fb1d2..129bb38f 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -151,7 +151,13 @@ _check_deployfile() { IFS=$OLDIFS } -# deploy_filepath deploy_config +# Description: +# This function retrieves a list of services from the deploy configuration file. +# Arguments: +# $1 - The path to the deploy configuration file. +# $2 - The name of the deploy configuration to use. +# Usage: +# _get_services_list "" "" _get_services_list() { _deploy_file="$1" _deploy_config="$2" @@ -164,7 +170,12 @@ _get_services_list() { echo "$_services" } -# env_list +# Description: This function takes a list of environment variables in YAML format, +# parses them, and exports each key-value pair as environment variables. +# Arguments: +# $1 - A string containing the list of environment variables in YAML format. +# Usage: +# _export_envs "$env_list" _export_envs() { _env_list="$1" @@ -178,6 +189,13 @@ _export_envs() { IFS=$OLDIFS } +# Description: +# This function takes a YAML formatted string of environment variables, parses it, +# and clears each environment variable. It logs the process of clearing each variable. +# Arguments: +# $1 - A YAML formatted string containing environment variable key-value pairs. +# Usage: +# _clear_envs "" _clear_envs() { _env_list="$1" @@ -188,7 +206,7 @@ _clear_envs() { echo "$env_pairs" | while IFS='=' read -r _key _value; do _debug3 "Deleting key" "$_key" _cleardomainconf "SAVED_$_key" - unset "$_key" + unset -v "$_key" done IFS="$OLDIFS" } From 7a35d6838dd5b92589fced4ddda5e24850aa7426 Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Fri, 21 Feb 2025 18:44:46 +0100 Subject: [PATCH 13/17] added docs and enhanced log messages --- deploy/multideploy.sh | 57 +++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index 129bb38f..81754f1c 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -2,13 +2,21 @@ # MULTIDEPLOY_CONFIG="default" -######## Public functions ##################### - MULTIDEPLOY_VERSION="1.0" MULTIDEPLOY_FILENAME="multideploy.yml" MULTIDEPLOY_FILENAME2="multideploy.yaml" -# domain keyfile certfile cafile fullchain pfx +# Description: This function handles the deployment of certificates to multiple services. +# It processes the provided certificate files and deploys them according to the +# configuration specified in the MULTIDEPLOY_CONFIG. +# +# Parameters: +# _cdomain - The domain name for which the certificate is issued. +# _ckey - The private key file for the certificate. +# _ccert - The certificate file. +# _cca - The CA (Certificate Authority) file. +# _cfullchain - The full chain certificate file. +# _cpfx - The PFX (Personal Information Exchange) file. multideploy_deploy() { _cdomain="$1" _ckey="$2" @@ -40,7 +48,10 @@ multideploy_deploy() { fi OLDIFS=$IFS - file=$(_preprocess_deployfile "$MULTIDEPLOY_FILENAME" "$MULTIDEPLOY_FILENAME2") || return 1 + if ! file=$(_preprocess_deployfile "$MULTIDEPLOY_FILENAME" "$MULTIDEPLOY_FILENAME2"); then + _err "Failed to preprocess deploy file." + return 1 + fi _debug3 "File" "$file" # Deploy to services @@ -54,9 +65,13 @@ multideploy_deploy() { return 0 } -#################### Private functions below ##################### - -# deploy_filepath +# Description: +# This function preprocesses the deploy file by checking if 'yq' is installed, +# verifying the existence of the deploy file, and ensuring only one deploy file is present. +# Arguments: +# $@ - Posible deploy file names. +# Usage: +# _preprocess_deployfile "" "" _preprocess_deployfile() { # Check if yq is installed if ! command -v yq >/dev/null 2>&1; then @@ -93,7 +108,13 @@ _preprocess_deployfile() { echo "$DOMAIN_PATH/$found_file" } -# deploy_filepath _deploy_config +# Description: +# This function checks the deploy file for version compatibility and the existence of the specified configuration and services. +# Arguments: +# $1 - The path to the deploy configuration file. +# $2 - The name of the deploy configuration to use. +# Usage: +# _check_deployfile "" "" _check_deployfile() { _deploy_file="$1" _deploy_config="$2" @@ -144,7 +165,7 @@ _check_deployfile() { # Check if service has environment if ! yq e ".services[] | select(.name == \"$_service\").environment" "$_deploy_file" >/dev/null; then - _err "Service '$_service' does not an environment." + _err "Service '$_service' does not have an environment." return 1 fi done @@ -211,7 +232,13 @@ _clear_envs() { IFS="$OLDIFS" } -# deploy_filepath services_array +# Description: +# This function deploys services listed in the deploy configuration file. +# Arguments: +# $1 - The path to the deploy configuration file. +# $2 - The list of services to deploy. +# Usage: +# _deploy_services "" "" _deploy_services() { _deploy_file="$1" shift @@ -220,8 +247,7 @@ _deploy_services() { _debug3 "Deploy file" "$_deploy_file" _debug3 "Services" "$_services" - IFS=$(printf '\n') - for _service in $_services; do + printf '%s\n' "$_services" | while IFS= read -r _service; do _debug2 "Service" "$_service" _hook=$(yq e ".services[] | select(.name == \"$_service\").hook" "$_deploy_file") _envs=$(yq e ".services[] | select(.name == \"$_service\").environment[]" "$_deploy_file") @@ -230,9 +256,14 @@ _deploy_services() { _deploy_service "$_service" "$_hook" _clear_envs "$_envs" done - IFS=$OLDIFS } +# Description: Deploys a service using the specified hook. +# Arguments: +# $1 - The name of the service to deploy. +# $2 - The hook to use for deployment. +# Usage: +# _deploy_service _deploy_service() { _name="$1" _hook="$2" From b6a6e67d045f4d39891b81b1de3c14ddda7fd43f Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Fri, 21 Feb 2025 19:02:55 +0100 Subject: [PATCH 14/17] added header doc --- deploy/multideploy.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index 81754f1c..bea4622b 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -1,6 +1,25 @@ #!/usr/bin/env sh -# MULTIDEPLOY_CONFIG="default" +################################################################################ +# ACME.sh 3rd party deploy plugin for multiple (same) services +################################################################################ +# Authors: tomo2403 (creator), https://github.com/tomo2403 +# Updated: 2024-07-03 +# Issues: https://github.com/acmesh-official/acme.sh/issues/XXXXX +################################################################################ +# Usage (shown values are the examples): +# 1. Set optional environment variables +# - export MULTIDEPLOY_CONFIG="default" - "default" will be automatically used if not set" +# +# 2. Run command: +# acme.sh --deploy --deploy-hook multideploy -d example.com +################################################################################ +# Dependencies: +# - yq +################################################################################ +# Return value: +# 0 means success, otherwise error. +################################################################################ MULTIDEPLOY_VERSION="1.0" MULTIDEPLOY_FILENAME="multideploy.yml" From 98aaff68f44128cb7539dc5d7f95244fd1fefcf5 Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Fri, 21 Feb 2025 19:15:42 +0100 Subject: [PATCH 15/17] allowed using varaibles in deploy file --- deploy/multideploy.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index bea4622b..58df0482 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -223,6 +223,7 @@ _export_envs() { IFS=$(printf '\n') echo "$_env_list" | yq e -r 'to_entries | .[] | .key + "=" + .value' | while IFS='=' read -r _key _value; do + _value=$(eval echo "$_value") _savedomainconf "$_key" "$_value" _secure_debug3 "Saved $_key" "$_value" done From f26d40404a2e5b97234434a9bec3f36ce27d2a98 Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Fri, 21 Feb 2025 19:26:56 +0100 Subject: [PATCH 16/17] fixed missing wiki link --- deploy/multideploy.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index 58df0482..9e3f4e17 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -119,8 +119,7 @@ _preprocess_deployfile() { if [ -n "$found_file" ]; then _check_deployfile "$DOMAIN_PATH/$found_file" "$MULTIDEPLOY_CONFIG" else - # TODO: Replace URL with wiki link - _err "Deploy file not found. Go to https://CHANGE_URL_TO_WIKI to see how to create one." + _err "Deploy file not found. Go to https://github.com/acmesh-official/acme.sh/wiki/deployhooks#36-deploying-to-multiple-services-with-the-same-hooks to see how to create one." return 1 fi From 69858fbd5f7590f770434869c51e612776b244df Mon Sep 17 00:00:00 2001 From: tomo <49612544+tomo2403@users.noreply.github.com> Date: Sat, 1 Mar 2025 13:26:53 +0100 Subject: [PATCH 17/17] Update links in multideploy.sh --- deploy/multideploy.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/multideploy.sh b/deploy/multideploy.sh index 9e3f4e17..b002f068 100644 --- a/deploy/multideploy.sh +++ b/deploy/multideploy.sh @@ -4,8 +4,8 @@ # ACME.sh 3rd party deploy plugin for multiple (same) services ################################################################################ # Authors: tomo2403 (creator), https://github.com/tomo2403 -# Updated: 2024-07-03 -# Issues: https://github.com/acmesh-official/acme.sh/issues/XXXXX +# Updated: 2025-03-01 +# Issues: https://github.com/acmesh-official/acme.sh/issues and mention @tomo2403 ################################################################################ # Usage (shown values are the examples): # 1. Set optional environment variables