vboxshell.py revision 387afbc7dec0873ee738feba578645b3879d0673
#
# Copyright (C) 2009 Sun Microsystems, Inc.
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
# General Public License (GPL) as published by the Free Software
# Foundation, in version 2 as it comes in the "COPYING" file of the
# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
# Clara, CA 95054 USA or visit http://www.sun.com if you need
# additional information or have any questions.
#
#################################################################################
# This program is a simple interactive shell for VirtualBox. You can query #
# information and issue commands from a simple command line. #
# #
# It also provides you with examples on how to use VirtualBox's Python API. #
# This shell is even somewhat documented and supports TAB-completion and #
# history if you have Python readline installed. #
# #
# Enjoy. #
################################################################################
import traceback
import shlex
import time
# Simple implementation of IConsoleCallback, one can use it as skeleton
# for custom implementations
class GuestMonitor:
def onAdditionsStateChange(self):
def onVRDPServerChange(self):
def onUSBControllerChange(self):
def onCanShowWindow(self):
return True
class VBoxMonitor:
pass
print "onMachineDataChange: %s" %(id)
# Witty COM bridge thinks if someone wishes to return tuple, hresult
# is one of values we want to return
else:
return True, ""
print "onMediaRegistered: %s" %(id)
print "onMachineRegistered: %s" %(id)
g_hasreadline = 1
try:
import readline
import rlcompleter
except:
g_hasreadline = 0
if g_hasreadline:
"""
taken from:
"""
if text == "":
return ['\t',None][state]
else:
"""
Compute matches when text is a simple name.
Return a list of all names currently defined
in self.namespace that match.
"""
matches = []
try:
# although it has autoconversion, we need to cast
# explicitly for subscripts to work
except Exception,e:
print e
return matches
if not g_hasreadline:
return
comps = {}
comps[k] = None
def split_no_quotes(s):
try:
while not p.completed:
print "%d %%\r" %(p.percent),
except KeyboardInterrupt:
print "Interrupted."
if not ctx['remote']:
# update cache
try:
except:
if mach:
# update cache
if rc == 0:
# we ignore exceptions to allow starting VM even if
# perf collector cannot be started
if perf:
try:
except Exception,e:
print e
if g_verbose:
pass
# if session not opened, close doesn't make sense
else:
if ctx['vb'] is not None:
return ctx['_machlist']
else:
return []
if var:
return 'on'
else:
return 'off'
if not ctx['perf']:
return
exec cmds
if dur == -1:
# not infinity, but close enough
dur = 100000
try:
# We need to catch all exceptions here, otherwise callback will never be unregistered
except:
pass
if dur == -1:
# not infinity, but close enough
dur = 100000
try:
# We need to catch all exceptions here, otherwise callback will never be unregistered
except:
pass
f = args[0]
else:
f = "/tmp/screenshot.png"
w = args[1]
else:
h = args[2]
else:
print "Saving screenshot (%d x %d) in %s..." %(w,h,f)
size = (w,h)
mode = "RGBA"
print "Use host:port format for teleport target"
return
else:
passwd = ""
if rc == 0:
print "Success!"
else:
# we need to set up guest statistics
else:
update = 1
try:
except:
# to allow sleep interruption
pass
cpu = 0
try:
print "%s: %d" %(s, val)
except:
# likely not implemented
pass
try:
except Exception,e:
if g_verbose:
return
return
# this could be an example how to handle local only (i.e. unavailable
# in Webservices) functionality
print 'Trying to use local only functionality, ignored'
return
}
try:
except Exception, e:
print 'failed: ',e
if g_verbose:
mach = None
for m in getMachines(ctx):
mach = m
break
mach = m
break
return mach
return None
if m == None:
print "Machine '%s' is unknown, use list command to find available machines" %(id)
return m
if sp != 0:
else:
spec = ""
print "Help page:"
for i in names:
else:
if c == None:
print "Command '%s' not known" %(cmd)
else:
return 0
if m.teleporterEnabled:
tele = "[T] "
else:
tele = " "
return 0
def getControllerType(type):
if type == 0:
return "Null"
elif type == 1:
return "LsiLogic"
elif type == 2:
return "BusLogic"
elif type == 3:
return "IntelAhci"
elif type == 4:
return "PIIX3"
elif type == 5:
return "PIIX4"
elif type == 6:
return "ICH6"
else:
return "Unknown"
def getFirmwareType(type):
if type == 0:
return "invalid"
elif type == 1:
return "bios"
elif type == 2:
return "efi"
elif type == 3:
return "efi64"
elif type == 4:
return "efidual"
else:
return "Unknown"
print "usage: info [vmname|uuid]"
return 0
if mach == None:
return 0
print " One can use setvar <mach> <var> <value> to change variable, using name in []."
print
print
print
print
print " Hardware virtualization [mach.setHWVirtExProperty(ctx['global'].constants.HWVirtExPropertyType_Enabled,value)]: " + asState(hwVirtEnabled)
print " VPID support [mach.setHWVirtExProperty(ctx['global'].constants.HWVirtExPropertyType_VPID,value)]: " + asState(hwVirtVPID)
hwVirtNestedPaging = mach.getHWVirtExProperty(ctx['global'].constants.HWVirtExPropertyType_NestedPaging)
print " Nested paging [mach.setHWVirtExProperty(ctx['global'].constants.HWVirtExPropertyType_NestedPaging,value)]: " + asState(hwVirtNestedPaging)
print " Hardware 2d video acceleration[accelerate2DVideoEnabled]: " + asState(mach.accelerate2DVideoEnabled)
if controllers:
print
print " Controllers:"
for controller in controllers:
print " %s %s bus: %d" % (controller.name, getControllerType(controller.controllerType), controller.bus)
if attaches:
print
print " Mediums:"
for a in attaches:
m = a.medium
print " HDD:"
print " Id: %s" %(m.id)
print " Location: %s" %(m.location)
print " Name: %s" %(m.name)
print " Format: %s" %(m.format)
print " DVD:"
if m:
print " Id: %s" %(m.id)
print " Name: %s" %(m.name)
if m.hostDrive:
print " Host DVD %s" %(m.location)
if a.passthrough:
print " [passthrough mode]"
else:
print " Virtual image at %s" %(m.location)
print " Size: %s" %(m.size)
print " Floppy:"
if m:
print " Id: %s" %(m.id)
print " Name: %s" %(m.name)
if m.hostDrive:
print " Host floppy %s" %(m.location)
else:
print " Virtual image at %s" %(m.location)
print " Size: %s" %(m.size)
return 0
if mach == None:
return 0
else:
type = "gui"
return 0
print "usage: create name ostype <basefolder>"
return 0
else:
base = ''
try:
except Exception, e:
print 'Unknown OS type:',oskind
return 0
return 0
if mach == None:
return 0
return 0
if mach == None:
return 0
return 0
if mach == None:
return 0
return 0
if mach == None:
return 0
return 0
if mach == None:
return 0
return 0
if mach == None:
return 0
return 0
if mach == None:
return 0
return 0
print "usage: guest name commands"
return 0
if mach == None:
return 0
return 0
print "usage: screenshot name file <width> <height>"
return 0
if mach == None:
return 0
return 0
print "usage: teleport name host:port <password>"
return 0
if mach == None:
return 0
return 0
print "usage: openportal name port <password>"
return 0
if mach == None:
return 0
else:
passwd = ""
return 0
print "usage: closeportal name"
return 0
if mach == None:
return 0
return 0
print "usage: gueststats name <check interval>"
return 0
if mach == None:
return 0
return 0
print "usage: setvar [vmname|uuid] expr value"
return 0
if mach == None:
return 0
print "Executing",expr
try:
exec expr
except Exception, e:
print 'failed: ',e
if g_verbose:
return 0
print "usage: setextra [vmname|uuid|global] key <value>"
return 0
else:
value = None
return 0
if mach == None:
return 0
return 0
print "usage: getextra [vmname|uuid|global] <key>"
return 0
else:
key = None
else:
if obj == None:
return 0
if key == None:
else:
for k in keys:
return 0
return 1
return 0
print "'%s' is an alias for '%s'" %(k,v)
return 0
global g_verbose
return 0
def getUSBStateString(state):
if state == 0:
return "NotSupported"
elif state == 1:
return "Unavailable"
elif state == 2:
return "Busy"
elif state == 3:
return "Available"
elif state == 4:
return "Held"
elif state == 5:
return "Captured"
else:
return "Unknown"
print "Processor count:",cnt
print "Processor #%d speed: %dMHz %s" %(i,host.getProcessorSpeed(i), host.getProcessorDescription(i))
print "3D acceleration available"
else:
print "3D acceleration NOT available"
print "Network interfaces:"
print "DVD drives:"
print "USB devices:"
print " %s (vendorId=%d productId=%d serial=%s) %s" %(ud.product, ud.vendorId, ud.productId, ud.serialNumber, getUSBStateString(ud.state))
if ctx['perf']:
return 0
print "usage: monitorGuest name (duration)"
return 0
if mach == None:
return 0
dur = 5
return 0
print "usage: monitorVBox (duration)"
return 0
dur = 5
return 0
return "pcnet"
return "e1000"
return "virtio"
return None
else:
print "usage: portForward <vm> <adapter> <hostPort> <guestPort>"
return 0
if mach == None:
return 0
proto = "TCP"
return 0
print "usage: showLog <vm> <num>"
return 0
if mach == None:
return 0
log = "VBox.log"
try:
except IOError,e:
print "cannot open: ",e
return 0
print line,
return 0
try:
exec expr
except Exception, e:
print 'failed: ',e
if g_verbose:
return 0
# maybe will want more args smartness
return 0
print "usage: runScript <script>"
return 0
try:
except IOError,e:
return 0
try:
if done != 0: break
except Exception,e:
print "error:",e
if g_verbose:
return 0
print "usage: sleep <secs>"
return 0
try:
except:
# to allow sleep interrupt
pass
return 0
print "usage: shell <commands>"
return 0
try:
except KeyboardInterrupt:
# to allow shell command interruption
pass
return 0
print "usage: connect [url] [username] [passwd]"
return 0
if ctx['vb'] is not None:
print "Already connected, disconnect first..."
return 0
else:
url = None
else:
user = ""
else:
passwd = ""
return 0
print "usage: disconnect"
return 0
if ctx['vb'] is None:
print "Not connected yet."
return 0
try:
except:
ctx['vb'] = None
raise
ctx['vb'] = None
return 0
import sys
print "usage: exportVm <machine> <path> <format> <license>"
return 0
if mach is None:
return 0
else:
format = "ovf-1.0"
else:
license = "GPL"
progressBar(ctx, p)
return 0
'i':'info',
'l':'list',
'h':'help',
'a':'alias',
'q':'quit', 'exit':'quit',
'v':'verbose'}
'eval':['Evaluate arbitrary Python construction: eval \'for m in getMachines(ctx): print m.name,"has",m.memorySize,"M"\'', evalCmd, 0],
'guest':['Execute command for guest: guest Win32 \'console.mouse.putMouseEvent(20, 20, 0, 0)\'', guestCmd, 0],
'monitorGuest':['Monitor what happens with the guest for some time: monitorGuest Win32 10', monitorGuestCmd, 0],
'monitorVBox':['Monitor what happens with Virtual Box for some time: monitorVBox 10', monitorVBoxCmd, 0],
'portForward':['Setup permanent port forwarding for a VM, takes adapter number host port and guest port: portForward Win32 0 8080 80', portForwardCmd, 0],
'screenshot':['Take VM screenshot to a file: screenshot Win /tmp/win.png 1024 768', screenshotCmd, 0],
'teleport':['Teleport VM to another box (see openportal): teleport Win anotherhost:8000 <passwd>', teleportCmd, 0],
'openportal':['Open portal for teleportation of VM from another box (see teleport): openportal Win 8000 <passwd>', openportalCmd, 0],
'closeportal':['Close teleportation portal (see openportal,teleport): closeportal Win', closeportalCmd, 0],
'setextra':['Set extra data, empty value removes key: setextra <vm|global> <key> <value>', setExtraDataCmd, 0],
'gueststats':['Print available guest stats (only Windows guests with additions so far): gueststats Win32', gueststatsCmd, 0],
}
c = args[0]
c = aliases[c]
if ci == None:
print "Unknown command: '%s', type 'help' for list of known commands" %(c)
return 0
#
# To write your own custom commands to vboxshell, create
# file ~/.VirtualBox/shellext.py with content like
#
# def runTestCmd(ctx, args):
# print "Testy test", ctx['vb']
# return 0
#
# commands = {
# 'test': ['Test help', runTestCmd]
# }
# and issue reloadExt shell command.
# This file also will be read automatically on startup or 'reloadExt'.
#
# Also one can put shell extensions into ~/.VirtualBox/shexts and
# they will also be picked up, so this way one can exchange
# shell extensions easily.
return
d = {}
try:
for (k,v) in d['commands'].items():
if g_verbose:
print "customize: adding \"%s\" - %s" %(k, v[0])
except:
print "Error loading user extensions from %s" %(file)
# also check 'exts' directory for all files
return
for e in exts:
def getHomeFolder(ctx):
else:
if ctx['remote']:
if vbox is not None:
else:
ctx['perf'] = None
# to allow to print actual host information, we collect info for
# last 150 secs maximum, (sample every 10 secs and keep up to 15 samples)
if ctx['perf']:
try:
except:
pass
while True:
try:
if done != 0: break
except KeyboardInterrupt:
print '====== You can type quit or q to leave'
break
except EOFError:
break;
except Exception,e:
print e
if g_verbose:
try:
# There is no need to disable metric collection. This is just an example.
if ct['perf']:
except:
pass
style = None
style = "WEBSERVICE"
if autopath:
if vpp is None and (os.path.isfile(os.path.join(cwd, "VirtualBox")) or os.path.isfile(os.path.join(cwd, "VirtualBox.exe"))) :
print "Autodetected VBOX_PROGRAM_PATH as",vpp
from vboxapi import VirtualBoxManager
'_machlist':None
}
if __name__ == '__main__':