Last active
November 7, 2018 22:14
-
-
Save larroy/83e5bd25ab77102b2d574d16632317b2 to your computer and use it in GitHub Desktop.
Wait for ssh to be open in python
This file contains hidden or 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
def wait_ssh_open(server, port, keep_waiting=None, timeout=None): | |
""" Wait for network service to appear | |
@param server: host to connect to (str) | |
@param port: port (int) | |
@param timeout: in seconds, if None or 0 wait forever | |
@return: True of False, if timeout is None may return only True or | |
throw unhandled network exception | |
""" | |
import socket | |
import errno | |
import time | |
log = logging.getLogger('wait_ssh_open') | |
sleep_s = 1 | |
if timeout: | |
from time import time as now | |
# time module is needed to calc timeout shared between two exceptions | |
end = now() + timeout | |
while True: | |
log.debug("Sleeping for %s second(s)", sleep_s) | |
time.sleep(sleep_s) | |
s = socket.socket() | |
try: | |
if keep_waiting and not keep_waiting(): | |
log.debug("keep_waiting() is set and evaluates to False") | |
return False | |
if timeout: | |
next_timeout = end - now() | |
if next_timeout < 0: | |
log.debug("connect time out") | |
return False | |
else: | |
log.debug("connect timeout %d s", next_timeout) | |
s.settimeout(next_timeout) | |
log.debug("connect %s:%d", server, port) | |
s.connect((server, port)) | |
ret = s.recv(1024).decode() | |
if ret and ret.startswith('SSH'): | |
s.close() | |
log.info("wait_ssh_open: port %s:%s is open and ssh is ready", server, port) | |
return True | |
else: | |
log.debug("Didn't get the SSH banner") | |
s.close() | |
except ConnectionError as err: | |
log.debug("ConnectionError %s", err) | |
if sleep_s == 0: | |
sleep_s = 1 | |
else: | |
sleep_s *= 2 | |
except socket.gaierror as err: | |
log.debug("gaierror %s",err) | |
return False | |
except socket.timeout as err: | |
# this exception occurs only if timeout is set | |
if timeout: | |
return False | |
except TimeoutError as err: | |
# catch timeout exception from underlying network library | |
# this one is different from socket.timeout | |
raise | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment