summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa
diff options
context:
space:
mode:
authorStefan Stanacar <stefanx.stanacar@intel.com>2013-06-28 11:04:06 +0300
committerRichard Purdie <richard.purdie@linuxfoundation.org>2013-07-09 10:53:44 +0100
commitac341af8fafc5ea6e3f937ea6ad078ab0812b2bc (patch)
tree6809fecffc6d785115f1e0093872e371a072b6b2 /meta/lib/oeqa
parent12bf6262f674a6301332cc5fdc10b2757793cfc5 (diff)
downloadpoky-ac341af8fafc5ea6e3f937ea6ad078ab0812b2bc.tar.gz
lib/oeqa/utils/sshcontrol.py: helper module for running remote commands
Provides a class for setting up ssh connections, running commands and copying files to/from a target. (From OE-Core rev: 683cac9768e0d38fa15ddc5451e6b2333f184033) Signed-off-by: Stefan Stanacar <stefanx.stanacar@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/oeqa')
-rw-r--r--meta/lib/oeqa/utils/__init__.py0
-rw-r--r--meta/lib/oeqa/utils/sshcontrol.py100
2 files changed, 100 insertions, 0 deletions
diff --git a/meta/lib/oeqa/utils/__init__.py b/meta/lib/oeqa/utils/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/meta/lib/oeqa/utils/__init__.py
diff --git a/meta/lib/oeqa/utils/sshcontrol.py b/meta/lib/oeqa/utils/sshcontrol.py
new file mode 100644
index 0000000000..85a09a026f
--- /dev/null
+++ b/meta/lib/oeqa/utils/sshcontrol.py
@@ -0,0 +1,100 @@
1import subprocess
2import time
3import os
4import shlex
5
6class SSHControl(object):
7
8 def __init__(self, host=None, timeout=200, logfile=None):
9 self.host = host
10 self.timeout = timeout
11 self._out = ''
12 self._ret = 126
13 self.logfile = logfile
14
15 def log(self, msg):
16 if self.logfile:
17 with open(self.logfile, "a") as f:
18 f.write("%s\n" % msg)
19
20 def _internal_run(self, cmd):
21 # ssh hangs without os.setsid
22 proc = subprocess.Popen(shlex.split(cmd), shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, preexec_fn=os.setsid)
23 return proc
24
25 def run(self, cmd, timeout=None):
26 """Run cmd and get it's return code and output.
27 Let it run for timeout seconds and then terminate/kill it,
28 if time is 0 will let cmd run until it finishes.
29 Time can be passed to here or can be set per class instance."""
30
31
32
33 actualcmd = "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -l root %s '%s'" % (self.host, cmd)
34 if self.host:
35 sshconn = self._internal_run(actualcmd)
36 else:
37 raise Exception("Remote IP hasn't been set: '%s'" % actualcmd)
38
39 if timeout == 0:
40 self.log("[SSH run without timeout]$ %s" % actualcmd)
41 self.log(" # %s" % cmd)
42 self._out = sshconn.communicate()[0]
43 self._ret = sshconn.poll()
44 else:
45 if timeout is None:
46 endtime = time.time() + self.timeout
47 else:
48 endtime = time.time() + timeout
49 while sshconn.poll() is None and time.time() < endtime:
50 time.sleep(1)
51 self.log("[SSH run with timeout]$ %s" % actualcmd)
52 self.log(" # %s" % cmd)
53 # process hasn't returned yet
54 if sshconn.poll() is None:
55 self._ret = 255
56 sshconn.terminate()
57 sshconn.kill()
58 self._out = sshconn.stdout.read()
59 sshconn.stdout.close()
60 self.log("[!!! process killed]")
61 else:
62 self._out = sshconn.stdout.read()
63 self._ret = sshconn.poll()
64 # remove first line from output which is always smth like (unless return code is 255 - which is a ssh error):
65 # Warning: Permanently added '192.168.7.2' (RSA) to the list of known hosts.
66 if self._ret != 255:
67 self._out = '\n'.join(self._out.splitlines()[1:])
68 self.log("%s" % self._out)
69 self.log("[SSH command returned]: %s" % self._ret)
70 return (self._ret, self._out)
71
72 def _internal_scp(self, cmd):
73 self.log("[SCP]$ %s" % cmd)
74 scpconn = self._internal_run(cmd)
75 try:
76 self._out = scpconn.communicate()[0]
77 self._ret = scpconn.poll()
78 if self._ret != 0:
79 self.log("%s" % self._out)
80 raise Exception("Error copying file")
81 except Exception as e:
82 print("Execution failed: %s :" % cmd)
83 print e
84 self.log("%s" % self._out)
85 return (self._ret, self._out)
86
87 def copy_to(self, localpath, remotepath):
88 actualcmd = "scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no %s root@%s:%s" % (localpath, self.host, remotepath)
89 return self._internal_scp(actualcmd)
90
91
92 def copy_from(self, remotepath, localpath):
93 actualcmd = "scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@%s:%s %s" % (self.host, remotepath, localpath)
94 return self._internal_scp(actualcmd)
95
96 def get_status(self):
97 return self._ret
98
99 def get_output(self):
100 return self._out