#!/usr/bin/python
#
# rhos-log-collector
#   run and collect support reports on each OpenStack hosts in parallel
#   list of OpenStack hosts can be extracted from Packstack answer file
#   or provided in PSSH hosts file format, see pssh(1).

import ConfigParser
import subprocess
import sys
import uuid

from optparse import OptionParser

def get_hosts(answer_file):
    """Return the list of OpenStack hosts from Packstack answer file."""
    # based on packstack/modules/ospluginutils.py gethostlist(CONF)
    conf = ConfigParser.ConfigParser()
    conf.read(answer_file)
    hosts = []
    for name, value in conf.items('general'):
        if name.endswith("_host"):
            value = value.split('/')[0]
            if value and value not in hosts:
                hosts.append(value)
        elif name.endswith("_hosts"):
            for host in value.split(","):
                host = host.strip()
                host = host.split('/')[0]
                if host and host not in hosts:
                    hosts.append(host)
    return hosts

def pssh(opts, remote_cmd):
    """Execute remote_cmd on multiple hosts using pssh."""
    cmd = ["pssh", "-i", "-t", "0"]
    cmd.extend(opts)
    cmd.append(remote_cmd)
    return subprocess.call(cmd)

def pslurp(opts, remote_dir, local_dir):
    """Copy remote_dir folder recursively from multiple machines using pslurp."""
    cmd = ["pslurp", "-t", "0", "-r"]
    cmd.extend(opts)
    cmd.append(remote_dir)
    cmd.append(local_dir)
    return subprocess.call(cmd)

opts = OptionParser("usage: %prog [--answer-file=PACKSTACK-ANSWER_FILE] [--hosts=PSSH-HOSTS-FILE]")
opts.add_option("--answer-file", help="Packstack answer file to extract OpenStack hosts to get support report from")
opts.add_option("--hosts", help="PSSH hosts file (each line [user@]host[:port])")

(options, args) = opts.parse_args()
if options.answer_file:
    hosts = get_hosts(options.answer_file)
    hosts_opt = []
    for host in hosts:
        hosts_opt.append("-H")
        hosts_opt.append("root@%s" % host)
elif options.hosts:
    hosts_opt = ["-h", options.hosts]
else:
    opts.print_usage()
    raise SystemExit

# remote /tmp may be tmpfs, use generated uuid-folder in homedir instead
tmpdir="sos-%s" % str(uuid.uuid1())
if pssh(hosts_opt, "sosreport --tmp-dir ~/%s" % tmpdir) == 0:
    pslurp(hosts_opt, tmpdir, tmpdir)
    print "Support reports from all hosts are saved in %s" % tmpdir
else:
    print "%s failed." % sys.argv[0]
    raise SystemExit
