#! /usr/bin/python3

"""
List all the Resalloc Pool-related LibVirt domains that are either (a) still
defined/running, or (b) have some resource (e.g. storage) still available in the
LibVirt hypervisor.
"""

import os
import re
import argparse
import sys
import libvirt
from helpers import get_hv_identification_from_pool_id


def _get_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument("--connection", required=False)
    parser.add_argument("--pool", required=False)
    return parser

def _main():
    args = _get_parser().parse_args()

    pool_id = args.pool or os.getenv("RESALLOC_POOL_ID")
    if not pool_id:
        sys.stderr.write("Specify pool ID by --pool or $RESALLOC_POOL_ID\n")
        sys.exit(1)

    connection = args.connection if args.connection else \
        get_hv_identification_from_pool_id(pool_id)[1]

    try:
        conn = libvirt.openReadOnly(connection)
    except libvirt.libvirtError:
        sys.stderr.write('Failed to open connection to the hypervisor\n')
        sys.exit(1)

    # Gather the list of all domains here
    vm_names = set()

    # Some of those are used by Red Hat Copr
    known_suffixes = ["_root_disk$", "_config_cd$", "_swap$", "_root$", "_config$"]
    known_pools = ["images", "swap-space"]

    for pool in conn.listAllStoragePools():
        # List all the volumes in the volume pool that seem to be related to
        # the given Pool name
        if pool.name() not in known_pools:
            continue

        for volume in pool.listVolumes():
            if volume.startswith(pool_id):
                for suffix in known_suffixes:
                    volume = re.sub(suffix, "", volume)
                vm_names.add(volume)

        # List all domains that are related to given Pool (just to be 100% sure, but
        # this shouldn't add any new items to the vm_names set actually).
        for domain in conn.listAllDomains():
            name = domain.name()
            if name.startswith(pool_id):
                vm_names.add(name)

    # Print them out, so upper level tooling can work with the list.  See:
    # roles/copr/backend/files/provision/libvirt-list
    for name in vm_names:
        # The only stdout output comes here!
        print(name)

if __name__ == "__main__":
    _main()
