blob: f0e728970a4184f6a91093e267840f7dbf36b529 [file] [log] [blame]
David K. Bainbridgebba65ff2018-01-19 09:26:09 -08001#!/usr/bin/env bash
Zack Williams41513bf2018-07-07 20:08:35 -07002# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
David K. Bainbridgebba65ff2018-01-19 09:26:09 -080015# Use this script to test if a given TCP host/port are available
16
17cmdname=$(basename $0)
18
19echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
20
21usage()
22{
23 cat << USAGE >&2
24Usage:
25 $cmdname host:port [-s] [-t timeout] [-- command args]
26 -h HOST | --host=HOST Host or IP under test
27 -p PORT | --port=PORT TCP port under test
28 Alternatively, you specify the host and port as host:port
29 -s | --strict Only execute subcommand if the test succeeds
30 -q | --quiet Don't output any status messages
31 -t TIMEOUT | --timeout=TIMEOUT
32 Timeout in seconds, zero for no timeout
33 -- COMMAND ARGS Execute command with args after the test finishes
34USAGE
35 exit 1
36}
37
38wait_for()
39{
40 if [[ $TIMEOUT -gt 0 ]]; then
41 echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT"
42 else
43 echoerr "$cmdname: waiting for $HOST:$PORT without a timeout"
44 fi
45 start_ts=$(date +%s)
46 while :
47 do
48 if [[ $ISBUSY -eq 1 ]]; then
49 nc -z $HOST $PORT
50 result=$?
51 else
52 (echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1
53 result=$?
54 fi
55 if [[ $result -eq 0 ]]; then
56 end_ts=$(date +%s)
57 echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds"
58 break
59 fi
60 sleep 1
61 done
62 return $result
63}
64
65wait_for_wrapper()
66{
67 # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
68 if [[ $QUIET -eq 1 ]]; then
69 timeout $BUSYTIMEFLAG $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
70 else
71 timeout $BUSYTIMEFLAG $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT &
72 fi
73 PID=$!
74 trap "kill -INT -$PID" INT
75 wait $PID
76 RESULT=$?
77 if [[ $RESULT -ne 0 ]]; then
78 echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT"
79 fi
80 return $RESULT
81}
82
83# process arguments
84while [[ $# -gt 0 ]]
85do
86 case "$1" in
87 *:* )
88 hostport=(${1//:/ })
89 HOST=${hostport[0]}
90 PORT=${hostport[1]}
91 shift 1
92 ;;
93 --child)
94 CHILD=1
95 shift 1
96 ;;
97 -q | --quiet)
98 QUIET=1
99 shift 1
100 ;;
101 -s | --strict)
102 STRICT=1
103 shift 1
104 ;;
105 -h)
106 HOST="$2"
107 if [[ $HOST == "" ]]; then break; fi
108 shift 2
109 ;;
110 --host=*)
111 HOST="${1#*=}"
112 shift 1
113 ;;
114 -p)
115 PORT="$2"
116 if [[ $PORT == "" ]]; then break; fi
117 shift 2
118 ;;
119 --port=*)
120 PORT="${1#*=}"
121 shift 1
122 ;;
123 -t)
124 TIMEOUT="$2"
125 if [[ $TIMEOUT == "" ]]; then break; fi
126 shift 2
127 ;;
128 --timeout=*)
129 TIMEOUT="${1#*=}"
130 shift 1
131 ;;
132 --)
133 shift
134 CLI=("$@")
135 break
136 ;;
137 --help)
138 usage
139 ;;
140 *)
141 echoerr "Unknown argument: $1"
142 usage
143 ;;
144 esac
145done
146
147if [[ "$HOST" == "" || "$PORT" == "" ]]; then
148 echoerr "Error: you need to provide a host and port to test."
149 usage
150fi
151
152TIMEOUT=${TIMEOUT:-15}
153STRICT=${STRICT:-0}
154CHILD=${CHILD:-0}
155QUIET=${QUIET:-0}
156
157# check to see if timeout is from busybox?
158# check to see if timeout is from busybox?
159TIMEOUT_PATH=$(realpath $(which timeout))
160if [[ $TIMEOUT_PATH =~ "busybox" ]]; then
161 ISBUSY=1
162 BUSYTIMEFLAG="-t"
163else
164 ISBUSY=0
165 BUSYTIMEFLAG=""
166fi
167
168if [[ $CHILD -gt 0 ]]; then
169 wait_for
170 RESULT=$?
171 exit $RESULT
172else
173 if [[ $TIMEOUT -gt 0 ]]; then
174 wait_for_wrapper
175 RESULT=$?
176 else
177 wait_for
178 RESULT=$?
179 fi
180fi
181
182if [[ $CLI != "" ]]; then
183 if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then
184 echoerr "$cmdname: strict mode, refusing to execute subprocess"
185 exit $RESULT
186 fi
187 exec "${CLI[@]}"
188else
189 exit $RESULT
190fi