#! /usr/bin/python3

"""
Obtain ipv4 address from a given domain; using qemu agent.
"""

# Copyright (C) 2021 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import logging
import subprocess
import sys

import libvirt

logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger()

if len(sys.argv) != 2:
    print("one argument (domain name) expected")
    sys.exit(1)

conn = libvirt.open()

try:
    domain_name = sys.argv[1]
    log.info("using domain '%s'", domain_name)
    dom0 = conn.lookupByName(domain_name)
    interfaces = dom0.interfaceAddresses(libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT, 0)
except libvirt.libvirtError:
    sys.exit(1)


def _main():
    found = False
    found_ipv4 = False
    for interface in interfaces:
        log.debug("checking interface %s", interface)
        # F41 moved to enp1s0 from eth0
        if interface not in ['eth0', 'enp1s0', 'enp0s1', 'enc2']:
            log.debug("skipping interface %s", interface)
            continue

        found = True

        if 'addrs' not in interfaces[interface]:
            log.debug("addrs not in interface")
            break

        if not isinstance(interfaces[interface]['addrs'], list):
            log.debug("addrs is not a list")
            break

        for address in interfaces[interface]['addrs']:
            if address['type'] != libvirt.VIR_IP_ADDR_TYPE_IPV4:
                continue
            log.debug("addr for %s is %s", interface, address["addr"])

            log.debug("waiting for ssh for 120 seconds")
            process = subprocess.run(
                ["wait-for-ssh", "--log=debug", "--timeout=60", address['addr']],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )

            if process.returncode == 0:
                log.debug("ssh succeeded for %s", address['addr'])
                print(address['addr'])
                sys.exit(0)

            log.error("ssh failed for %s, reason: %s", address['addr'], process.stderr)

    if not found:
        log.error("interface found")

    if not found_ipv4:
        log.error("no ipv4 address (yet?)")

    sys.exit(1)


if __name__ == "__main__":
    _main()
