#!/usr/bin/python

# QEMU Guest Agent Client
#
# Copyright (C) 2012 Ryota Ozaki <ozaki.ryota@gmail.com>
#
# This work is licensed under the terms of the GNU GPL, version 2.  See
# the COPYING file in the top-level directory.
#
# Usage:
#
# Start QEMU with:
#
# # qemu [...] -chardev socket,path=/tmp/qga.sock,server,nowait,id=qga0 \
#   -device virtio-serial -device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0
#
# Run the script:
#
# $ qemu-ga-client --address=/tmp/qga.sock <command> [args...]
#
# or
#
# $ export QGA_CLIENT_ADDRESS=/tmp/qga.sock
# $ qemu-ga-client <command> [args...]
#
# For example:
#
# $ qemu-ga-client cat /etc/resolv.conf
# # Generated by NetworkManager
# nameserver 10.0.2.3
# $ qemu-ga-client fsfreeze status
# thawed
# $ qemu-ga-client fsfreeze freeze
# 2 filesystems frozen
#
# See also: http://wiki.qemu-project.org/Features/QAPI/GuestAgent
#

import base64
import random

import qmp


class QemuGuestAgent(qmp.QEMUMonitorProtocol):
    def __getattr__(self, name):
        def wrapper(**kwds):
            return self.command('guest-' + name.replace('_', '-'), **kwds)
        return wrapper


class QemuGuestAgentClient:
    error = QemuGuestAgent.error

    def __init__(self, address):
        self.qga = QemuGuestAgent(address)
        self.qga.connect(negotiate=False)

    def sync(self, timeout=3):
        # Avoid being blocked forever
        if not self.ping(timeout):
            raise EnvironmentError('Agent seems not alive')
        uid = random.randint(0, (1 << 32) - 1)
        while True:
            ret = self.qga.sync(id=uid)
            if isinstance(ret, int) and int(ret) == uid:
                break

    def __file_read_all(self, handle):
        eof = False
        data = ''
        while not eof:
            ret = self.qga.file_read(handle=handle, count=1024)
            _data = base64.b64decode(ret['buf-b64'])
            data += _data
            eof = ret['eof']
        return data

    def read(self, path):
        handle = self.qga.file_open(path=path)
        try:
            data = self.__file_read_all(handle)
        finally:
            self.qga.file_close(handle=handle)
        return data

    def info(self):
        info = self.qga.info()

        msgs = []
        msgs.append('version: ' + info['version'])
        msgs.append('supported_commands:')
        enabled = [c['name'] for c in info['supported_commands'] if c['enabled']]
        msgs.append('\tenabled: ' + ', '.join(enabled))
        disabled = [c['name'] for c in info['supported_commands'] if not c['enabled']]
        msgs.append('\tdisabled: ' + ', '.join(disabled))

        return '\n'.join(msgs)

    def __gen_ipv4_netmask(self, prefixlen):
        mask = int('1' * prefixlen + '0' * (32 - prefixlen), 2)
        return '.'.join([str(mask >> 24),
                         str((mask >> 16) & 0xff),
                         str((mask >> 8) & 0xff),
                         str(mask & 0xff)])

    def ifconfig(self):
        nifs = self.qga.network_get_interfaces()

        msgs = []
        for nif in nifs:
            msgs.append(nif['name'] + ':')
            if 'ip-addresses' in nif:
                for ipaddr in nif['ip-addresses']:
                    if ipaddr['ip-address-type'] == 'ipv4':
                        addr = ipaddr['ip-address']
                        mask = self.__gen_ipv4_netmask(int(ipaddr['prefix']))
                        msgs.append("\tinet %s  netmask %s" % (addr, mask))
                    elif ipaddr['ip-address-type'] == 'ipv6':
                        addr = ipaddr['ip-address']
                        prefix = ipaddr['prefix']
                        msgs.append("\tinet6 %s  prefixlen %s" % (addr, prefix))
            if nif['hardware-address'] != '00:00:00:00:00:00':
                msgs.append("\tether " + nif['hardware-address'])

        return '\n'.join(msgs)

    def ping(self, timeout):
        self.qga.settimeout(timeout)
        try:
            self.qga.ping()
        except self.qga.timeout:
            return False
        return True

    def fsfreeze(self, cmd):
        if cmd not in ['status', 'freeze', 'thaw']:
            raise StandardError('Invalid command: ' + cmd)

        return getattr(self.qga, 'fsfreeze' + '_' + cmd)()

    def fstrim(self, minimum=0):
        return getattr(self.qga, 'fstrim')(minimum=minimum)

    def suspend(self, mode):
        if mode not in ['disk', 'ram', 'hybrid']:
            raise StandardError('Invalid mode: ' + mode)

        try:
            getattr(self.qga, 'suspend' + '_' + mode)()
            # On error exception will raise
        except self.qga.timeout:
            # On success command will timed out
            return

    def shutdown(self, mode='powerdown'):
        if mode not in ['powerdown', 'halt', 'reboot']:
            raise StandardError('Invalid mode: ' + mode)

        try:
            self.qga.shutdown(mode=mode)
        except self.qga.timeout:
            return


