Last active
May 10, 2017 13:23
-
-
Save thonixx/647f2a2bee9ae381a88bfd08f15d9ece to your computer and use it in GitHub Desktop.
Wait for a server and try to log in via SSH (public key)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# global ssh arguments | |
SSHARG="-o StrictHostKeyChecking=false -o UserKnownHostsFile=/dev/null" | |
TIMEOUT="$(uname | grep -q Darwin && echo gtimeout || echo timeout)" | |
# get IP address from hostname | |
getIP() { | |
# return with failure if no server given | |
test -z "$1" && return 1 | |
# query IP | |
ip="$(dig +short +search -t a $1 | tail -n 1)" | |
test -z "$ip" && ip="$(ping -c1 -W 1000 $1 | egrep -m1 -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)")" | |
test -z "$ip" \ | |
&& { | |
# check if it is an ip already | |
echo "$1" | egrep "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" -q \ | |
&& { | |
# print if its ip | |
echo "$1" | |
return 0 | |
} \ | |
|| return 1 | |
} \ | |
|| { | |
# print queried ip | |
echo "$ip" | |
return 0 | |
} | |
return 1 | |
} | |
# ping loop to wait for the server to be booted up | |
waitforserver() { | |
# wait until server is ready to log in via ssh | |
ip="$(getIP $1)" | |
test -z "$ip" && return 1 | |
# ping the server | |
i=0 | |
i2=0 | |
ifail=0 | |
noloop="" | |
# check if server already responds to ping | |
$TIMEOUT 1 ping -c1 $ip &> /dev/null \ | |
&& noloop="true" | |
# loop through ping | |
if [[ "$noloop" != "true" ]] | |
then | |
while true | |
do | |
# timeout config | |
timeoutcmd=1 | |
timeoutsuccess=10 | |
timeoutfails=300 | |
# timeout if server is not pingable | |
# count one up if ping succeeded | |
# reset counter if ping failed | |
$TIMEOUT $timeoutcmd ping -c1 $ip &> /dev/null \ | |
&& i=$((i+1)) \ | |
|| i=0 | |
# only sleep a second if ping succeeds | |
# otherwise it "sleeps" a second due to timeout command | |
test "$i" -gt 0 && sleep 1 || sleep 0.1 | |
# introduce fail count | |
test "$i" = 0 && ifail=$((ifail+1)) || ifail=0 | |
# check if minimum of tries reached | |
if [[ "$i" -le $timeoutsuccess ]] && [[ "$ifail" -le $timeoutfails ]] | |
then | |
# if ping does not reach minimum go on and print tries | |
test "$i2" = 0 && printf "\rServer alive for ${i}s (${ifail}s failing). " | |
test "$i2" = 1 && printf "\rServer alive for ${i}s (${ifail}s failing).. " | |
test "$i2" = 2 && printf "\rServer alive for ${i}s (${ifail}s failing)..." | |
# counter for dots | |
test "$i2" -lt 2 && i2=$((i2+1)) || i2=0 | |
elif [[ "$ifail" -ge $timeoutfails ]] | |
then | |
# stop if maximum is reached | |
echo -e "\n${Red}Server not alive (tried for ${ifail}s)." | |
return 1 | |
else | |
# stop loop if minimum is reached | |
echo -e "\nServer alive." | |
break | |
fi | |
done | |
else | |
echo "Server alive." | |
fi | |
# sshing the server | |
i=0 | |
i2=0 | |
ifail=0 | |
noloop="" | |
# check if server already responds to ping | |
ssh -o BatchMode=yes -o ConnectTimeout=1 $SSHARG $ip "echo hello world" &> /dev/null \ | |
&& noloop="true" | |
# loop through ping | |
if [[ "$noloop" != "true" ]] | |
then | |
while true | |
do | |
# timeout config | |
timeoutcmd=1 | |
timeoutsuccess=3 | |
timeoutfails=120 | |
# timeout if server is not able to log in | |
# count one up if ssh succeeded | |
# reset counter if ssh failed | |
ssh -o BatchMode=yes -o ConnectTimeout=1 $SSHARG $ip "echo hello world" &> /dev/null \ | |
&& i=$((i+1)) \ | |
|| i=0 | |
# always sleep 1 second | |
sleep 1 | |
# introduce fail count | |
test "$i" = 0 && ifail=$((ifail+1)) || ifail=0 | |
# check if minimum of tries reached | |
if [[ "$i" -le $timeoutsuccess ]] && [[ "$ifail" -le $timeoutfails ]] | |
then | |
# if ssh does not reach minimum go on and print tries | |
test "$i2" = 0 && printf "\rHost is responding to SSH for $i seconds ($ifail seconds failing). " | |
test "$i2" = 1 && printf "\rHost is responding to SSH for $i seconds ($ifail seconds failing).. " | |
test "$i2" = 2 && printf "\rHost is responding to SSH for $i seconds ($ifail seconds failing)..." | |
# counter for dots | |
test "$i2" -lt 2 && i2=$((i2+1)) || i2=0 | |
elif [[ "$ifail" -ge $timeoutfails ]] | |
then | |
# stop if maximum is reached | |
echo -e "\n${Red}Server is not responding to ssh even after $ifail seconds." | |
return 1 | |
else | |
# stop loop if minimum is reached | |
echo -e "\nHost can be logged in." | |
break | |
fi | |
done | |
else | |
echo "Server already responding to SSH login." | |
return 0 | |
fi | |
} | |
test -z "$1" && echo "Provide hostname, servername, IP or domain to wait for." || waitforserver $1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment