#!/bin/sh # Copyright 2023 Helmut Grohne # SPDX-License-Identifier: MIT : <<'POD2MAN' =head1 NAME debvm-waitssh - Wait for a ssh server to be reachable =head1 SYNOPSIS B [B<-t> I] [I:]I =head1 DESCRIPTION B can be used to wait for a virtual machine with exposed ssh port to be reachable on that port. If no hostname is given, B is assumed. =head1 OPTIONS =over 8 =item B<-t> I, B<--timeout>=I Set the maximum duration for waiting in seconds. Defaults to one minute. =back =head1 EXIT VALUES =over 8 =item B<0> The server is reachable. =item B<1> A timeout was reached before the server answered. =item B<2> Usage error. =back =head1 SEE ALSO debvm-run(1) =cut POD2MAN set -u TOTALTIMEOUT=60 SCANTIMEOUT=10 SCANDELAY=1 nth_arg() { shift "$1" printf "%s" "$1" } die() { echo "$*" >&2 exit 2 } usage() { die "usage: $0 [-t ] [:]" } usage_error() { echo "error: $*" >&2 usage } opt_timeout() { TOTALTIMEOUT=$1 } while getopts :t:-: OPTCHAR; do case "$OPTCHAR" in t) opt_timeout "$OPTARG" ;; -) case "$OPTARG" in help) usage ;; timeout) test "$OPTIND" -gt "$#" && usage_error "missing argument for --$OPTARG" "opt_$OPTARG" "$(nth_arg "$OPTIND" "$@")" OPTIND=$((OPTIND+1)) ;; timeout=) "opt_${OPTARG%%=*}" "${OPTARG#*=}" ;; *) usage_error "unrecognized option --$OPTARG" ;; esac ;; :) usage_error "missing argument for -$OPTARG" ;; '?') usage_error "unrecognized option -$OPTARG" ;; *) die "internal error while parsing command options, please report a bug" ;; esac done shift "$((OPTIND - 1))" test "$#" = 1 || usage case "$1" in "") usage ;; *:*) HOST=${1%:*} PORT=${1##*:} ;; *) HOST=localhost PORT=$1 ;; esac now=$(date +%s) deadline=$((now + TOTALTIMEOUT)) while test "$now" -lt "$deadline"; do start=$now ssh-keyscan -T "$SCANTIMEOUT" -p "$PORT" "$HOST" >/dev/null 2>&1 && exit 0 now=$(date +%s) if test "$((now - start))" -lt "$SCANTIMEOUT"; then sleep "$SCANDELAY" now=$(date +%s) fi done exit 1