def _cmd_cat(client, args):
    if len(args) != 1:
        print('Invalid argument')
        print('Usage: cat <file>')
        sys.exit(1)
    print(client.read(args[0]))


def _cmd_fsfreeze(client, args):
    usage = 'Usage: fsfreeze status|freeze|thaw'
    if len(args) != 1:
        print('Invalid argument')
        print(usage)
        sys.exit(1)
    if args[0] not in ['status', 'freeze', 'thaw']:
        print('Invalid command: ' + args[0])
        print(usage)
        sys.exit(1)
    cmd = args[0]
    ret = client.fsfreeze(cmd)
    if cmd == 'status':
        print(ret)
    elif cmd == 'freeze':
        print("%d filesystems frozen" % ret)
    else:
        print("%d filesystems thawed" % ret)


def _cmd_fstrim(client, args):
    if len(args) == 0:
        minimum = 0
    else:
        minimum = int(args[0])
    print(client.fstrim(minimum))


def _cmd_ifconfig(client, args):
    print(client.ifconfig())


def _cmd_info(client, args):
    print(client.info())


def _cmd_ping(client, args):
    if len(args) == 0:
        timeout = 3
    else:
        timeout = float(args[0])
    alive = client.ping(timeout)
    if not alive:
        print("Not responded in %s sec" % args[0])
        sys.exit(1)


def _cmd_suspend(client, args):
    usage = 'Usage: suspend disk|ram|hybrid'
    if len(args) != 1:
        print('Less argument')
        print(usage)
        sys.exit(1)
    if args[0] not in ['disk', 'ram', 'hybrid']:
        print('Invalid command: ' + args[0])
        print(usage)
        sys.exit(1)
    client.suspend(args[0])


def _cmd_shutdown(client, args):
    client.shutdown()
_cmd_powerdown = _cmd_shutdown


def _cmd_halt(client, args):
    client.shutdown('halt')


def _cmd_reboot(client, args):
    client.shutdown('reboot')


commands = [m.replace('_cmd_', '') for m in dir() if '_cmd_' in m]


def main(address, cmd, args):
    if not os.path.exists(address):
        print('%s not found' % address)
        sys.exit(1)

    if cmd not in commands:
        print('Invalid command: ' + cmd)
        print('Available commands: ' + ', '.join(commands))
        sys.exit(1)

    try:
        client = QemuGuestAgentClient(address)
    except QemuGuestAgent.error, e:
        import errno

        print(e)
        if e.errno == errno.ECONNREFUSED:
            print('Hint: qemu is not running?')
        sys.exit(1)

    if cmd == 'fsfreeze' and args[0] == 'freeze':
        client.sync(60)
    elif cmd != 'ping':
        client.sync()

    globals()['_cmd_' + cmd](client, args)


if __name__ == '__main__':
    import sys
    import os
    import optparse

    address = os.environ['QGA_CLIENT_ADDRESS'] if 'QGA_CLIENT_ADDRESS' in os.environ else None

    usage = "%prog [--address=<unix_path>|<ipv4_address>] <command> [args...]\n"
    usage += '<command>: ' + ', '.join(commands)
    parser = optparse.OptionParser(usage=usage)
    parser.add_option('--address', action='store', type='string',
                      default=address, help='Specify a ip:port pair or a unix socket path')
    options, args = parser.parse_args()

    address = options.address
    if address is None:
        parser.error('address is not specified')
        sys.exit(1)

    if len(args) == 0:
        parser.error('Less argument')
        sys.exit(1)

    main(address, args[0], args[1:])
