ADDED mkvm Index: mkvm ================================================================== --- mkvm +++ mkvm @@ -0,0 +1,25 @@ +#!/usr/bin/python +import os +options={'qemubinary':'qemu-system-x86_64', +"accel":"-enable-kvm", +"memory":"1024M", +"drive":"-drive media=disk,index=0,if=virtio,file=drive0.qcow2", +"cdrom":"-drive media=cdrom,index=2,if=ide", +"sound":"-sound hda", +"net":"-net nic,macaddr=%s -net bridge,br=lxc0", +"usb":"-usb"} + +with open("start.template","r") as f: + template=f.read() + +vmdir = "~/VWs/%s" % name + +os.mkdir(vmdir) +with open(vmdir +"/start",w) as f: + f.write(template.format(options) +os.chmod(0755,vmdir + "/start") +os.system("qemu-img create -f qcow2 "+vmdir+"/drive0.qcow2") + + + + Index: start.template ================================================================== --- start.template +++ start.template @@ -9,14 +9,20 @@ SPICE_AUTH="password=$SPICE_PASSWORD" else SPICE_AUTH="disable-ticketing,addr=127.0.0.1" fi SPICE_PORT=$(find_free_port 5900) +if [ "$1" = '-cdrom' ]; then + shift + CDROM="file=$1" + shift +fi {qemubinary} -name $NAME {accel} \ +-m {memory} {drive} \ -{cdrom} \ +{cdrom}$CDROM \ {net} \ {usb} \ {sound} \ -chardev socket,server,nowait,path=/home/vitus/asta.monitor,id=monitor \ -mon chardev=monitor,mode=readline \ Index: vws ================================================================== --- vws +++ vws @@ -1,10 +1,12 @@ #!/usr/bin/python from ConfigParser import ConfigParser from argparse import ArgumentParser +import fcntl import socket import errno +import re import os,sys config=ConfigParser({"SharedVMs":"/var/cache/vws/shared","AutostartVMs":"/var/cache/vws/auto"}) def find_vm(name): search_path=[os.environ['HOME']+"/VWs", config.get("directories","SharedVMs"), @@ -11,33 +13,34 @@ config.get("directories","AutostartVMs")] for dirname in search_path: if name in os.listdir(dirname): return dirname+"/"+name raise ValueError("Machine "+name+" not found.") + def connect_vm(vm_dir): sock=socket.socket(socket.AF_UNIX) sock.connect(vm_dir+"/monitor") - greeting=sock.recv() + greeting=sock.recv(1024) return sock def send_command(sock,command): fcntl.flock(sock,fcntl.LOCK_EX) try: sock.send(command+"\n") answer="" - while not answer.endswith("(qemu)"): - chunk=sock.recv() - print "Got chunk = ",repr(chunk) + while not answer.endswith("(qemu) "): + chunk=sock.recv(1024) + #print "Got chunk = ",repr(chunk) if chunk == '': raise IOError("Unexpected EOF From monitor") - answer+=sock.recv() + answer+=chunk finally: fcntl.flock(sock,fcntl.LOCK_UN) return answer -def cmd_spiceurl(options): +def spiceurl(options): output=send_command(options.sock,"info spice") url=None for line in output.split("\n"): if url is not None: continue @@ -49,25 +52,53 @@ return "spice://"+url # # command implementation # + +def cmd_spiceuri(options): + print spiceurl(options) + + def cmd_start(options): - pass + if options.stopped: + arg="" + if options.cdrom: + arg=" -cdrom "+options.cdrom + cmd=options.dir+"/start"+arg + os.system(cmd) + if options.gui: + uri = spiceurl(options) + os.system("remore-viewer $uri &") + elif not options.stopped: + print >>sys.stderr,"VM already running" + def cmd_stop(options): - send_command(options.sock,'system_powerdown') + print send_command(options.sock,'system_powerdown') def cmd_reset(options): - send_command(options.sock,'system_reset') + print send_command(options.sock,'system_reset') def cmd_cdrom(options): + if options.id is None: + # Search for devices which could be interpreted as CDROM + devlist=send_command(options.sock,"info block") + for dev in re.findall("([-\\w]+): [^\n]+\n Removable device:",devlist): + if re.search("cd",dev): + options.id=dev + break + if options.id is None: + print >>sys.stderr, "No CDROM device found among:\n"+devlist; + sys.exit(1) + if options.file == "": + print >>sys.stderr, "Please specify either --eject or iso image" + sys.exit(1) if options.file is None: answer=send_command(options.sock,"eject "+options.id) else: answer=send_command(options.sock, "change %s %s" % (options.id, options.file)) print answer - raise NotImplementedError def cmd_usb_insert(options): raise NotImplementedError def cmd_usb_list(options): os.system(lspci) @@ -74,10 +105,21 @@ def cmd_usb_remove(options): raise NotImplementedError def cmd_usb_attached(options): answer=send_command(options.sock,"info usb") print answer +def cmd_list(options): + search_path=[os.environ['HOME']+"/VWs", + config.get("directories","SharedVMs"), + config.get("directories","AutostartVMs")] + for dirname in search_path: + if not os.access(dirname+"/.",os.X_OK): + continue + for vmname in os.listdir(dirname): + if os.access(dirname+"/"+vmname+"/start",os.X_OK): + print vmname + # # Utility functions for arg parsing # def new_command(cmds,name,**kwargs): """ @@ -97,10 +139,16 @@ config.read(['/etc/vws.conf',os.environ['HOME']+'/.vwsrc']) args=ArgumentParser() cmds=args.add_subparsers(dest='command',help="sub-command help") +p=cmds.add_parser("list",help="List existing VWs") +p.add_argument("--state",action='store_const',const=True,default=False, + dest='state',help='Show state of the machine') +p.add_argument("--addr",action='store_const',const=True,default=False, + dest='addr',help='Show mac address and spice port') + # Power management p=new_command(cmds,'start',help='Start VM and connect to console') p.add_argument('--no-gui',dest='gui',action='store_const',const=False, default=True,help='do not open console window') p.add_argument('--cdrom',dest='cdrom',nargs=1, @@ -109,13 +157,13 @@ new_command(cmds,'stop',help='Shut down virtual machine') new_command(cmds,'save',help='Save VM state and stop emulation') new_command(cmds,'reset',help='Reboot a guest OS') # Removable devices management p=new_command(cmds,'cdrom',help='manage CDROM Drive') -p.add_argument('--id',type=str,default='cdrom0', +p.add_argument('--id',type=str,default=None, help='Identifier of CDROM drive if VM has more than one') -p.add_argument('file',help='ISO image or special file to connect to drive') +p.add_argument('file',nargs="?",default='',help='ISO image or special file to connect to drive') p.add_argument('--eject',dest='file',action='store_const',const=None) usb=cmds.add_parser('usb').add_subparsers(dest='subcommand',help='manage USB devices') p=new_command(usb,'insert',help='attach device to the virtual machine') p.add_argument('pattern',help='Pattern of device name to look up in lsusb') p.add_argument('--address',nargs=1,help='exact address bus:device') @@ -138,10 +186,11 @@ # Miscellenia p=new_command(cmds,'monitor',help='connect stdin/stdout to monitor of VM') p=new_command(cmds,'spiceuri',help='Output spice URI of machine') parsed_args=args.parse_args(sys.argv[1:]) +parsed_args.stopped = False stopped_vm_commands = ['start','snapshot','revert','commit','snapshots'] if hasattr(parsed_args,'machine'): parsed_args.dir=find_vm(parsed_args.machine) try: parsed_args.sock=connect_vm(parsed_args.dir) @@ -149,17 +198,19 @@ if e.errno == errno.ECONNREFUSED: # virtal machine is not running if not parsed_args.command in stopped_vm_commands: print >>sys.stderr, "Virtual machine %s is not running."%parsed_args.machine sys.exit(1) + else: + parsed_args.stopped = True else: raise e -print repr(parsed_args) funcname="cmd_"+parsed_args.command -if hasattr(parsed_args."subcommand"): + +if hasattr(parsed_args,"subcommand"): funcname+="_"+parsed_args.subcommand try: func=globals()[funcname] except KeyError: print >>sys.stderr,"Operation %s is not implemented"%funcname sys.exit(3) func(parsed_args)