From 1e16634af63a49c3a59335e47d96691ff4df2a7a Mon Sep 17 00:00:00 2001 From: Stefan Stanacar Date: Sun, 3 Nov 2013 14:27:16 +0200 Subject: lib/oeqa/utils: sshcontrol: make timeout depend on output Instead of running the commands with a fixed timeout, we should kill the command if there is no output for timeout seconds. Also changed some strings/comments. (From OE-Core rev: beea86fa9637fd629719980e14beea758847b8f3) Signed-off-by: Stefan Stanacar Signed-off-by: Saul Wold Signed-off-by: Richard Purdie --- meta/lib/oeqa/utils/sshcontrol.py | 41 ++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'meta/lib/oeqa/utils/sshcontrol.py') diff --git a/meta/lib/oeqa/utils/sshcontrol.py b/meta/lib/oeqa/utils/sshcontrol.py index 1539ff2a37..07257b8948 100644 --- a/meta/lib/oeqa/utils/sshcontrol.py +++ b/meta/lib/oeqa/utils/sshcontrol.py @@ -9,6 +9,7 @@ import subprocess import time import os +import select class SSHControl(object): @@ -50,32 +51,44 @@ class SSHControl(object): if self.host: sshconn = self._internal_run(cmd) else: - raise Exception("Remote IP hasn't been set: '%s'" % actualcmd) + raise Exception("Remote IP/host hasn't been set, I can't run ssh without one.") + # run the command forever if timeout == 0: - self._out = sshconn.communicate()[0] - self._ret = sshconn.poll() + output = sshconn.communicate()[0] else: + # use the default timeout if timeout is None: tdelta = self.timeout + # use the specified timeout else: tdelta = timeout endtime = self._starttime + tdelta - while sshconn.poll() is None and time.time() < endtime: - time.sleep(1) + output = '' + eof = False + while time.time() < endtime and not eof: + if select.select([sshconn.stdout], [], [], 5)[0] != []: + data = os.read(sshconn.stdout.fileno(), 1024) + if not data: + sshconn.stdout.close() + eof = True + else: + output += data + endtime = time.time() + tdelta + # process hasn't returned yet if sshconn.poll() is None: - self._ret = 255 sshconn.terminate() - sshconn.kill() - self._out = sshconn.stdout.read() - sshconn.stdout.close() - self._out += "\n[!!! SSH command timed out after %d seconds and it was killed]" % tdelta - else: - self._out = sshconn.stdout.read() - self._ret = sshconn.poll() + time.sleep(3) + try: + sshconn.kill() + except OSError: + pass + output += "\n[!!! SSH command killed - no output for %d seconds. Total running time: %d seconds." % (tdelta, time.time() - self._starttime) + + self._ret = sshconn.poll() # strip the last LF so we can test the output - self._out = self._out.rstrip() + self._out = output.rstrip() self.log("%s" % self._out) self.log("[SSH command returned after %d seconds]: %s" % (time.time() - self._starttime, self._ret)) return (self._ret, self._out) -- cgit v1.2.3-54-g00ecf