#!/usr/bin/env python

import argparse
import os.path

import libvirt

templatedir = os.path.join(os.path.dirname(os.path.dirname(__file__)),
                           'templates')


CONSOLE_LOG = """
    <serial type='file'>
      <source path='%(console_log)s'/>
      <target port='0'/>
      <alias name='serial0'/>
    </serial>
    <serial type='pty'>
      <source path='/dev/pts/49'/>
      <target port='1'/>
      <alias name='serial1'/>
    </serial>
    <console type='file'>
      <source path='%(console_log)s'/>
      <target type='serial' port='0'/>
      <alias name='serial0'/>
    </console>
"""


def main():
    parser = argparse.ArgumentParser(
        description="Configure a kvm virtual machine for the seed image.")
    parser.add_argument('--name', default='seed',
                        help='the name to give the machine in libvirt.')
    parser.add_argument('--image',
                        help='Use a custom image file (must be qcow2).')
    parser.add_argument('--engine', default='qemu',
                        help='The virtualization engine to use')
    parser.add_argument('--arch', default='i686',
                        help='The architecture to use')
    parser.add_argument('--memory', default='2097152',
                        help="Maximum memory for the VM in KB.")
    parser.add_argument('--cpus', default='1',
                        help="CPU count for the VM.")
    parser.add_argument('--bootdev', default='hd',
                        help="What boot device to use (hd/network).")
    parser.add_argument('--network', default="brbm",
                        help='The libvirt network name to use')
    parser.add_argument('--libvirt-nic-driver', default='e1000',
                        help='The libvirt network driver to use')
    parser.add_argument('--console-log',
                        help='File to log console')
    parser.add_argument('--emulator', default=None,
                        help='Path to emulator bin for vm template')
    args = parser.parse_args()
    with file(templatedir + '/vm.xml', 'rb') as f:
        source_template = f.read()
    params = {
        'name': args.name,
        'imagefile': args.image,
        'engine': args.engine,
        'arch': args.arch,
        'memory': args.memory,
        'cpus': args.cpus,
        'bootdev': args.bootdev,
        'network': args.network,
        'nicdriver': args.libvirt_nic_driver,
        'emulator': args.emulator,
    }

    if args.emulator:
        params['emulator'] = args.emulator
    else:
        if os.path.exists("/usr/bin/kvm"):  # Debian
            params['emulator'] = "/usr/bin/kvm"
        elif os.path.exists("/usr/bin/qemu-kvm"):  # Redhat
            params['emulator'] = "/usr/bin/qemu-kvm"

    if args.console_log:
        params['bios_serial'] = "<bios useserial='yes'/>"
        params['console_log'] = CONSOLE_LOG % {'console_log': args.console_log}
    else:
        params['bios_serial'] = ''
        params['console_log'] = ''
    libvirt_template = source_template % params
    conn = libvirt.open("qemu:///system")

    a = conn.defineXML(libvirt_template)
    print ("Created machine %s with UUID %s" % (args.name, a.UUIDString()))

if __name__ == '__main__':
    main()
