diff --git a/docker/base/kolla-common.sh b/docker/base/kolla-common.sh index 75058e521e..bc932a31d5 100644 --- a/docker/base/kolla-common.sh +++ b/docker/base/kolla-common.sh @@ -19,16 +19,37 @@ check_required_vars() { done } +# The usage of the wait_for function looks like the following +# wait_for LOOPS_NUMBER SLEEP_TIME ARGS +# +# The ARGS are read and concatenated together into a single command and the +# command is executed in a loop until it succeeds or reaches the max number of +# attempts (LOOPS_NUMBER). +# +# Optional variables SUCCESSFUL_MATCH_OUTPUT and FAIL_MATCH_OUTPUT variable may +# also be set to control if the loop exits early if the commands stdout/stderr +# matches the supplied regex string. Consider using the `wait_for_output` and +# `wait_for_output_unless` functions in case there is a need to check for the +# command output. +# +# The script exits on failure, either when output contains string identified as +# failure, or when it reaches a timeout. +# +# Examples: +# wait_for 30 10 ping -c 1 192.0.2.2 +# wait_for 10 1 ls file_we_are_waiting_for +# wait_for 10 3 date \| grep 8 wait_for() { local loops=${1:-""} local sleeptime=${2:-""} - local fail_match_output=${fail_match_output:-""} - local successful_match_output=${successful_match_output:-""} + FAIL_MATCH_OUTPUT=${FAIL_MATCH_OUTPUT:-""} + SUCCESSFUL_MATCH_OUTPUT=${SUCCESSFUL_MATCH_OUTPUT:-""} shift 2 || true local command="$@" if [ -z "$loops" -o -z "$sleeptime" -o -z "$command" ]; then - echo "Incorrect call of wait_for. Refer to docs/wait-for.md for help" + echo "wait_for is missing a required parameter" + return 1 fi local i=0 @@ -36,15 +57,15 @@ wait_for() { i=$((i + 1)) local status=0 local output=$(eval $command 2>&1) || status=$? - if [[ -n "$successful_match_output" ]] \ - && [[ $output =~ $successful_match_output ]]; then - break - elif [[ -n "$fail_match_output" ]] \ - && [[ $output =~ $fail_match_output ]]; then - echo "Command output matched '$fail_match_output'." - continue - elif [[ -z "$successful_match_output" ]] && [[ $status -eq 0 ]]; then - break + if [[ -n "$SUCCESSFUL_MATCH_OUTPUT" ]] \ + && [[ $output =~ $SUCCESSFUL_MATCH_OUTPUT ]]; then + return 0 + elif [[ -n "$FAIL_MATCH_OUTPUT" ]] \ + && [[ $output =~ $FAIL_MATCH_OUTPUT ]]; then + echo "Command output matched '$FAIL_MATCH_OUTPUT'." + exit 1 + elif [[ -z "$SUCCESSFUL_MATCH_OUTPUT" ]] && [[ $status -eq 0 ]]; then + return 0 fi sleep $sleeptime done @@ -54,6 +75,34 @@ wait_for() { exit 1 } +# Helper function to `wait_for` that only succeeds when the given regex is +# matching the command's output. Exit early with a failure when the second +# supplied regexp is matching the output. +# +# Example: +# wait_for_output_unless CREATE_COMPLETE CREATE_FAIL 30 10 heat stack-show undercloud +wait_for_output_unless() { + SUCCESSFUL_MATCH_OUTPUT=$1 + FAIL_MATCH_OUTPUT=$2 + shift 2 + wait_for $@ + local status=$? + unset SUCCESSFUL_MATCH_OUTPUT + unset FAIL_MATCH_OUTPUT + return $status +} + +# Helper function to `wait_for` that only succeeds when the given regex is +# matching the command's output. +# +# Example: +# wait_for_output CREATE_COMPLETE 30 10 heat stack-show undercloud +wait_for_output() { + local expected_output=$1 + shift + wait_for_output_unless $expected_output '' $@ +} + # Exit unless we receive a successful response from corresponding OpenStack # service. check_for_os_service() { diff --git a/docs/wait-for.md b/docs/wait-for.md deleted file mode 100644 index 3317c315f5..0000000000 --- a/docs/wait-for.md +++ /dev/null @@ -1,18 +0,0 @@ -# Wait-for function - -The usage of the wait_for function looks like the following - $ SCRIPT_NAME LOOPS_NUMBER SLEEP_TIME ARGS - -The ARGS are read and concatenated together into a single command -and the command is executed in a loop until it succeeds or reaches -the max number of attempts (LOOPS_NUMBER). - -An optional FAIL_MATCH_OUTPUT variable may also be set to control -if the loop exits early if the commands stdout/stderr matches the -supplied regex string. -Examples: - $ wait_for 30 10 ping -c 1 192.0.2.2 - $ wait_for 10 1 ls file_we_are_waiting_for - $ wait_for 10 3 date \| grep 8 - $ FAIL_MATCH_OUTPUT=CREATE_FAILED wait_for 30 10 heat stack-show undercloud - $ SUCCESSFUL_MATCH_OUTPUT=CREATE_COMPLETE wait_for 30 10 heat stack-show undercloud