-
Notifications
You must be signed in to change notification settings - Fork 5
/
globals.py
177 lines (142 loc) · 4.56 KB
/
globals.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import logging
import random
import sys
import subprocess
import time
try:
from termcolor import colored
except:
def colored(txt, color): return txt
FUNCTION_REGISTRY = {}
def register_fn(name, fn):
global FUNCTION_REGISTRY
FUNCTION_REGISTRY[name] = fn
KILL_PROCS = [
"iokerneld", "cstate", "memcached", "x264",
"swaptions", "mpstat", "rstat", "go", "stress",
"storage_server", "silo"
]
LOGGER = logging.getLogger('experiment')
logging.basicConfig(format='%(asctime)s: %(message)s', level=logging.INFO)
def _reset_log():
import sys
for handler in LOGGER.handlers[:]: LOGGER.removeHandler(handler)
sh = logging.StreamHandler(sys.stdout)
LOGGER.addHandler(sh)
def INITLOGGING(exp):
_reset_log()
_hostname = subprocess.check_output("hostname -s", shell=True).strip().decode('utf-8')
fh = logging.FileHandler('{}/pylog.{}.log'.format(exp['name'], _hostname))
fh.setLevel(logging.DEBUG)
LOGGER.addHandler(fh)
NETPFX = "0.0.0"
EXP_BASE = "./"
SHELL = "/bin/bash"
def mask_to_list(mask):
i = 0
l = []
while mask:
if mask & 1: l.append(i)
mask >>= 1
i += 1
return l
def list_to_mask(l):
i = 0
for w in l:
i |= 1 << w
return i
def core_list(r):
return ",".join(map(str, r))
def set_pfx(netpfx):
global NETPFX
NETPFX = netpfx
def IP(node):
assert node > 0 and node < 255
return "{}.{}".format(NETPFX, node)
def gen_random_mac():
return ":".join(["02"] + ["%02x" % random.randint(0, 255) for i in range(5)])
def _runcmd(cmdstr, outp, suppress=False, **kwargs):
kwargs['executable'] = kwargs.get("executable", SHELL)
kwargs['cwd'] = kwargs.get('cwd', EXP_BASE)
pfn = LOGGER.debug if True or suppress else LOGGER.info
if outp:
pfn("running {%s}: " % cmdstr)
res = subprocess.check_output(cmdstr, shell=True, **kwargs)
# pfn("%s\n" % res.strip())
return res
else:
p = subprocess.Popen(cmdstr, shell=True,
stdin=subprocess.PIPE, **kwargs)
LOGGER.info("[%04d]: launched {%s}" % (p.pid, cmdstr))
return p
def launch(*args, **kwargs):
assert 'outp' not in kwargs
assert len(args) == 1
return _runcmd(args[0], False, **kwargs)
def runcmd(*args, **kwargs):
assert 'outp' not in kwargs
assert len(args) == 1
return _runcmd(args[0], True, **kwargs)
def launch_para(cmd, inputs, die_on_failure=True, **kwargs):
fail = "--halt now,success=1" if die_on_failure else ""
cmd = "PARALLEL_SHELL={} parallel -j {} {} \"{}\" ::: {}".format(SHELL, len(inputs), fail, cmd, " ".join(inputs))
return launch(cmd, **kwargs)
def runpara(cmd, inputs, die_on_failure=False, **kwargs):
fail = "--halt now,success=1" if die_on_failure else ""
cmd = "PARALLEL_SHELL={} parallel -j {} {} \"{}\" ::: {}".format(SHELL, len(inputs), fail, cmd, " ".join(inputs))
return runcmd(cmd, **kwargs)
def runremote(cmd, hosts, **kwargs):
return runpara("ssh -t -t {{}} '{cmd}'".format(cmd=cmd), hosts, **kwargs)
def launchremote(cmd, hosts, **kwargs):
return launch_para("ssh -t -t {{}} '{cmd}'".format(cmd=cmd), hosts, **kwargs)
def poll_procs(*l, **kwargs):
assert len(l) > 0
done = kwargs.get('done', False)
ret = None
while True:
for p in l:
if p.poll() != None:
txt = "[%04d] is done, ret = %d" % (p.pid, p.returncode)
ret = p.returncode
if p.returncode != 0:
LOGGER.error(txt)
else:
LOGGER.info(txt)
done = True
if not done: time.sleep(2)
else: break
return ret
def except_none(func):
def e(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
return None
return e
@except_none
def kill_single(pid):
runcmd("sudo kill -SIGINT %d 2> /dev/null" % pid, suppress=True)
def get_kids_list(pid):
lns = runcmd("ps -o pid --ppid %d --noheaders || true" % pid, suppress=True).splitlines()
if lns: lns = map(int, lns)
return lns
def kill_pid_and_kids(pid):
kids = get_kids_list(pid)
if kids:
for i in kids:
kill_pid_and_kids(i)
kill_single(pid)
def get_pid_tree_set(pid):
kids = get_kids_list(pid)
desc = set([pid])
if kids:
desc |= set(kids)
for i in kids:
desc |= get_pid_tree_set(i)
return desc
def kill_proc(proc):
kill_pid_and_kids(proc.pid)
# mark script changes that need to be reverted
def expires(*args):
from datetime import datetime
assert datetime.now() < datetime(*args)