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, hostnames = 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):
        hostnames = random.sample(hostnames, len(hostnames))
    hostsdown = []
    for host in hostnames:
        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:
                return (host, hostsdown, pipe.returncode,) + output
        else:
            return (host, hostsdown, pipe.returncode,) + output
    raise RuntimeError("Failed to contact any hosts: tried %s" % (hostsdown, ))
