From b70efc6906cc15d5324b4c5490d844c64f1254a7 Mon Sep 17 00:00:00 2001 From: Saswat Padhi Date: Tue, 1 Oct 2024 18:36:09 -0700 Subject: [PATCH] fix options leaking --- .gitignore | 2 +- _scripts/generate-and-verify.sh | 4 +- _scripts/test_comp.sh | 135 +++++++++++++++++++------------- comp | 18 +++-- 4 files changed, 96 insertions(+), 63 deletions(-) diff --git a/.gitignore b/.gitignore index d6225a5..05d014b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,4 @@ */data */generated -test__*__ \ No newline at end of file +test__* \ No newline at end of file diff --git a/_scripts/generate-and-verify.sh b/_scripts/generate-and-verify.sh index 011c886..bcddc1d 100755 --- a/_scripts/generate-and-verify.sh +++ b/_scripts/generate-and-verify.sh @@ -12,7 +12,7 @@ TARGET_FILE="$2" ENV_VARS="$(cut -d= -f1 .env | awk '{print "$" $0}')" -echo -n "[*] Generating '$TARGET_FILE': " +echo -n "[*] $TARGET_FILE: " if [ -e "$TARGET_FILE" ] && [ ! -f "$TARGET_FILE" ] ; then echo "CANNOT OVERWRITE!" @@ -30,7 +30,7 @@ SRC_VARS=$(envsubst -v "$(cat "$SOURCE_FILE")" | paste -sd '|') if grep -qE "$SRC_VARS" "$TARGET_FILE" ; then LINE="$(grep -E "$SRC_VARS" "$TARGET_FILE")" LEFTOVER_VAR="$(envsubst -v "$LINE" | paste -sd '|')" - echo "\`$LEFTOVER_VAR\` NOT DEFINED!" + echo "${_fg_red_}${_bold_}\`$LEFTOVER_VAR\` NOT DEFINED!${_normal_}" rm "$TARGET_FILE" exit 1 fi diff --git a/_scripts/test_comp.sh b/_scripts/test_comp.sh index cb18874..14d366a 100755 --- a/_scripts/test_comp.sh +++ b/_scripts/test_comp.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -#shellcheck disable=SC2086,SC2154 source=/dev/null +#shellcheck disable=SC2059,SC2086,SC2154 source=/dev/null set -Eumo pipefail @@ -18,8 +18,11 @@ TEST_COMP_TMP_PATH=/tmp/__test_comp_intermediate_storage_dir__ rm -rf "$TEST_COMP_TMP_PATH" mkdir -p "$TEST_COMP_TMP_PATH" +SKIPPING_THIS= + # SETUP function SETUP () { + [ -z "$SKIPPING_THIS" ] || return echo ; echo "${_fg_white_}${_bg_black_}${_bold_} T ${_normal_} Test $1: " local io_path_prefix="$TEST_COMP_TMP_PATH/$1" @@ -44,6 +47,7 @@ function SETUP () { # CHECK function CHECK { + [ -z "$SKIPPING_THIS" ] || return [ -z "$DEBUG" ] || echo "CHECK: $1" if eval -- $1 ; then @@ -55,19 +59,27 @@ function CHECK { fi } +# _WAIT function _WAIT () { + [ -z "$SKIPPING_THIS" ] || return echo ; echo "${_fg_white_}${_bg_black_}${_bold_} W ${_normal_} Waiting ${_fg_magenta_}$1${_normal_} for $2" sleep "$1" } +COMP_COUNTER=1 +# _INIT function _INIT () { + [ -z "$SKIPPING_THIS" ] || return + local TARGET_COMP_VAR="TARGET_COMP_$COMP_COUNTER" + local TARGET_COMP_DISPLAY_VAR="TARGET_COMP_${COMP_COUNTER}_DISPLAY" echo ; echo -n "${_fg_white_}${_bg_black_}${_bold_} I ${_normal_} Initializing ${_fg_magenta_}$1${_normal_} -> " - TARGET_COMP="test__$1__" - rm -rf "$TARGET_COMP" - cp -r "$1" "$TARGET_COMP" - TARGET_COMP_DISPLAY="${_fg_blue_}$TARGET_COMP${_normal_}" - ( cd "$TARGET_COMP" && rm -rf .env data generated ./*override* ) - echo "$TARGET_COMP_DISPLAY" + printf -v "$TARGET_COMP_VAR" "test__${COMP_COUNTER}__$1__" + rm -rf "${!TARGET_COMP_VAR}" + cp -r "$1" "${!TARGET_COMP_VAR}" + printf -v "$TARGET_COMP_DISPLAY_VAR" "${_fg_blue_}${!TARGET_COMP_VAR}${_normal_}" + ( cd "${!TARGET_COMP_VAR}" && rm -rf .env data generated ./*override* ) + echo "${!TARGET_COMP_DISPLAY_VAR}" + (( COMP_COUNTER++ )) } function FINAL () { @@ -83,7 +95,7 @@ function FINAL () { SETUP "invocation without args" \ "" \ "" -CHECK $'grep -sq "\[,,\.\.\.\] \[flags\] \[ \.\.\.\]" "$COMP_ERR_PATH"' \ +CHECK $'grep -qs "\[,,\.\.\.\] \[flags\] \[ \.\.\.\]" "$COMP_ERR_PATH"' \ "Usage information on stderr" CHECK $'[ $COMP_EXIT_CODE -eq $EXIT_CODE_USAGE_ERROR ]' \ "EXIT_CODE_USAGE_ERROR" @@ -91,86 +103,86 @@ CHECK $'[ $COMP_EXIT_CODE -eq $EXIT_CODE_USAGE_ERROR ]' \ SETUP "status of non-existent composition" \ "status unknown_comp" \ "" -CHECK $'grep -sq "Executing status on unknown_comp" "$COMP_OUT_PATH"' \ - "Info message at beginning of execution" -CHECK $'grep -sq "is not a base directory" "$COMP_ERR_PATH"' \ - "Helpful error message on stderr" +CHECK $'grep -qs "Executing status on unknown_comp" "$COMP_OUT_PATH"' \ + "Info at beginning of execution" +CHECK $'grep -qs "is not a base directory" "$COMP_ERR_PATH"' \ + "Helpful message on stderr" CHECK $'[ $COMP_EXIT_CODE -eq $EXIT_CODE_COMPOSITION_NOT_FOUND ]'\ "EXIT_CODE_COMPOSITION_NOT_FOUND" _INIT tang -SETUP "stopping $TARGET_COMP_DISPLAY while its not running" \ - "down $TARGET_COMP" \ +SETUP "stopping $TARGET_COMP_1_DISPLAY while its not running" \ + "down $TARGET_COMP_1" \ "" -CHECK $'grep -sq "Executing down on $TARGET_COMP" "$COMP_OUT_PATH"' \ - "Info message at beginning of execution" +CHECK $'grep -qs "Executing down on $TARGET_COMP_1" "$COMP_OUT_PATH"' \ + "Info at beginning of execution" CHECK $'[ $COMP_EXIT_CODE -eq 0 ]' \ "EXIT_CODE = 0" \ exit_on_failure -SETUP "that status reports $TARGET_COMP_DISPLAY is unhealthy" \ - "status -P $TARGET_COMP" \ +SETUP "that status reports $TARGET_COMP_1_DISPLAY is unhealthy" \ + "status -P $TARGET_COMP_1" \ "" -CHECK $'grep -sq "Executing status on $TARGET_COMP" "$COMP_OUT_PATH"' \ - "Info message at beginning of execution" -CHECK $'grep -sq "Unhealthy service:" "$COMP_ERR_PATH"' \ - "Error message about unhealthy service on stderr" +CHECK $'grep -qs "Executing status on $TARGET_COMP_1" "$COMP_OUT_PATH"' \ + "Info at beginning of execution" +CHECK $'grep -qs "Unhealthy service:" "$COMP_ERR_PATH"' \ + "Error about unhealthy service on stderr" CHECK $'[ $COMP_EXIT_CODE -eq $EXIT_CODE_SIMPLE_VERB_FAILURE ]' \ "EXIT_CODE_SIMPLE_VERB_FAILURE" \ exit_on_failure -SETUP "starting $TARGET_COMP_DISPLAY without prerequisites" \ - "up -P $TARGET_COMP" \ - "n" -CHECK $'grep -sq "Executing up on $TARGET_COMP" "$COMP_OUT_PATH"' \ - "Info message at beginning of execution" +SETUP "starting $TARGET_COMP_1_DISPLAY without prerequisites" \ + "up -P $TARGET_COMP_1" \ + "" +CHECK $'grep -qs "Executing up on $TARGET_COMP_1" "$COMP_OUT_PATH"' \ + "Info at beginning of execution" CHECK $'[ $COMP_EXIT_CODE -eq 0 ]' \ "EXIT_CODE = 0" \ exit_on_failure -SETUP "cleaning $TARGET_COMP_DISPLAY before stopping" \ - "clean $TARGET_COMP" \ +SETUP "cleaning $TARGET_COMP_1_DISPLAY before stopping" \ + "clean $TARGET_COMP_1" \ "" -CHECK $'grep -sq "Executing clean on $TARGET_COMP" "$COMP_OUT_PATH"' \ - "Info message at beginning of execution" -CHECK $'grep -sq "Cannot clean while $TARGET_COMP is running" "$COMP_ERR_PATH"' \ - "Error message about running composition on stderr" \ +CHECK $'grep -qs "Executing clean on $TARGET_COMP_1" "$COMP_OUT_PATH"' \ + "Info at beginning of execution" +CHECK $'grep -qs "Cannot clean while $TARGET_COMP_1 is running" "$COMP_ERR_PATH"' \ + "Error about running composition on stderr" \ exit_on_failure CHECK $'[ $COMP_EXIT_CODE -eq $EXIT_CODE_SIMPLE_VERB_FAILURE ]' \ "EXIT_CODE_SIMPLE_VERB_FAILURE" \ exit_on_failure -_WAIT 30s "$TARGET_COMP_DISPLAY to start up and emit health status" +_WAIT 30s "$TARGET_COMP_1_DISPLAY to start up and emit health status" -SETUP "that status reports $TARGET_COMP_DISPLAY is healthy" \ - "status -P $TARGET_COMP" \ +SETUP "that status reports $TARGET_COMP_1_DISPLAY is healthy" \ + "status -P $TARGET_COMP_1" \ "" -CHECK $'grep -sq "Executing status on $TARGET_COMP" "$COMP_OUT_PATH"' \ - "Info message at beginning of execution" -CHECK $'grep -sq "$TARGET_COMP is healthy" "$COMP_OUT_PATH"' \ - "Info message about healthy composition" +CHECK $'grep -qs "Executing status on $TARGET_COMP_1" "$COMP_OUT_PATH"' \ + "Info at beginning of execution" +CHECK $'grep -qs "$TARGET_COMP_1 is healthy" "$COMP_OUT_PATH"' \ + "Info about healthy composition" CHECK $'[ $COMP_EXIT_CODE -eq 0 ]' \ "EXIT_CODE = 0" \ exit_on_failure -SETUP "stopping $TARGET_COMP_DISPLAY while its running" \ - "down $TARGET_COMP" \ +SETUP "stopping $TARGET_COMP_1_DISPLAY while its running" \ + "down $TARGET_COMP_1" \ "" -CHECK $'grep -sq "Executing down on $TARGET_COMP" "$COMP_OUT_PATH"' \ - "Info message at beginning of execution" +CHECK $'grep -qs "Executing down on $TARGET_COMP_1" "$COMP_OUT_PATH"' \ + "Info at beginning of execution" CHECK $'[ $COMP_EXIT_CODE -eq 0 ]' \ "EXIT_CODE = 0" \ exit_on_failure SETUP "cleaning, but deny deleting data" \ - "clean $TARGET_COMP" \ + "clean $TARGET_COMP_1" \ "n" -CHECK $'grep -sq "Executing clean on $TARGET_COMP" "$COMP_OUT_PATH"' \ - "Info message at beginning of execution" -CHECK $'grep -sq "Remove \'$TARGET_COMP/data\' (y/N)?" "$COMP_OUT_PATH"' \ +CHECK $'grep -qs "Executing clean on $TARGET_COMP_1" "$COMP_OUT_PATH"' \ + "Info at beginning of execution" +CHECK $'grep -qs "Remove \'$TARGET_COMP_1/data\' (y/N)?" "$COMP_OUT_PATH"' \ "Confirmation prompt before deletion" -CHECK $'[ -d $TARGET_COMP/data ]' \ +CHECK $'[ -d $TARGET_COMP_1/data ]' \ "Data is not deleted" \ exit_on_failure CHECK $'[ $COMP_EXIT_CODE -eq 0 ]' \ @@ -178,17 +190,32 @@ CHECK $'[ $COMP_EXIT_CODE -eq 0 ]' \ exit_on_failure SETUP "cleaning, and allow deleting data" \ - "clean $TARGET_COMP" \ + "clean $TARGET_COMP_1" \ "y" -CHECK $'grep -sq "Executing clean on $TARGET_COMP" "$COMP_OUT_PATH"' \ - "Info message at beginning of execution" -CHECK $'grep -sq "Remove \'$TARGET_COMP/data\' (y/N)?" "$COMP_OUT_PATH"' \ +CHECK $'grep -qs "Executing clean on $TARGET_COMP_1" "$COMP_OUT_PATH"' \ + "Info at beginning of execution" +CHECK $'grep -qs "Remove \'$TARGET_COMP_1/data\' (y/N)?" "$COMP_OUT_PATH"' \ "Confirmation prompt before deletion" -CHECK $'! [ -d $TARGET_COMP/data ]' \ +CHECK $'! [ -d $TARGET_COMP_1/data ]' \ "Data is deleted" \ exit_on_failure CHECK $'[ $COMP_EXIT_CODE -eq 0 ]' \ "EXIT_CODE = 0" \ exit_on_failure +_INIT tiny_httpd + +echo "DEVICES=no" > $TARGET_COMP_1/options.override.conf + +SETUP "starting $TARGET_COMP_1_DISPLAY & $TARGET_COMP_2_DISPLAY with different options" \ + "up -P $TARGET_COMP_1 $TARGET_COMP_2" \ + "" +CHECK $'grep -lPqsz "Executing up on $TARGET_COMP_1.*\\n.*Disabled options: DEVICES \(conf\)" "$COMP_OUT_PATH"' \ + "Info with disabled options at beginning of $TARGET_COMP_1_DISPLAY execution" +CHECK $'grep -lPqsvz "Executing up on $TARGET_COMP_2.*\\n.*Disabled options: DEVICES \(conf\)" "$COMP_OUT_PATH"' \ + "Info without disabled options at beginning of $TARGET_COMP_2_DISPLAY execution" +CHECK $'[ $COMP_EXIT_CODE -eq 0 ]' \ + "EXIT_CODE = 0" \ + exit_on_failure + FINAL diff --git a/comp b/comp index 0c1ca46..3aa9c48 100755 --- a/comp +++ b/comp @@ -71,7 +71,7 @@ __create_external_networks () { done done - for ext_net in $(printf "%s\n" "${EXTERNAL_NETWORKS[@]}" | sort -u) ; do + for ext_net in $( printf "%s\n" "${EXTERNAL_NETWORKS[@]}" | sort -u ) ; do "$SCRIPTS_DIR/create-network.sh" "$ext_net" || return 1 done } @@ -91,7 +91,7 @@ __do_prereqs () { else __CALL_SELF__ "$verb" -F "$prereq_comp_dir" || return 1 fi - done < <(cat "$PREREQS_FILENAME" "$PREREQS_OVERRIDE_FILENAME" 2>/dev/null) + done < <( cat "$PREREQS_FILENAME" "$PREREQS_OVERRIDE_FILENAME" 2>/dev/null ) } __error () { @@ -125,7 +125,7 @@ __gen_env () { __gen_templates () { find ./extra -name '*.template.*' 2>/dev/null | grep -q . || return 0 - echo "[~] Verifying templated files ..." + echo "[~] Generating templated files ..." while IFS= read -r template_file ; do local generated_file="./generated${template_file#./extra}" @@ -233,9 +233,11 @@ __will_invoke_compose () { do_validate () { [ "${1:-}" = "shallow" ] || __do_prereqs validate || return 1 - if echo "$comp" | grep -q '\.'; then - __error "$DOCKER_COMPOSE_CMD will use '${comp//.}' as project name." - return 1 + if echo "$comp" | grep -q '\.' ; then + __error "$DOCKER_COMPOSE_CMD will use '${comp//.}' as project name." ; return 1 + fi + if [[ "$comp" =~ ^_ ]] ; then + __error "$DOCKER_COMPOSE_CMD will use '${comp:1}' as project name." ; return 1 fi printf '[~] Validating service:' @@ -489,6 +491,8 @@ fi # # # # # # # # # # # # # # # # # # # MAIN FUNCTION # # # # # # # # # # # # # # # # # # # COMPOSITIONS=( "$@" ) +OPTIONS_FROM_ARGS=( "$OPTION_DEVICES" "$OPTION_HOOKS" "$OPTION_LABELS" "$OPTION_LOGGING" "$OPTION_PORTS" ) + perform () { local SIMPLE_VERB="$1" for comp in "${COMPOSITIONS[@]}" ; do @@ -496,6 +500,7 @@ perform () { echo -ne "\n${_fg_white_}${_bg_black_}${_bold_} ${SIMPLE_VERB:0:1} ${_normal_} Executing ${_bold_}$SIMPLE_VERB${_normal_} on " [ -z "$COMP_INTERNAL_CALL" ] || printf 'pre-req ' echo "${_bold_}$comp${_normal_} ... " + if ! { [ "$comp" = "$(basename "$comp")" ] && [ -d "$SELF_DIR/$comp" ]; } ; then __error "${_bold_}$comp${_normal_} is not a base directory at '$SELF_DIR'!" __maybe_fail_fast $EXIT_CODE_COMPOSITION_NOT_FOUND || continue @@ -511,6 +516,7 @@ perform () { COMPOSE_FILES+=( "docker-compose.override.yml") fi + read -r OPTION_DEVICES OPTION_HOOKS OPTION_LABELS OPTION_LOGGING OPTION_PORTS <<<"${OPTIONS_FROM_ARGS[*]}" local opt_error=0 opt_line_head='[o] Disabled options' for opt in DEVICES HOOKS LABELS LOGGING PORTS ; do