vws at [e7fb60a50e]
Not logged in

File vws artifact 0fd7f10ab5 part of check-in e7fb60a50e


#!/usr/bin/python
from ConfigParser import ConfigParser
from argparse import ArgumentParser
import socket
import errno
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"),
        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()
    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)
            if chunk == '':
                raise IOError("Unexpected EOF From monitor")
            answer+=sock.recv()
    finally:
        fcntl.flock(sock,fcntl.LOCK_UN)
    return answer

def cmd_spiceurl(options):
    output=send_command(options.sock,"info spice")
    url=None
    for    line in output.split("\n"):
        if url is not None:
            continue
        n=line.find("address:")
        if n != -1:
            url=line[n+9:]
            if url.startswith('*:'):
                url="localhost"+url[1:]
    return "spice://"+url      

#
# command implementation
#
def cmd_start(options):
    pass
def cmd_stop(options):
    send_command(options.sock,'system_powerdown')
    
def cmd_reset(options):
    send_command(options.sock,'system_reset')
def cmd_cdrom(options):
    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)

def cmd_usb_remove(options):
    raise NotImplementedError
def cmd_usb_attached(options):
    answer=send_command(options.sock,"info usb")
    print answer
#
# Utility functions for arg parsing
#
def new_command(cmds,name,**kwargs):
    """
    Adds a subparser and adds a machine name argument to it
    """
    p=cmds.add_parser(name,**kwargs)
    p.add_argument('machine',type=str,help='name of vm to operate on')
    return p
#
# arg parsing
#



config=ConfigParser({'SharedVMs':'/var/cache/vws/shared',  
    'AuthoStartVMs':'/var/cache/vws/autostart'})

config.read(['/etc/vws.conf',os.environ['HOME']+'/.vwsrc'])

args=ArgumentParser()
cmds=args.add_subparsers(dest='command',help="sub-command help")
# 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,
               help='connect specified iso image to VMs cdrom on start')
# Following commands don't need extra args
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',
               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('--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')
p=new_command(usb,'remove',help='detach connected usb device')
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')
p=new_command(usb,'attached',help='list devices attached to vm')
usb.add_parser('list',help='list devices available in the host system')
# Snapshot management
p=new_command(cmds,'snapshot',help='Create new snapshot')
p=new_command(cmds,'revert',help='Revert to last snapshot')
p=new_command(cmds,'commit',help='Commit snapshot changes into backing file')
p=new_command(cmds,'snapshots',help='List existing snapshots')
# Screenshoits and recording
p=new_command(cmds,'screenshoot',help='take a screenshot')
p.add_argument('filename',help='image filename to write screenshot to')
p=new_command(cmds,'record',help='Record audio output from VM')
p.add_argument('filename',help='wav file to record autdio to')
new_command(cmds,'stoprecord',help='stop recording audio')
# 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:])

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)
    except IOError as e:
        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:
            raise e
print repr(parsed_args)
funcname="cmd_"+parsed_args.command
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)