2013-04-02 17:12:37 +02:00
#!/usr/bin/python3
import argparse
import sys
2013-04-07 02:41:58 +02:00
import time
2013-04-05 20:27:21 +02:00
from VMHelper import VMHelper
2013-04-07 02:41:58 +02:00
#### 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 ) )
2013-04-02 17:12:37 +02:00
def vmm_start ( args ) :
2013-04-07 02:41:58 +02:00
if ( helper . process_running ( args . vmid ) ) :
print ( " VM {0} is already running! " . format ( args . vmid ) )
return
2013-04-05 20:27:21 +02:00
print ( ' Starting VM {0.vmid} . ' . format ( args ) )
helper . startVM ( args . vmid )
2013-04-07 02:41:58 +02:00
#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 )
2013-04-02 17:12:37 +02:00
def vmm_stop ( args ) :
2013-04-07 02:41:58 +02:00
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 )
2013-04-02 17:12:37 +02:00
2013-04-07 02:41:58 +02:00
def vmm_status ( args ) :
2013-04-05 20:27:21 +02:00
if args . v > = 1 :
print ( ' Gathering status information for VM {0.vmid} . ' . format ( args ) )
2013-04-07 02:41:58 +02:00
proc_running = helper . process_running ( args . vmid )
2013-04-05 20:27:21 +02:00
print ( " VM ID: {0} " . format ( args . vmid ) )
2013-04-07 02:41:58 +02:00
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 ) )
2013-04-05 20:27:21 +02:00
def vmm_cleanup ( args ) :
2013-04-07 02:41:58 +02:00
if ( helper . process_running ( args . vmid ) ) :
print ( " VM {0} is running, nothing to clean up! " . format ( args . vmid ) )
return
2013-04-05 20:27:21 +02:00
print ( ' Cleaning up for VM {0.vmid} . ' . format ( args ) )
helper . teardownNetwork ( args . vmid )
2013-04-07 02:41:58 +02:00
#TODO remove pidfile and qmpfile
2013-04-02 17:12:37 +02:00
2013-04-07 02:41:58 +02:00
def vmm_version ( args ) :
2013-04-05 20:27:21 +02:00
print ( " MC VM Manager v0.1 \n Copyright (c) M. Hauschild and P. Dahlberg 2013. \n " )
2013-04-07 02:41:58 +02:00
def vmm_autostart ( args ) :
helper . autostartVMs ( )
def main ( ) :
#maybe we need to create a lockfile
2013-04-05 20:27:21 +02:00
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 )
2013-04-02 17:12:37 +02:00
2013-04-07 02:41:58 +02:00
parser_stop = subparsers . add_parser ( ' stop ' , help = ' Shutdown VM with ACPI poweroff ' )
2013-04-05 20:27:21 +02:00
parser_stop . add_argument ( ' vmid ' , action = ' store ' , help = ' the ID of the VM ' )
2013-04-07 02:41:58 +02:00
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 ' )
2013-04-05 20:27:21 +02:00
parser_stop . set_defaults ( func = vmm_stop )
2013-04-02 17:12:37 +02:00
2013-04-07 02:41:58 +02:00
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 )
2013-04-05 20:27:21 +02:00
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 )
2013-04-02 17:12:37 +02:00
2013-04-05 20:27:21 +02:00
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 )
2013-04-02 17:12:37 +02:00
2013-04-07 02:41:58 +02:00
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 )
2013-04-05 20:27:21 +02:00
2013-04-07 02:41:58 +02:00
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
2013-04-05 20:27:21 +02:00
args . func ( args )
2013-04-02 17:12:37 +02:00
if __name__ == ' __main__ ' :
2013-04-05 20:27:21 +02:00
main ( )