Balance LVM requests (LP: #307361)
[invirt/packages/invirt-remote.git] / python / remote / monocast.py
diff --git a/python/remote/monocast.py b/python/remote/monocast.py
new file mode 100644 (file)
index 0000000..1b39b57
--- /dev/null
@@ -0,0 +1,34 @@
+from subprocess import PIPE, Popen
+from invirt.config import structs as config
+import random
+
+hostnames = [ h.hostname for h in config.hosts ]
+
+def monocast(args, hosts = hostnames, randomize = True):
+    """
+    Given a command and a list of hostnames or IPs, issue the command to each
+    node until it connects to one of the nodes.
+
+    Returns:
+        host the command ran on
+        hosts that could not be contacted
+        returncode of remctl
+        stdout of remctl
+        stderr of remctl
+    """
+    if(randomize):
+        hosts = random.sample(hosts, len(hosts))
+    hostsdown = []
+    for host in hosts:
+        pipe = Popen(['remctl', host, 'remote', 'web'] + args, stdout=PIPE, stderr=PIPE)
+        output = pipe.communicate()
+        if pipe.returncode != 0:
+            if output[1].startswith('remctl: cannot connect to %s' % host):
+                hostsdown.append(host)
+            else:
+                #raise RuntimeError("remctl to host %s returned non-zero exit status %d; stderr:\n%s"
+                #                   % (host, pipe.returncode, output[1]))
+                return (host, hostsdown, pipe.returncode,) + output
+        else:
+            return (host, hostsdown, pipe.returncode,) + output
+    raise RuntimeError("Failed to contact any hosts: tried %s" % (hostsdown, ))