#!/usr/bin/python
#
# Parses arguments provided by libvirt to qemu-system-arm,
# removing bad ones (unsupported devices) and rewriting others
# (network interfaces and disks) to let qemu-system-arm
# start nicely.
#
# Debug: create the file /tmp/qemu-system-arm-wrapper
# with mode 666; original arguments and modified ones
# will be printed there.
#
# Tested on Debian Squeeze, libvirt 0.8.3-5 and qemu 0.12.5.
#
# Author:	Niccolo Rigacci <niccolo@rigacci.org>
#

import os, sys

qemu_system_arm = "/usr/bin/qemu-system-arm"
passthrough_switches = ['-S', '-usb', '-nodefaults', '-help']
passthrough_args = ['-M', '-m', '-smp', '-name', '-uuid', '-mon', '-rtc',
                    '-boot', '-kernel', '-initrd', '-append', '-vnc', '-vga']

# Print arguments vector.
def print_argv(argv):
    try:
        f = open("/tmp/qemu-system-arm-wrapper", "a")
        f.write(" ".join(argv) + "\n")
        f.close()
    except:
        pass

# Split a string like "socket,id=monitor,server,nowait" into a
# dictionary: {"socket": None, "id": "monitor", "server": None, "nowait": None}"
def split_key_list(value):
    a = {}
    keys = value.split(",")
    for key in keys:
        pair = key.split("=")
        if len(pair) > 1:
            a[pair[0]] = pair[1]
        else:
            a[pair[0]] = None
    return a

# Parse: -chardev socket,id=monitor,...
def parse_chardev(value):
    options = split_key_list(value)
    if "id" in options.keys():
        if options["id"] == "monitor":
            return ["-chardev", value]
    if "null" in options.keys(): return None
    return ["-chardev", value]

# Parse: -drive file=...
def parse_drive(value):
    options = split_key_list(value)
    if "file" in options.keys():
        return ["-hda", options["file"]]
    return None

# Parse: -device virtio-net-pci,vlan=0,id=net0,mac=52:54:00:00:03:72,...
def parse_device(value):
    options = split_key_list(value)
    if "virtio-net-pci" in options.keys():
        new_value = "nic"
        if "vlan" in options.keys(): new_value += ",vlan="    + options["vlan"]
        if "mac"  in options.keys(): new_value += ",macaddr=" + options["mac"]
        return ["-net", new_value]
    if "lsi"                in options.keys(): return None
    if "scsi-disk"          in options.keys(): return None
    if "isa-serial"         in options.keys(): return None
    if "virtio-balloon-pci" in options.keys(): return None
    return ["-device", value]

# Parse: -net tap,...
def parse_net(value):
    options = split_key_list(value)
    if "tap" in options.keys():
        return ["-net", value]
    return None

#---------------------------------------------------------------
# Main program.
#---------------------------------------------------------------
print_argv(sys.argv)
new_argv = [qemu_system_arm]
for i in range(1, len(sys.argv)):
    arg = sys.argv[i]
    if arg in passthrough_switches:
        new_argv.append(arg)
    if arg in passthrough_args:
        new_argv.append(arg)
        i += 1
        new_argv.append(sys.argv[i])
    if arg == '-chardev':
        i += 1
        new_value = parse_chardev(sys.argv[i])
        if new_value != None: new_argv.extend(new_value)
    if arg == '-drive':
        i += 1
        new_value = parse_drive(sys.argv[i])
        if new_value != None: new_argv.extend(new_value)
    if arg == '-device':
        i += 1
        new_value = parse_device(sys.argv[i])
        if new_value != None: new_argv.extend(new_value)
    if arg == '-net':
        i += 1
        new_value = parse_net(sys.argv[i])
        if new_value != None: new_argv.extend(new_value)

print_argv(new_argv)
os.execv(qemu_system_arm, new_argv)