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

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