github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/scripts/docker/production/wait-for-it.sh (about) 1 #!/usr/bin/env bash 2 # Use this script to test if a given TCP host/port are available 3 4 # From https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh 5 6 WAITFORIT_cmdname=${0##*/} 7 8 echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } 9 10 usage() 11 { 12 cat << USAGE >&2 13 Usage: 14 $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args] 15 -h HOST | --host=HOST Host or IP under test 16 -p PORT | --port=PORT TCP port under test 17 Alternatively, you specify the host and port as host:port 18 -s | --strict Only execute subcommand if the test succeeds 19 -q | --quiet Don't output any status messages 20 -t TIMEOUT | --timeout=TIMEOUT 21 Timeout in seconds, zero for no timeout 22 -- COMMAND ARGS Execute command with args after the test finishes 23 USAGE 24 exit 1 25 } 26 27 wait_for() 28 { 29 if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then 30 echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" 31 else 32 echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout" 33 fi 34 WAITFORIT_start_ts=$(date +%s) 35 while : 36 do 37 if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then 38 nc -z $WAITFORIT_HOST $WAITFORIT_PORT 39 WAITFORIT_result=$? 40 else 41 (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1 42 WAITFORIT_result=$? 43 fi 44 if [[ $WAITFORIT_result -eq 0 ]]; then 45 WAITFORIT_end_ts=$(date +%s) 46 echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds" 47 break 48 fi 49 sleep 1 50 done 51 return $WAITFORIT_result 52 } 53 54 wait_for_wrapper() 55 { 56 # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 57 if [[ $WAITFORIT_QUIET -eq 1 ]]; then 58 timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & 59 else 60 timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & 61 fi 62 WAITFORIT_PID=$! 63 trap "kill -INT -$WAITFORIT_PID" INT 64 wait $WAITFORIT_PID 65 WAITFORIT_RESULT=$? 66 if [[ $WAITFORIT_RESULT -ne 0 ]]; then 67 echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" 68 fi 69 return $WAITFORIT_RESULT 70 } 71 72 # process arguments 73 while [[ $# -gt 0 ]] 74 do 75 case "$1" in 76 *:* ) 77 WAITFORIT_hostport=(${1//:/ }) 78 WAITFORIT_HOST=${WAITFORIT_hostport[0]} 79 WAITFORIT_PORT=${WAITFORIT_hostport[1]} 80 shift 1 81 ;; 82 --child) 83 WAITFORIT_CHILD=1 84 shift 1 85 ;; 86 -q | --quiet) 87 WAITFORIT_QUIET=1 88 shift 1 89 ;; 90 -s | --strict) 91 WAITFORIT_STRICT=1 92 shift 1 93 ;; 94 -h) 95 WAITFORIT_HOST="$2" 96 if [[ $WAITFORIT_HOST == "" ]]; then break; fi 97 shift 2 98 ;; 99 --host=*) 100 WAITFORIT_HOST="${1#*=}" 101 shift 1 102 ;; 103 -p) 104 WAITFORIT_PORT="$2" 105 if [[ $WAITFORIT_PORT == "" ]]; then break; fi 106 shift 2 107 ;; 108 --port=*) 109 WAITFORIT_PORT="${1#*=}" 110 shift 1 111 ;; 112 -t) 113 WAITFORIT_TIMEOUT="$2" 114 if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi 115 shift 2 116 ;; 117 --timeout=*) 118 WAITFORIT_TIMEOUT="${1#*=}" 119 shift 1 120 ;; 121 --) 122 shift 123 WAITFORIT_CLI=("$@") 124 break 125 ;; 126 --help) 127 usage 128 ;; 129 *) 130 echoerr "Unknown argument: $1" 131 usage 132 ;; 133 esac 134 done 135 136 if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then 137 echoerr "Error: you need to provide a host and port to test." 138 usage 139 fi 140 141 WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15} 142 WAITFORIT_STRICT=${WAITFORIT_STRICT:-0} 143 WAITFORIT_CHILD=${WAITFORIT_CHILD:-0} 144 WAITFORIT_QUIET=${WAITFORIT_QUIET:-0} 145 146 # Check to see if timeout is from busybox? 147 WAITFORIT_TIMEOUT_PATH=$(type -p timeout) 148 WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH) 149 150 WAITFORIT_BUSYTIMEFLAG="" 151 if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then 152 WAITFORIT_ISBUSY=1 153 # Check if busybox timeout uses -t flag 154 # (recent Alpine versions don't support -t anymore) 155 if timeout &>/dev/stdout | grep -q -e '-t '; then 156 WAITFORIT_BUSYTIMEFLAG="-t" 157 fi 158 else 159 WAITFORIT_ISBUSY=0 160 fi 161 162 if [[ $WAITFORIT_CHILD -gt 0 ]]; then 163 wait_for 164 WAITFORIT_RESULT=$? 165 exit $WAITFORIT_RESULT 166 else 167 if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then 168 wait_for_wrapper 169 WAITFORIT_RESULT=$? 170 else 171 wait_for 172 WAITFORIT_RESULT=$? 173 fi 174 fi 175 176 if [[ $WAITFORIT_CLI != "" ]]; then 177 if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then 178 echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess" 179 exit $WAITFORIT_RESULT 180 fi 181 exec "${WAITFORIT_CLI[@]}" 182 else 183 exit $WAITFORIT_RESULT 184 fi