blob: 11b38ae359a34683f02e4b469cc0c313157d8160 [file] [log] [blame]
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08001import time
koder aka kdanilov4ec0f712015-02-19 19:19:27 -08002import socket
koder aka kdanilove21d7472015-02-14 19:02:04 -08003import logging
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08004import threading
5import contextlib
koder aka kdanilov4643fd62015-02-10 16:20:13 -08006
koder aka kdanilove21d7472015-02-14 19:02:04 -08007
8logger = logging.getLogger("io-perf-tool")
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -08009
10
koder aka kdanilove06762a2015-03-22 23:32:09 +020011def parse_creds(creds):
12 # parse user:passwd@host
13 user, passwd_host = creds.split(":", 1)
14
15 if '@' not in passwd_host:
16 passwd, host = passwd_host, None
17 else:
18 passwd, host = passwd_host.rsplit('@', 1)
19
20 return user, passwd, host
21
22
koder aka kdanilov2c473092015-03-29 17:12:13 +030023class TaksFinished(Exception):
24 pass
koder aka kdanilov4643fd62015-02-10 16:20:13 -080025
koder aka kdanilov2c473092015-03-29 17:12:13 +030026
27class Barrier(object):
28 def __init__(self, count):
29 self.count = count
30 self.curr_count = 0
31 self.cond = threading.Condition()
32 self.exited = False
33
34 def wait(self, timeout=None):
35 with self.cond:
36 if self.exited:
37 raise TaksFinished()
38
39 self.curr_count += 1
40 if self.curr_count == self.count:
41 self.curr_count = 0
42 self.cond.notify_all()
koder aka kdanilov4643fd62015-02-10 16:20:13 -080043 else:
koder aka kdanilov2c473092015-03-29 17:12:13 +030044 self.cond.wait(timeout=timeout)
koder aka kdanilov4643fd62015-02-10 16:20:13 -080045
koder aka kdanilov2c473092015-03-29 17:12:13 +030046 def exit(self):
47 with self.cond:
48 self.exited = True
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080049
50
51@contextlib.contextmanager
52def log_error(action, types=(Exception,)):
53 if not action.startswith("!"):
koder aka kdanilove21d7472015-02-14 19:02:04 -080054 logger.debug("Starts : " + action)
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080055 else:
56 action = action[1:]
57
58 try:
59 yield
60 except Exception as exc:
61 if isinstance(exc, types) and not isinstance(exc, StopIteration):
62 templ = "Error during {0} stage: {1}"
koder aka kdanilove21d7472015-02-14 19:02:04 -080063 logger.debug(templ.format(action, exc.message))
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080064 raise
65
66
koder aka kdanilov66839a92015-04-11 13:22:31 +030067def run_over_ssh(conn, cmd, stdin_data=None, exec_timeout=5 * 60 * 60):
koder aka kdanilov7acd6bd2015-02-12 14:28:30 -080068 "should be replaces by normal implementation, with select"
koder aka kdanilov2c473092015-03-29 17:12:13 +030069 transport = conn.get_transport()
70 session = transport.open_session()
koder aka kdanilov83cd7132015-02-14 21:37:14 -080071 try:
koder aka kdanilov2c473092015-03-29 17:12:13 +030072 session.set_combine_stderr(True)
koder aka kdanilov83cd7132015-02-14 21:37:14 -080073
koder aka kdanilov2c473092015-03-29 17:12:13 +030074 stime = time.time()
75 session.exec_command(cmd)
koder aka kdanilov83cd7132015-02-14 21:37:14 -080076
koder aka kdanilov2c473092015-03-29 17:12:13 +030077 if stdin_data is not None:
78 session.sendall(stdin_data)
koder aka kdanilov83cd7132015-02-14 21:37:14 -080079
koder aka kdanilov2c473092015-03-29 17:12:13 +030080 session.settimeout(1)
81 session.shutdown_write()
82 output = ""
83
84 while True:
85 try:
86 ndata = session.recv(1024)
87 output += ndata
88 if "" == ndata:
89 break
90 except socket.timeout:
91 pass
koder aka kdanilov66839a92015-04-11 13:22:31 +030092
koder aka kdanilov2c473092015-03-29 17:12:13 +030093 if time.time() - stime > exec_timeout:
koder aka kdanilov66839a92015-04-11 13:22:31 +030094 raise OSError(output + "\nExecution timeout")
95
koder aka kdanilov2c473092015-03-29 17:12:13 +030096 code = session.recv_exit_status()
97 finally:
98 session.close()
99
koder aka kdanilov66839a92015-04-11 13:22:31 +0300100 if code != 0:
101 templ = "Cmd {0!r} failed with code {1}. Output: {2}"
102 raise OSError(templ.format(cmd, code, output))
103
104 return output
koder aka kdanilov2c473092015-03-29 17:12:13 +0300105
106
107SMAP = dict(k=1024, m=1024 ** 2, g=1024 ** 3, t=1024 ** 4)
koder aka kdanilov8ad6e812015-03-22 14:42:18 +0200108
109
110def ssize_to_b(ssize):
111 try:
koder aka kdanilov2c473092015-03-29 17:12:13 +0300112 ssize = ssize.lower()
koder aka kdanilov8ad6e812015-03-22 14:42:18 +0200113
koder aka kdanilov2c473092015-03-29 17:12:13 +0300114 if ssize.endswith("b"):
115 ssize = ssize[:-1]
116 if ssize[-1] in SMAP:
117 return int(ssize[:-1]) * SMAP[ssize[-1]]
koder aka kdanilov8ad6e812015-03-22 14:42:18 +0200118 return int(ssize)
119 except (ValueError, TypeError, AttributeError):
koder aka kdanilov2e928022015-04-08 13:47:15 +0300120 raise ValueError("Unknow size format {0!r}".format(ssize))