#!/usr/bin/python3 import argparse import sys import time from VMHelper import VMHelper #### Constants ### CONFIG_FILENAME_DEFAULT = "/root/tmp/config.json" SHUTDOWN_TIMEOUT = 180 #### --------- ### helper = VMHelper(CONFIG_FILENAME_DEFAULT) stopStatusToMessage = { "send_powerdown" : "Sending ACPI poweroff Event.", "send_quit" : "Shoutdown has timed out! Quitting forcefully!", "kill_vm" : "Killing process!" } def vmm_list(args): print("Available VMs:") print() for vmid in helper.getVmIds(): s = "ID: {0} -- {1}" state = None if helper.process_running(vmid): state = helper.getQMPStatus(vmid)["status"] else : state = "stopped" print(s.format(vmid,state)) def vmm_start(args): if(helper.process_running(args.vmid)): print("VM {0} is already running!".format(args.vmid)) return print('Starting VM {0.vmid}.'.format(args)) helper.startVM(args.vmid) #print("Successfully started: " + ("yes" if helper.process_running(args.vmid) else "no")) def vmm_shutdown(args): timeout = SHUTDOWN_TIMEOUT if args.t is None or not args.t.isdigit() else int(args.t) stCallback = lambda vmid, st : print("VM {0}: {1}".format(vmid, stopStatusToMessage[st])) helper.shutdownVMs(timeout, args.s is None or args.s < 1, statusCallback=stCallback) def vmm_stop(args): if(not helper.process_running(args.vmid)): print("VM {0} is not running!".format(args.vmid)) return if args.k is not None and args.k >= 1: helper.killVm(args.vmid) time.sleep(0.3) if helper.process_running(args.vmid): time.sleep(2) if helper.process_running(args.vmid): helper.killVm(args.vmid , 9) print("VM killed successfully: " + ("yes" if not helper.process_running(args.vmid) else "no")) return if args.t is not None and not args.t.isdigit(): print ("timeout must be positve integer but is " + args.t + "!") return timeout = int(args.t) if args.t is not None else None print('Stopping VM {0.vmid} with timeout {1}.'.format(args,timeout)) helper.stopVM(args.vmid, timeout, lambda x: print(stopStatusToMessage[x]), wait=args.w is not None) def vmm_status(args): if args.v >= 1: print('Gathering status information for VM {0.vmid}.'.format(args)) proc_running = helper.process_running(args.vmid) print("VM ID: {0}".format(args.vmid)) print("Qemu process is running: " + ("yes (pid: {0})".format(helper.getPid(args.vmid)) if proc_running else "no")) #TODO write some decoder with status descriptions plaintext for key,val in helper.getQMPStatus(args.vmid).items(): print("{0}: {1}".format(key,val)) def vmm_cleanup(args): if(helper.process_running(args.vmid)): print("VM {0} is running, nothing to clean up!".format(args.vmid)) return print('Cleaning up for VM {0.vmid}.'.format(args)) helper.teardownNetwork(args.vmid) #TODO remove pidfile and qmpfile def vmm_version(args): print("MC VM Manager v0.1\nCopyright (c) M. Hauschild and P. Dahlberg 2013.\n") def vmm_autostart(args): helper.autostartVMs() def main(): #maybe we need to create a lockfile parser = argparse.ArgumentParser(prog='mcvmm', description='Manages VMs') subparsers = parser.add_subparsers(title='subcommands') parser.add_argument('-v', action='count', default=0, help='increase verbosity') parser_start = subparsers.add_parser('start', help='starts a VM') parser_start.add_argument('vmid', action='store', help='the ID of the VM') parser_start.set_defaults(func=vmm_start) parser_stop = subparsers.add_parser('stop', help='Shutdown VM with ACPI poweroff') parser_stop.add_argument('vmid', action='store', help='the ID of the VM') parser_stop.add_argument('-t', action='store', help='forcefully quit after given timeout value (signed integer), implies -w') parser_stop.add_argument('-k', action='count', help='Kill the qemu process') parser_stop.add_argument('-w', action='count', help='wait until the VM has stopped') parser_stop.set_defaults(func=vmm_stop) parser_shutdown = subparsers.add_parser('shutdown', help='Shutdown all VMs ACPI poweroff and quit forcefully after timeout') parser_shutdown.add_argument('-t', action='store', help='forcefully quit after given timeout value (signed integer, default: {0}'.format(SHUTDOWN_TIMEOUT)) parser_shutdown.add_argument('-s', action='count', help='sequencial mode, timeout for each vm') parser_shutdown.set_defaults(func=vmm_shutdown) parser_status = subparsers.add_parser('status', help='status a VM') parser_status.add_argument('-v', action='count', help='increase verbosity') parser_status.add_argument('vmid', action='store', default=0, help='the ID of the VM') parser_status.set_defaults(func=vmm_status) parser_cleanup = subparsers.add_parser('cleanup', help='cleans up stuff for a VM') parser_cleanup.add_argument('vmid', action='store', default=0, help='the ID of the VM') parser_cleanup.set_defaults(func=vmm_cleanup) parser_list = subparsers.add_parser('list', help='list available vms') parser_list.set_defaults(func=vmm_list) parser_version = subparsers.add_parser('version', help='Prints version and authors') parser_version.set_defaults(func=vmm_version) parser_autostart = subparsers.add_parser('autostart', help='Start VMs configured with autostart') parser_autostart.set_defaults(func=vmm_autostart) args = parser.parse_args() if "vmid" in args and args.vmid not in helper.getVmIds(): print("VM {0} does not exist!".format(args.vmid)) return args.func(args) if __name__ == '__main__': main()