From 475d4c57676e9e93276be3b802aaa7e758610ead Mon Sep 17 00:00:00 2001 From: Michael Matloob Date: Thu, 21 Dec 2023 15:55:28 -0500 Subject: [PATCH] third_party/wait-for-it: replace with a simple go program The program doesn't have all the features of wait-for-it, but it implements the core functionality we need. For golang/go#61399 Change-Id: Ia5498523e44b74dcd5af1c984521f1a46208d2c5 Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/552295 kokoro-CI: kokoro LUCI-TryBot-Result: Go LUCI Reviewed-by: Jonathan Amsterdam --- devtools/cmd/wait_available/main.go | 66 +++++++ devtools/docker/compose.yaml | 10 +- tests/screentest/run.sh | 2 +- third_party/wait-for-it/.gitignore | 3 - third_party/wait-for-it/.travis.yml | 7 - third_party/wait-for-it/LICENSE | 20 -- third_party/wait-for-it/README.md | 78 -------- third_party/wait-for-it/composer.json | 7 - third_party/wait-for-it/test/README.md | 18 -- .../wait-for-it/test/container-runners.py | 35 ---- third_party/wait-for-it/test/requirements.txt | 2 - third_party/wait-for-it/test/wait-for-it.py | 182 ------------------ third_party/wait-for-it/wait-for-it.sh | 182 ------------------ 13 files changed, 72 insertions(+), 540 deletions(-) create mode 100644 devtools/cmd/wait_available/main.go delete mode 100644 third_party/wait-for-it/.gitignore delete mode 100644 third_party/wait-for-it/.travis.yml delete mode 100644 third_party/wait-for-it/LICENSE delete mode 100644 third_party/wait-for-it/README.md delete mode 100644 third_party/wait-for-it/composer.json delete mode 100644 third_party/wait-for-it/test/README.md delete mode 100755 third_party/wait-for-it/test/container-runners.py delete mode 100644 third_party/wait-for-it/test/requirements.txt delete mode 100755 third_party/wait-for-it/test/wait-for-it.py delete mode 100755 third_party/wait-for-it/wait-for-it.sh diff --git a/devtools/cmd/wait_available/main.go b/devtools/cmd/wait_available/main.go new file mode 100644 index 000000000..31fa72e09 --- /dev/null +++ b/devtools/cmd/wait_available/main.go @@ -0,0 +1,66 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build unix + +package main + +import ( + "context" + "net" + "os" + "os/exec" + "path/filepath" + "syscall" + "time" + + "golang.org/x/pkgsite/internal/log" +) + +var timeout = 15 * time.Second + +func main() { + ctx := context.Background() + + if len(os.Args) < 2 { + log.Fatalf(ctx, "expected at least one argument; got none") + } + hostport := os.Args[1] + var command []string + + if len(os.Args) > 2 { + if os.Args[2] != "--" { + log.Fatalf(ctx, "expected second argument to be \"--\"; got %q", os.Args[2]) + } + command = os.Args[3:] + } + + start := time.Now() + for { + if time.Since(start) > timeout { + break + } + if conn, err := net.DialTimeout("tcp", hostport, 1*time.Second); err != nil { + time.Sleep(1 * time.Second) + continue + } else { + conn.Close() + break + } + } + var err error + binpath := command[0] + if !filepath.IsAbs(binpath) { + binpath, err = exec.LookPath(command[0]) + if err != nil { + log.Fatalf(ctx, "looking up err: %v", err) + } + } + if len(command) > 0 { + err := syscall.Exec(binpath, command, os.Environ()) + if err != nil { + log.Fatalf(ctx, "exec-ing binary: %v", err) + } + } +} diff --git a/devtools/docker/compose.yaml b/devtools/docker/compose.yaml index adeb54bcf..c6bb71314 100644 --- a/devtools/docker/compose.yaml +++ b/devtools/docker/compose.yaml @@ -38,7 +38,7 @@ services: # TERM is set to xterm-256color for use by devtools/lib.sh. TERM: xterm-256color WAITFORIT_TIMEOUT: 300 - entrypoint: ./third_party/wait-for-it/wait-for-it.sh db:5432 -- ./all.bash + entrypoint: go run ./devtools/cmd/wait_available db:5432 -- ./all.bash volumes: - ../../:/pkgsite working_dir: /pkgsite @@ -49,7 +49,7 @@ services: environment: <<: [*database-variables, *go-variables] WAITFORIT_TIMEOUT: 300 - entrypoint: ./third_party/wait-for-it/wait-for-it.sh frontend:8080 -- go run + entrypoint: go run ./devtools/cmd/wait_available frontend:8080 -- go run command: "tests/search/main.go -frontend http://frontend:8080" volumes: - ../../:/pkgsite @@ -61,7 +61,7 @@ services: environment: <<: *go-variables WAITFORIT_TIMEOUT: 300 - entrypoint: ./third_party/wait-for-it/wait-for-it.sh frontend:8080 -- go run + entrypoint: go run ./devtools/cmd/wait_available frontend:8080 -- go run command: "tests/api/main.go -frontend http://frontend:8080 -all compare " volumes: - ../../:/pkgsite @@ -72,7 +72,7 @@ services: depends_on: - db command: bash -c " - ./third_party/wait-for-it/wait-for-it.sh db:5432 -- + go run ./devtools/cmd/wait_available db:5432 -- go run ./devtools/cmd/db/main.go create && go run ./devtools/cmd/db/main.go migrate && go run ./cmd/frontend -host=0.0.0.0:8080" @@ -94,7 +94,7 @@ services: # time seeddb runs. If this ends up being flaky, we should add a check here. command: bash -c " echo GO_DISCOVERY_CONFIG_DYNAMIC=$GO_DISCOVERY_CONFIG_DYNAMIC && - ./third_party/wait-for-it/wait-for-it.sh db:5432 -- + go run ./devtools/cmd/wait_available db:5432 -- go run ./devtools/cmd/db/main.go create && go run ./devtools/cmd/db/main.go migrate && go run ./devtools/cmd/seeddb/main.go -seed ${GO_DISCOVERY_SEED_DB_FILE:-seed.txt}" diff --git a/tests/screentest/run.sh b/tests/screentest/run.sh index 730e473ea..3edb33dac 100755 --- a/tests/screentest/run.sh +++ b/tests/screentest/run.sh @@ -133,7 +133,7 @@ main() { dcompose run --rm --entrypoint bash go -c " export WAITFORIT_TIMEOUT=120 go install golang.org/x/website/cmd/screentest@latest - ./third_party/wait-for-it/wait-for-it.sh frontend:8080 -- + go run ./devtools/cmd/wait_available frontend:8080 -- $(echo $cmd)" elif [ "$env" = local ]; then if ! nc -z localhost 9222; then diff --git a/third_party/wait-for-it/.gitignore b/third_party/wait-for-it/.gitignore deleted file mode 100644 index fcad8de3b..000000000 --- a/third_party/wait-for-it/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -**/*.pyc -.pydevproject -/vendor/ diff --git a/third_party/wait-for-it/.travis.yml b/third_party/wait-for-it/.travis.yml deleted file mode 100644 index 30a813838..000000000 --- a/third_party/wait-for-it/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: python -python: - - "2.7" - -script: - - python test/wait-for-it.py - diff --git a/third_party/wait-for-it/LICENSE b/third_party/wait-for-it/LICENSE deleted file mode 100644 index bd18d0c45..000000000 --- a/third_party/wait-for-it/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) -Copyright (c) 2016 Giles Hall - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/third_party/wait-for-it/README.md b/third_party/wait-for-it/README.md deleted file mode 100644 index d6372e657..000000000 --- a/third_party/wait-for-it/README.md +++ /dev/null @@ -1,78 +0,0 @@ -COPIED from https://github.com/vishnubob/wait-for-it at -commit 81b1373f17855a4dc21156cfe1694c31d7d1792e. - -# wait-for-it - -`wait-for-it.sh` is a pure bash script that will wait on the availability of a -host and TCP port. It is useful for synchronizing the spin-up of -interdependent services, such as linked docker containers. Since it is a pure -bash script, it does not have any external dependencies. - -## Usage - -```text -wait-for-it.sh host:port [-s] [-t timeout] [-- command args] --h HOST | --host=HOST Host or IP under test --p PORT | --port=PORT TCP port under test - Alternatively, you specify the host and port as host:port --s | --strict Only execute subcommand if the test succeeds --q | --quiet Don't output any status messages --t TIMEOUT | --timeout=TIMEOUT - Timeout in seconds, zero for no timeout --- COMMAND ARGS Execute command with args after the test finishes -``` - -## Examples - -For example, let's test to see if we can access port 80 on `www.google.com`, -and if it is available, echo the message `google is up`. - -```text -$ ./wait-for-it.sh www.google.com:80 -- echo "google is up" -wait-for-it.sh: waiting 15 seconds for www.google.com:80 -wait-for-it.sh: www.google.com:80 is available after 0 seconds -google is up -``` - -You can set your own timeout with the `-t` or `--timeout=` option. Setting -the timeout value to 0 will disable the timeout: - -```text -$ ./wait-for-it.sh -t 0 www.google.com:80 -- echo "google is up" -wait-for-it.sh: waiting for www.google.com:80 without a timeout -wait-for-it.sh: www.google.com:80 is available after 0 seconds -google is up -``` - -The subcommand will be executed regardless if the service is up or not. If you -wish to execute the subcommand only if the service is up, add the `--strict` -argument. In this example, we will test port 81 on `www.google.com` which will -fail: - -```text -$ ./wait-for-it.sh www.google.com:81 --timeout=1 --strict -- echo "google is up" -wait-for-it.sh: waiting 1 seconds for www.google.com:81 -wait-for-it.sh: timeout occurred after waiting 1 seconds for www.google.com:81 -wait-for-it.sh: strict mode, refusing to execute subprocess -``` - -If you don't want to execute a subcommand, leave off the `--` argument. This -way, you can test the exit condition of `wait-for-it.sh` in your own scripts, -and determine how to proceed: - -```text -$ ./wait-for-it.sh www.google.com:80 -wait-for-it.sh: waiting 15 seconds for www.google.com:80 -wait-for-it.sh: www.google.com:80 is available after 0 seconds -$ echo $? -0 -$ ./wait-for-it.sh www.google.com:81 -wait-for-it.sh: waiting 15 seconds for www.google.com:81 -wait-for-it.sh: timeout occurred after waiting 15 seconds for www.google.com:81 -$ echo $? -124 -``` - -## Community - -*Debian*: There is a [Debian package](https://tracker.debian.org/pkg/wait-for-it). diff --git a/third_party/wait-for-it/composer.json b/third_party/wait-for-it/composer.json deleted file mode 100644 index ea892d726..000000000 --- a/third_party/wait-for-it/composer.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "vishnubob/wait-for-it", - "description": "Pure bash script to test and wait on the availability of a TCP host and port", - "type": "library", - "license": "MIT", - "bin": ["wait-for-it.sh"] -} diff --git a/third_party/wait-for-it/test/README.md b/third_party/wait-for-it/test/README.md deleted file mode 100644 index 59cd8db80..000000000 --- a/third_party/wait-for-it/test/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Tests for wait-for-it - -* wait-for-it.py - pytests for wait-for-it.sh -* container-runners.py - Runs wait-for-it.py tests in multiple containers -* requirements.txt - pip requirements for container-runners.py - -To run the basic tests: - -``` -python wait-for-it.py -``` - -Many of the issues encountered have been related to differences between operating system versions. The container-runners.py script provides an easy way to run the python wait-for-it.py tests against multiple system configurations: - -``` -pip install -r requirements.txt -python container-runners.py -``` diff --git a/third_party/wait-for-it/test/container-runners.py b/third_party/wait-for-it/test/container-runners.py deleted file mode 100755 index 3f8f358f0..000000000 --- a/third_party/wait-for-it/test/container-runners.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python - -# Unit tests to run wait-for-it.py unit tests in several different docker images - -import unittest -import os -import docker -from parameterized import parameterized - -client = docker.from_env() -app_path = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..')) -volumes = {app_path: {'bind': '/app', 'mode': 'ro'}} - -class TestContainers(unittest.TestCase): - """ - Test multiple container types with the test cases in wait-for-it.py - """ - - @parameterized.expand([ - "python:3.5-buster", - "python:3.5-stretch", - "dougg/alpine-busybox:alpine-3.11.3_busybox-1.30.1", - "dougg/alpine-busybox:alpine-3.11.3_busybox-1.31.1" - ]) - def test_image(self, image): - print(image) - command="/app/test/wait-for-it.py" - container = client.containers.run(image, command=command, volumes=volumes, detach=True) - result = container.wait() - logs = container.logs() - container.remove() - self.assertEqual(result["StatusCode"], 0) - -if __name__ == '__main__': - unittest.main() diff --git a/third_party/wait-for-it/test/requirements.txt b/third_party/wait-for-it/test/requirements.txt deleted file mode 100644 index 9ba1e5249..000000000 --- a/third_party/wait-for-it/test/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -docker>=4.0.0 -parameterized>=0.7.0 diff --git a/third_party/wait-for-it/test/wait-for-it.py b/third_party/wait-for-it/test/wait-for-it.py deleted file mode 100755 index de7530ee3..000000000 --- a/third_party/wait-for-it/test/wait-for-it.py +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env python - -import unittest -import shlex -from subprocess import Popen, PIPE -import os -import sys -import socket -import re - -MISSING_ARGS_TEXT = "Error: you need to provide a host and port to test." -HELP_TEXT = "Usage:" # Start of help text -DIVIDE_LINE = '-'*71 # Output line of dashes - - -class TestWaitForIt(unittest.TestCase): - """ - TestWaitForIt tests the wait-for-it.sh shell script. - The wait-for-it.sh script is assumed to be in the parent directory to - the test script. - """ - - def execute(self, cmd): - """Executes a command and returns exit code, STDOUT, STDERR""" - args = shlex.split(cmd) - proc = Popen(args, stdout=PIPE, stderr=PIPE) - out, err = proc.communicate() - exitcode = proc.returncode - return exitcode, out.decode('utf-8'), err.decode('utf-8') - - def open_local_port(self, timeout=5): - s = socket.socket() - s.bind(('', 0)) - s.listen(timeout) - return s, s.getsockname()[1] - - def check_args(self, args, stdout_regex, stderr_regex, should_succeed): - command = self.wait_script + " " + args - exitcode, out, err = self.execute(command) - - # Check stderr - msg = ("Failed check that STDERR:\n" + - DIVIDE_LINE + "\n" + err + "\n" + DIVIDE_LINE + - "\nmatches:\n" + - DIVIDE_LINE + "\n" + stderr_regex + "\n" + DIVIDE_LINE) - self.assertIsNotNone(re.match(stderr_regex, err, re.DOTALL), msg) - - # Check STDOUT - msg = ("Failed check that STDOUT:\n" + - DIVIDE_LINE + "\n" + out + "\n" + DIVIDE_LINE + - "\nmatches:\n" + - DIVIDE_LINE + "\n" + stdout_regex + "\n" + DIVIDE_LINE) - self.assertIsNotNone(re.match(stdout_regex, out, re.DOTALL), msg) - - # Check exit code - self.assertEqual(should_succeed, exitcode == 0) - - def setUp(self): - script_path = os.path.dirname(sys.argv[0]) - parent_path = os.path.abspath(os.path.join(script_path, os.pardir)) - self.wait_script = os.path.join(parent_path, "wait-for-it.sh") - - def test_no_args(self): - """ - Check that no aruments returns the missing args text and the - correct return code - """ - self.check_args( - "", - "^$", - MISSING_ARGS_TEXT, - False - ) - # Return code should be 1 when called with no args - exitcode, out, err = self.execute(self.wait_script) - self.assertEqual(exitcode, 1) - - def test_help(self): - """ Check that help text is printed with --help argument """ - self.check_args( - "--help", - "", - HELP_TEXT, - False - ) - - def test_no_port(self): - """ Check with missing port argument """ - self.check_args( - "--host=localhost", - "", - MISSING_ARGS_TEXT, - False - ) - - def test_no_host(self): - """ Check with missing hostname argument """ - self.check_args( - "--port=80", - "", - MISSING_ARGS_TEXT, - False - ) - - def test_host_port(self): - """ Check that --host and --port args work correctly """ - soc, port = self.open_local_port() - self.check_args( - "--host=localhost --port={0} --timeout=1".format(port), - "", - "wait-for-it.sh: waiting 1 seconds for localhost:{0}".format(port), - True - ) - soc.close() - - def test_combined_host_port(self): - """ - Tests that wait-for-it.sh returns correctly after establishing a - connectionm using combined host and ports - """ - soc, port = self.open_local_port() - self.check_args( - "localhost:{0} --timeout=1".format(port), - "", - "wait-for-it.sh: waiting 1 seconds for localhost:{0}".format(port), - True - ) - soc.close() - - - def test_port_failure_with_timeout(self): - """ - Note exit status of 124 is exected, passed from the timeout command - """ - self.check_args( - "localhost:8929 --timeout=1", - "", - ".*timeout occurred after waiting 1 seconds for localhost:8929", - False - ) - - def test_command_execution(self): - """ - Checks that a command executes correctly after a port test passes - """ - soc, port = self.open_local_port() - self.check_args( - "localhost:{0} -- echo \"CMD OUTPUT\"".format(port), - "CMD OUTPUT", - ".*wait-for-it.sh: localhost:{0} is available after 0 seconds".format(port), - True - ) - soc.close() - - def test_failed_command_execution(self): - """ - Check command failure. The command in question outputs STDERR and - an exit code of 2 - """ - soc, port = self.open_local_port() - self.check_args( - "localhost:{0} -- ls not_real_file".format(port), - "", - ".*No such file or directory\n", - False - ) - soc.close() - - def test_command_after_connection_failure(self): - """ - Test that a command still runs even if a connection times out - and that the return code is correct for the comand being run - """ - self.check_args( - "localhost:8929 --timeout=1 -- echo \"CMD OUTPUT\"", - "CMD OUTPUT", - ".*timeout occurred after waiting 1 seconds for localhost:8929", - True - ) - -if __name__ == '__main__': - unittest.main() diff --git a/third_party/wait-for-it/wait-for-it.sh b/third_party/wait-for-it/wait-for-it.sh deleted file mode 100755 index d990e0d36..000000000 --- a/third_party/wait-for-it/wait-for-it.sh +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env bash -# Use this script to test if a given TCP host/port are available - -WAITFORIT_cmdname=${0##*/} - -echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } - -usage() -{ - cat << USAGE >&2 -Usage: - $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args] - -h HOST | --host=HOST Host or IP under test - -p PORT | --port=PORT TCP port under test - Alternatively, you specify the host and port as host:port - -s | --strict Only execute subcommand if the test succeeds - -q | --quiet Don't output any status messages - -t TIMEOUT | --timeout=TIMEOUT - Timeout in seconds, zero for no timeout - -- COMMAND ARGS Execute command with args after the test finishes -USAGE - exit 1 -} - -wait_for() -{ - if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then - echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" - else - echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout" - fi - WAITFORIT_start_ts=$(date +%s) - while : - do - if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then - nc -z $WAITFORIT_HOST $WAITFORIT_PORT - WAITFORIT_result=$? - else - (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1 - WAITFORIT_result=$? - fi - if [[ $WAITFORIT_result -eq 0 ]]; then - WAITFORIT_end_ts=$(date +%s) - echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds" - break - fi - sleep 1 - done - return $WAITFORIT_result -} - -wait_for_wrapper() -{ - # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 - if [[ $WAITFORIT_QUIET -eq 1 ]]; then - timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & - else - timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & - fi - WAITFORIT_PID=$! - trap "kill -INT -$WAITFORIT_PID" INT - wait $WAITFORIT_PID - WAITFORIT_RESULT=$? - if [[ $WAITFORIT_RESULT -ne 0 ]]; then - echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" - fi - return $WAITFORIT_RESULT -} - -# process arguments -while [[ $# -gt 0 ]] -do - case "$1" in - *:* ) - WAITFORIT_hostport=(${1//:/ }) - WAITFORIT_HOST=${WAITFORIT_hostport[0]} - WAITFORIT_PORT=${WAITFORIT_hostport[1]} - shift 1 - ;; - --child) - WAITFORIT_CHILD=1 - shift 1 - ;; - -q | --quiet) - WAITFORIT_QUIET=1 - shift 1 - ;; - -s | --strict) - WAITFORIT_STRICT=1 - shift 1 - ;; - -h) - WAITFORIT_HOST="$2" - if [[ $WAITFORIT_HOST == "" ]]; then break; fi - shift 2 - ;; - --host=*) - WAITFORIT_HOST="${1#*=}" - shift 1 - ;; - -p) - WAITFORIT_PORT="$2" - if [[ $WAITFORIT_PORT == "" ]]; then break; fi - shift 2 - ;; - --port=*) - WAITFORIT_PORT="${1#*=}" - shift 1 - ;; - -t) - WAITFORIT_TIMEOUT="$2" - if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi - shift 2 - ;; - --timeout=*) - WAITFORIT_TIMEOUT="${1#*=}" - shift 1 - ;; - --) - shift - WAITFORIT_CLI=("$@") - break - ;; - --help) - usage - ;; - *) - echoerr "Unknown argument: $1" - usage - ;; - esac -done - -if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then - echoerr "Error: you need to provide a host and port to test." - usage -fi - -WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15} -WAITFORIT_STRICT=${WAITFORIT_STRICT:-0} -WAITFORIT_CHILD=${WAITFORIT_CHILD:-0} -WAITFORIT_QUIET=${WAITFORIT_QUIET:-0} - -# Check to see if timeout is from busybox? -WAITFORIT_TIMEOUT_PATH=$(type -p timeout) -WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH) - -WAITFORIT_BUSYTIMEFLAG="" -if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then - WAITFORIT_ISBUSY=1 - # Check if busybox timeout uses -t flag - # (recent Alpine versions don't support -t anymore) - if timeout &>/dev/stdout | grep -q -e '-t '; then - WAITFORIT_BUSYTIMEFLAG="-t" - fi -else - WAITFORIT_ISBUSY=0 -fi - -if [[ $WAITFORIT_CHILD -gt 0 ]]; then - wait_for - WAITFORIT_RESULT=$? - exit $WAITFORIT_RESULT -else - if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then - wait_for_wrapper - WAITFORIT_RESULT=$? - else - wait_for - WAITFORIT_RESULT=$? - fi -fi - -if [[ $WAITFORIT_CLI != "" ]]; then - if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then - echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess" - exit $WAITFORIT_RESULT - fi - exec "${WAITFORIT_CLI[@]}" -else - exit $WAITFORIT_RESULT -fi