1b39b57d598c71144c0d1eb7631c99f69fc53342
[invirt/packages/invirt-remote.git] / python / remote / monocast.py
1 from subprocess import PIPE, Popen
2 from invirt.config import structs as config
3 import random
4
5 hostnames = [ h.hostname for h in config.hosts ]
6
7 def monocast(args, hosts = hostnames, randomize = True):
8     """
9     Given a command and a list of hostnames or IPs, issue the command to each
10     node until it connects to one of the nodes.
11
12     Returns:
13         host the command ran on
14         hosts that could not be contacted
15         returncode of remctl
16         stdout of remctl
17         stderr of remctl
18     """
19     if(randomize):
20         hosts = random.sample(hosts, len(hosts))
21     hostsdown = []
22     for host in hosts:
23         pipe = Popen(['remctl', host, 'remote', 'web'] + args, stdout=PIPE, stderr=PIPE)
24         output = pipe.communicate()
25         if pipe.returncode != 0:
26             if output[1].startswith('remctl: cannot connect to %s' % host):
27                 hostsdown.append(host)
28             else:
29                 #raise RuntimeError("remctl to host %s returned non-zero exit status %d; stderr:\n%s"
30                 #                   % (host, pipe.returncode, output[1]))
31                 return (host, hostsdown, pipe.returncode,) + output
32         else:
33             return (host, hostsdown, pipe.returncode,) + output
34     raise RuntimeError("Failed to contact any hosts: tried %s" % (hostsdown, ))