[2495] | 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, )) |
---|