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