-
Notifications
You must be signed in to change notification settings - Fork 3
/
cnc_ssh.py
79 lines (71 loc) · 2.57 KB
/
cnc_ssh.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
from __future__ import print_function
import time
import subprocess
import select
class CncSsh(object):
def __init__(self, ssh_options=None):
self.ssh_options = ssh_options
def run(self, command, servers, timeout=1000, launch=False, captive=False):
procs = []
for i,server in enumerate(servers):
if '__INDEX__' in command:
cmd = command.replace('__INDEX__', str(i))
else:
cmd = command
cmd = "ssh %s %s '%s'" % (self.ssh_options or '', server, cmd)
print('Command:', cmd)
procs.append(subprocess.Popen(cmd, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT))
t0 = time.time()
returns = [None for s in servers]
outputs = ['' for s in servers]
while True:
alldone = True
for i,p in enumerate(procs):
if p is None:
continue
r = p.poll()
print('Server', i, 'returned:', r)
if r is None:
alldone = False
else:
returns[i] = r
outputs[i] += p.stdout.read() # + p.stderr.read()
procs[i] = None
if alldone:
break
# rlist = []
# rmap = {}
# for i,p in enumerate(procs):
# if p is None:
# continue
# rlist.append(procs[i].stdout)
# rmap[procs[i].stdout] = i
# rlist,nil,nil = select.select(rlist, [], [], 0.)
# for r in rlist:
# i = rmap[r]
# #print('Ready:', r, type(r))
# #data = r.read1(1024)
# data = r.read(1024)
# outputs[i] += data
# print('Read:', data)
dt = (time.time() - t0)*1000
print('Time taken:', dt, 'vs timeout', timeout)
if dt > timeout:
print('timeout')
break
time.sleep(1.)
rtn = []
for r,o in zip(returns, outputs):
if r is None:
rtn.append(None)
else:
rtn.append((r, o, ''))
return rtn
if __name__ == '__main__':
client = CncSsh()
servers = ['cf0g0', 'cf0g1', 'cf0g2']
command = 'echo "Hello from server __INDEX__, I am $(hostname)"; sleep 2; echo "Bye"'
res = client.run(command, servers, timeout=3000)
print('Results:', res)