#!/bin/bash # # Copyright 2013 Red Hat # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -e # exit on the first non-zero status set -u # exit on unset variables SCRIPT_NAME=$(basename $0) function show_options() { echo "Usage: $SCRIPT_NAME LOOPS_NUMBER SLEEP_TIME ARGS" echo echo "ARGS are read and concatenated together into a single command." echo "Execute the command in a loop until it succeeds or the number" echo "of attempts exceeds LOOPS_NUMBER value. After each failure" echo "pause for SLEEP_TIME seconds." echo echo "An optional FAIL_MATCH_OUTPUT variable may also be set to control " echo "if the loop exits early if the commands stdout/stderr matches the " echo "supplied regex string." echo echo "Examples:" echo " wait_for 30 10 ping -c 1 192.0.2.2" echo " wait_for 10 1 ls file_we_are_waiting_for" echo " wait_for 10 3 date \| grep 8" echo " FAIL_MATCH_OUTPUT=CREATE_FAILED wait_for 30 10 heat stack-show undercloud" echo " SUCCESSFUL_MATCH_OUTPUT=CREATE_COMPLETE wait_for 30 10 heat stack-show undercloud" exit 1 } LOOPS=${1:-""} SLEEPTIME=${2:-""} FAIL_MATCH_OUTPUT=${FAIL_MATCH_OUTPUT:-""} SUCCESSFUL_MATCH_OUTPUT=${SUCCESSFUL_MATCH_OUTPUT:-""} shift 2 || true COMMAND="$@" if [ -z "$LOOPS" -o -z "$SLEEPTIME" -o -z "$COMMAND" ]; then show_options fi i=0 while [ $i -lt $LOOPS ]; do i=$((i + 1)) STATUS=0 OUTPUT=$(eval $COMMAND 2>&1) || STATUS=$? if [[ -n "$SUCCESSFUL_MATCH_OUTPUT" ]] \ && [[ $OUTPUT =~ $SUCCESSFUL_MATCH_OUTPUT ]]; then exit 0 elif [[ -n "$FAIL_MATCH_OUTPUT" ]] \ && [[ $OUTPUT =~ $FAIL_MATCH_OUTPUT ]]; then echo "Command output matched '$FAIL_MATCH_OUTPUT'. Exiting..." exit 1 elif [[ -z "$SUCCESSFUL_MATCH_OUTPUT" ]] && [[ $STATUS -eq 0 ]]; then # The command successfully completed and we aren't testing against # it's output so we have finished waiting. exit 0 fi sleep $SLEEPTIME done SECONDS=$((LOOPS * SLEEPTIME)) printf 'Timing out after %d seconds:\nCOMMAND=%s\nOUTPUT=%s\n' \ "$SECONDS" "$COMMAND" "$OUTPUT" exit 1