]>
Commit | Line | Data |
---|---|---|
2fa26715 JD |
1 | # Host class |
2 | # Copyright (c) 2016, Qualcomm Atheros, Inc. | |
3 | # | |
4 | # This software may be distributed under the terms of the BSD license. | |
5 | # See README for more details. | |
6 | ||
7 | import logging | |
8 | import subprocess | |
9 | import threading | |
10 | ||
11 | logger = logging.getLogger() | |
12 | ||
5aa751ea JA |
13 | def remote_compatible(func): |
14 | func.remote_compatible = True | |
15 | return func | |
16 | ||
2fa26715 | 17 | def execute_thread(command, reply): |
6a003eb2 JD |
18 | cmd = ' '.join(command) |
19 | logger.debug("thread run: " + cmd) | |
2fa26715 | 20 | try: |
bc6e3288 | 21 | status = 0 |
d5e6ffd6 | 22 | buf = subprocess.check_output(command, stderr=subprocess.STDOUT).decode() |
2fa26715 JD |
23 | except subprocess.CalledProcessError as e: |
24 | status = e.returncode | |
25 | buf = e.output | |
26 | ||
2fa26715 JD |
27 | logger.debug("thread cmd: " + cmd) |
28 | logger.debug("thread exit status: " + str(status)) | |
29 | logger.debug("thread exit buf: " + str(buf)) | |
30 | reply.append(status) | |
31 | reply.append(buf) | |
32 | ||
33 | class Host(): | |
34 | def __init__(self, host=None, ifname=None, port=None, name="", user="root"): | |
35 | self.host = host | |
36 | self.name = name | |
37 | self.user = user | |
ede47197 JD |
38 | self.monitors = [] |
39 | self.monitor_thread = None | |
40 | self.logs = [] | |
2fa26715 JD |
41 | self.ifname = ifname |
42 | self.port = port | |
a73fa13b | 43 | self.dev = None |
2fa26715 JD |
44 | if self.name == "" and host != None: |
45 | self.name = host | |
46 | ||
47 | def local_execute(self, command): | |
5a766acc | 48 | logger.debug("execute: " + str(command)) |
2fa26715 | 49 | try: |
bc6e3288 | 50 | status = 0 |
5a766acc | 51 | buf = subprocess.check_output(command, stderr=subprocess.STDOUT) |
2fa26715 JD |
52 | except subprocess.CalledProcessError as e: |
53 | status = e.returncode | |
54 | buf = e.output | |
55 | ||
56 | logger.debug("status: " + str(status)) | |
57 | logger.debug("buf: " + str(buf)) | |
45b0b88f | 58 | return status, buf.decode() |
2fa26715 JD |
59 | |
60 | def execute(self, command): | |
61 | if self.host is None: | |
62 | return self.local_execute(command) | |
63 | ||
5a766acc | 64 | cmd = ["ssh", self.user + "@" + self.host, ' '.join(command)] |
6a003eb2 | 65 | _cmd = self.name + " execute: " + ' '.join(cmd) |
2fa26715 JD |
66 | logger.debug(_cmd) |
67 | try: | |
68 | status = 0 | |
69 | buf = subprocess.check_output(cmd, stderr=subprocess.STDOUT) | |
70 | except subprocess.CalledProcessError as e: | |
71 | status = e.returncode | |
72 | buf = e.output | |
73 | ||
74 | logger.debug(self.name + " status: " + str(status)) | |
75 | logger.debug(self.name + " buf: " + str(buf)) | |
45b0b88f | 76 | return status, buf.decode() |
2fa26715 JD |
77 | |
78 | # async execute | |
79 | def execute_run(self, command, res): | |
80 | if self.host is None: | |
5a766acc | 81 | cmd = command |
2fa26715 | 82 | else: |
fab49f61 | 83 | cmd = ["ssh", self.user + "@" + self.host, ' '.join(command)] |
6a003eb2 | 84 | _cmd = self.name + " execute_run: " + ' '.join(cmd) |
2fa26715 | 85 | logger.debug(_cmd) |
fab49f61 | 86 | t = threading.Thread(target=execute_thread, args=(cmd, res)) |
2fa26715 JD |
87 | t.start() |
88 | return t | |
89 | ||
90 | def wait_execute_complete(self, t, wait=None): | |
91 | if wait == None: | |
92 | wait_str = "infinite" | |
93 | else: | |
94 | wait_str = str(wait) + "s" | |
95 | ||
96 | logger.debug(self.name + " wait_execute_complete(" + wait_str + "): ") | |
97 | if t.isAlive(): | |
98 | t.join(wait) | |
ede47197 | 99 | |
04fd8ea1 JA |
100 | def add_log(self, log_file): |
101 | self.logs.append(log_file) | |
102 | ||
ede47197 JD |
103 | def get_logs(self, local_log_dir=None): |
104 | for log in self.logs: | |
105 | if local_log_dir: | |
106 | self.local_execute(["scp", self.user + "@[" + self.host + "]:" + log, local_log_dir]) | |
107 | self.execute(["rm", log]) | |
108 | del self.logs[:] |