PageRenderTime 71ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/src/VBox/Frontends/VBoxShell/vboxshell.py

https://bitbucket.org/diagiman/vbox-trunk
Python | 3507 lines | 3444 code | 49 blank | 14 comment | 91 complexity | f866e3253327c2fa90813fa5c75fdf8e MD5 | raw file
Possible License(s): BSD-3-Clause, MIT, GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. #!/usr/bin/python
  2. """
  3. Copyright (C) 2009-2012 Oracle Corporation
  4. This file is part of VirtualBox Open Source Edition (OSE), as
  5. available from http://www.virtualbox.org. This file is free software;
  6. you can redistribute it and/or modify it under the terms of the GNU
  7. General Public License (GPL) as published by the Free Software
  8. Foundation, in version 2 as it comes in the "COPYING" file of the
  9. VirtualBox OSE distribution. VirtualBox OSE is distributed in the
  10. hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
  11. """
  12. #################################################################################
  13. # This program is a simple interactive shell for VirtualBox. You can query #
  14. # information and issue commands from a simple command line. #
  15. # #
  16. # It also provides you with examples on how to use VirtualBox's Python API. #
  17. # This shell is even somewhat documented, supports TAB-completion and #
  18. # history if you have Python readline installed. #
  19. # #
  20. # Finally, shell allows arbitrary custom extensions, just create #
  21. # .VirtualBox/shexts/ and drop your extensions there. #
  22. # Enjoy. #
  23. ################################################################################
  24. import os,sys
  25. import traceback
  26. import shlex
  27. import time
  28. import re
  29. import platform
  30. from optparse import OptionParser
  31. g_batchmode = False
  32. g_scripfile = None
  33. g_cmd = None
  34. g_hasreadline = True
  35. try:
  36. if g_hasreadline:
  37. import readline
  38. import rlcompleter
  39. except:
  40. g_hasreadline = False
  41. g_prompt = "vbox> "
  42. g_hascolors = True
  43. term_colors = {
  44. 'red':'\033[31m',
  45. 'blue':'\033[94m',
  46. 'green':'\033[92m',
  47. 'yellow':'\033[93m',
  48. 'magenta':'\033[35m',
  49. 'cyan':'\033[36m'
  50. }
  51. def colored(string,color):
  52. if not g_hascolors:
  53. return string
  54. global term_colors
  55. col = term_colors.get(color,None)
  56. if col:
  57. return col+str(string)+'\033[0m'
  58. else:
  59. return string
  60. if g_hasreadline:
  61. import string
  62. class CompleterNG(rlcompleter.Completer):
  63. def __init__(self, dic, ctx):
  64. self.ctx = ctx
  65. return rlcompleter.Completer.__init__(self,dic)
  66. def complete(self, text, state):
  67. """
  68. taken from:
  69. http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496812
  70. """
  71. if False and text == "":
  72. return ['\t',None][state]
  73. else:
  74. return rlcompleter.Completer.complete(self,text,state)
  75. def canBePath(self, phrase,word):
  76. return word.startswith('/')
  77. def canBeCommand(self, phrase, word):
  78. spaceIdx = phrase.find(" ")
  79. begIdx = readline.get_begidx()
  80. firstWord = (spaceIdx == -1 or begIdx < spaceIdx)
  81. if firstWord:
  82. return True
  83. if phrase.startswith('help'):
  84. return True
  85. return False
  86. def canBeMachine(self,phrase,word):
  87. return not self.canBePath(phrase,word) and not self.canBeCommand(phrase, word)
  88. def global_matches(self, text):
  89. """
  90. Compute matches when text is a simple name.
  91. Return a list of all names currently defined
  92. in self.namespace that match.
  93. """
  94. matches = []
  95. phrase = readline.get_line_buffer()
  96. try:
  97. if self.canBePath(phrase,text):
  98. (dir,rest) = os.path.split(text)
  99. n = len(rest)
  100. for word in os.listdir(dir):
  101. if n == 0 or word[:n] == rest:
  102. matches.append(os.path.join(dir,word))
  103. if self.canBeCommand(phrase,text):
  104. n = len(text)
  105. for list in [ self.namespace ]:
  106. for word in list:
  107. if word[:n] == text:
  108. matches.append(word)
  109. if self.canBeMachine(phrase,text):
  110. n = len(text)
  111. for m in getMachines(self.ctx, False, True):
  112. # although it has autoconversion, we need to cast
  113. # explicitly for subscripts to work
  114. word = re.sub("(?<!\\\\) ", "\\ ", str(m.name))
  115. if word[:n] == text:
  116. matches.append(word)
  117. word = str(m.id)
  118. if word[:n] == text:
  119. matches.append(word)
  120. except Exception,e:
  121. printErr(e)
  122. if g_verbose:
  123. traceback.print_exc()
  124. return matches
  125. def autoCompletion(commands, ctx):
  126. if not g_hasreadline:
  127. return
  128. comps = {}
  129. for (k,v) in commands.items():
  130. comps[k] = None
  131. completer = CompleterNG(comps, ctx)
  132. readline.set_completer(completer.complete)
  133. delims = readline.get_completer_delims()
  134. readline.set_completer_delims(re.sub("[\\./-]", "", delims)) # remove some of the delimiters
  135. readline.parse_and_bind("set editing-mode emacs")
  136. # OSX need it
  137. if platform.system() == 'Darwin':
  138. # see http://www.certif.com/spec_help/readline.html
  139. readline.parse_and_bind ("bind ^I rl_complete")
  140. readline.parse_and_bind ("bind ^W ed-delete-prev-word")
  141. # Doesn't work well
  142. # readline.parse_and_bind ("bind ^R em-inc-search-prev")
  143. readline.parse_and_bind("tab: complete")
  144. g_verbose = False
  145. def split_no_quotes(s):
  146. return shlex.split(s)
  147. def progressBar(ctx,p,wait=1000):
  148. try:
  149. while not p.completed:
  150. print "%s %%\r" %(colored(str(p.percent),'red')),
  151. sys.stdout.flush()
  152. p.waitForCompletion(wait)
  153. ctx['global'].waitForEvents(0)
  154. if int(p.resultCode) != 0:
  155. reportError(ctx, p)
  156. return 1
  157. except KeyboardInterrupt:
  158. print "Interrupted."
  159. ctx['interrupt'] = True
  160. if p.cancelable:
  161. print "Canceling task..."
  162. p.cancel()
  163. return 0
  164. def printErr(ctx,e):
  165. print colored(str(e), 'red')
  166. def reportError(ctx,progress):
  167. ei = progress.errorInfo
  168. if ei:
  169. print colored("Error in module '%s': %s" %(ei.component, ei.text), 'red')
  170. def colCat(ctx,str):
  171. return colored(str, 'magenta')
  172. def colVm(ctx,vm):
  173. return colored(vm, 'blue')
  174. def colPath(ctx,p):
  175. return colored(p, 'green')
  176. def colSize(ctx,m):
  177. return colored(m, 'red')
  178. def colPci(ctx,vm):
  179. return colored(vm, 'green')
  180. def colDev(ctx,vm):
  181. return colored(vm, 'cyan')
  182. def colSizeM(ctx,m):
  183. return colored(str(m)+'M', 'red')
  184. def createVm(ctx,name,kind):
  185. mgr = ctx['mgr']
  186. vb = ctx['vb']
  187. mach = vb.createMachine("", name, [], kind, "")
  188. mach.saveSettings()
  189. print "created machine with UUID",mach.id
  190. vb.registerMachine(mach)
  191. # update cache
  192. getMachines(ctx, True)
  193. def removeVm(ctx,mach):
  194. mgr = ctx['mgr']
  195. vb = ctx['vb']
  196. id = mach.id
  197. print "removing machine ",mach.name,"with UUID",id
  198. cmdClosedVm(ctx, mach, detachVmDevice, ["ALL"])
  199. mach = mach.unregister(ctx['global'].constants.CleanupMode_Full)
  200. if mach:
  201. mach.deleteSettings()
  202. # update cache
  203. getMachines(ctx, True)
  204. def startVm(ctx,mach,type):
  205. mgr = ctx['mgr']
  206. vb = ctx['vb']
  207. perf = ctx['perf']
  208. session = mgr.getSessionObject(vb)
  209. progress = mach.launchVMProcess(session, type, "")
  210. if progressBar(ctx, progress, 100) and int(progress.resultCode) == 0:
  211. # we ignore exceptions to allow starting VM even if
  212. # perf collector cannot be started
  213. if perf:
  214. try:
  215. perf.setup(['*'], [mach], 10, 15)
  216. except Exception,e:
  217. printErr(ctx, e)
  218. if g_verbose:
  219. traceback.print_exc()
  220. session.unlockMachine()
  221. class CachedMach:
  222. def __init__(self, mach):
  223. self.name = mach.name
  224. self.id = mach.id
  225. def cacheMachines(ctx,list):
  226. result = []
  227. for m in list:
  228. try:
  229. elem = CachedMach(m)
  230. result.append(elem)
  231. except:
  232. pass
  233. return result
  234. def getMachines(ctx, invalidate = False, simple=False):
  235. if ctx['vb'] is not None:
  236. if ctx['_machlist'] is None or invalidate:
  237. ctx['_machlist'] = ctx['global'].getArray(ctx['vb'], 'machines')
  238. ctx['_machlistsimple'] = cacheMachines(ctx,ctx['_machlist'])
  239. if simple:
  240. return ctx['_machlistsimple']
  241. else:
  242. return ctx['_machlist']
  243. else:
  244. return []
  245. def asState(var):
  246. if var:
  247. return colored('on', 'green')
  248. else:
  249. return colored('off', 'green')
  250. def asFlag(var):
  251. if var:
  252. return 'yes'
  253. else:
  254. return 'no'
  255. def getFacilityStatus(ctx, guest, facilityType):
  256. (status, ts) = guest.getFacilityStatus(facilityType)
  257. return asEnumElem(ctx, 'AdditionsFacilityStatus', status)
  258. def perfStats(ctx, mach):
  259. if not ctx['perf']:
  260. return
  261. for metric in ctx['perf'].query(["*"], [mach]):
  262. print metric['name'], metric['values_as_string']
  263. def guestExec(ctx, machine, console, cmds):
  264. exec cmds
  265. def printMouseEvent(ctx, mev):
  266. print "Mouse : absolute=%d x=%d y=%d z=%d buttons=%x" %(mev.absolute, mev.x, mev.y, mev.z, mev.buttons)
  267. def printKbdEvent(ctx, kev):
  268. print "Kbd: ", ctx['global'].getArray(kev, 'scancodes')
  269. def monitorSource(ctx, es, active, dur):
  270. def handleEventImpl(ev):
  271. type = ev.type
  272. print "got event: %s %s" %(str(type), asEnumElem(ctx, 'VBoxEventType', type))
  273. if type == ctx['global'].constants.VBoxEventType_OnMachineStateChanged:
  274. scev = ctx['global'].queryInterface(ev, 'IMachineStateChangedEvent')
  275. if scev:
  276. print "machine state event: mach=%s state=%s" %(scev.machineId, scev.state)
  277. elif type == ctx['global'].constants.VBoxEventType_OnGuestPropertyChanged:
  278. gpcev = ctx['global'].queryInterface(ev, 'IGuestPropertyChangedEvent')
  279. if gpcev:
  280. print "guest property change: name=%s value=%s" %(gpcev.name, gpcev.value)
  281. elif type == ctx['global'].constants.VBoxEventType_OnMousePointerShapeChanged:
  282. psev = ctx['global'].queryInterface(ev, 'IMousePointerShapeChangedEvent')
  283. if psev:
  284. shape = ctx['global'].getArray(psev, 'shape')
  285. if shape is None:
  286. print "pointer shape event - empty shape"
  287. else:
  288. print "pointer shape event: w=%d h=%d shape len=%d" %(psev.width, psev.height, len(shape))
  289. elif type == ctx['global'].constants.VBoxEventType_OnGuestMouse:
  290. mev = ctx['global'].queryInterface(ev, 'IGuestMouseEvent')
  291. if mev:
  292. printMouseEvent(ctx, mev)
  293. elif type == ctx['global'].constants.VBoxEventType_OnGuestKeyboard:
  294. kev = ctx['global'].queryInterface(ev, 'IGuestKeyboardEvent')
  295. if kev:
  296. printKbdEvent(ctx, kev)
  297. class EventListener:
  298. def __init__(self, arg):
  299. pass
  300. def handleEvent(self, ev):
  301. try:
  302. # a bit convoluted QI to make it work with MS COM
  303. handleEventImpl(ctx['global'].queryInterface(ev, 'IEvent'))
  304. except:
  305. traceback.print_exc()
  306. pass
  307. if active:
  308. listener = ctx['global'].createListener(EventListener)
  309. else:
  310. listener = es.createListener()
  311. registered = False
  312. if dur == -1:
  313. # not infinity, but close enough
  314. dur = 100000
  315. try:
  316. es.registerListener(listener, [ctx['global'].constants.VBoxEventType_Any], active)
  317. registered = True
  318. end = time.time() + dur
  319. while time.time() < end:
  320. if active:
  321. ctx['global'].waitForEvents(500)
  322. else:
  323. ev = es.getEvent(listener, 500)
  324. if ev:
  325. handleEventImpl(ev)
  326. # otherwise waitable events will leak (active listeners ACK automatically)
  327. es.eventProcessed(listener, ev)
  328. # We need to catch all exceptions here, otherwise listener will never be unregistered
  329. except:
  330. traceback.print_exc()
  331. pass
  332. if listener and registered:
  333. es.unregisterListener(listener)
  334. tsLast = 0
  335. def recordDemo(ctx, console, file, dur):
  336. demo = open(file, 'w')
  337. header="VM="+console.machine.name+"\n"
  338. demo.write(header)
  339. global tsLast
  340. tsLast = time.time()
  341. def stamp():
  342. global tsLast
  343. tsCur = time.time()
  344. rv = int((tsCur-tsLast)*1000)
  345. tsLast = tsCur
  346. return rv
  347. def handleEventImpl(ev):
  348. type = ev.type
  349. #print "got event: %s %s" %(str(type), asEnumElem(ctx, 'VBoxEventType', type))
  350. if type == ctx['global'].constants.VBoxEventType_OnGuestMouse:
  351. mev = ctx['global'].queryInterface(ev, 'IGuestMouseEvent')
  352. if mev:
  353. l = "%d: m %d %d %d %d %d %d\n" %(stamp(), mev.absolute, mev.x, mev.y, mev.z, mev.w, mev.buttons)
  354. demo.write(l)
  355. elif type == ctx['global'].constants.VBoxEventType_OnGuestKeyboard:
  356. kev = ctx['global'].queryInterface(ev, 'IGuestKeyboardEvent')
  357. if kev:
  358. l = "%d: k %s\n" %(stamp(), str(ctx['global'].getArray(kev, 'scancodes')))
  359. demo.write(l)
  360. listener = console.eventSource.createListener()
  361. registered = False
  362. # we create an aggregated event source to listen for multiple event sources (keyboard and mouse in our case)
  363. agg = console.eventSource.createAggregator([console.keyboard.eventSource, console.mouse.eventSource])
  364. demo = open(file, 'w')
  365. header="VM="+console.machine.name+"\n"
  366. demo.write(header)
  367. if dur == -1:
  368. # not infinity, but close enough
  369. dur = 100000
  370. try:
  371. agg.registerListener(listener, [ctx['global'].constants.VBoxEventType_Any], False)
  372. registered = True
  373. end = time.time() + dur
  374. while time.time() < end:
  375. ev = agg.getEvent(listener, 1000)
  376. if ev:
  377. handleEventImpl(ev)
  378. # keyboard/mouse events aren't waitable, so no need for eventProcessed
  379. # We need to catch all exceptions here, otherwise listener will never be unregistered
  380. except:
  381. traceback.print_exc()
  382. pass
  383. demo.close()
  384. if listener and registered:
  385. agg.unregisterListener(listener)
  386. def playbackDemo(ctx, console, file, dur):
  387. demo = open(file, 'r')
  388. if dur == -1:
  389. # not infinity, but close enough
  390. dur = 100000
  391. header = demo.readline()
  392. print "Header is", header
  393. basere = re.compile(r'(?P<s>\d+): (?P<t>[km]) (?P<p>.*)')
  394. mre = re.compile(r'(?P<a>\d+) (?P<x>-*\d+) (?P<y>-*\d+) (?P<z>-*\d+) (?P<w>-*\d+) (?P<b>-*\d+)')
  395. kre = re.compile(r'\d+')
  396. kbd = console.keyboard
  397. mouse = console.mouse
  398. try:
  399. end = time.time() + dur
  400. for line in demo:
  401. if time.time() > end:
  402. break
  403. m = basere.search(line)
  404. if m is None:
  405. continue
  406. dict = m.groupdict()
  407. stamp = dict['s']
  408. params = dict['p']
  409. type = dict['t']
  410. time.sleep(float(stamp)/1000)
  411. if type == 'k':
  412. codes=kre.findall(params)
  413. #print "KBD:",codes
  414. kbd.putScancodes(codes)
  415. elif type == 'm':
  416. mm = mre.search(params)
  417. if mm is not None:
  418. mdict = mm.groupdict()
  419. if mdict['a'] == '1':
  420. # absolute
  421. #print "MA: ",mdict['x'],mdict['y'],mdict['z'],mdict['b']
  422. mouse.putMouseEventAbsolute(int(mdict['x']), int(mdict['y']), int(mdict['z']), int(mdict['w']), int(mdict['b']))
  423. else:
  424. #print "MR: ",mdict['x'],mdict['y'],mdict['b']
  425. mouse.putMouseEvent(int(mdict['x']), int(mdict['y']), int(mdict['z']), int(mdict['w']), int(mdict['b']))
  426. # We need to catch all exceptions here, to close file
  427. except KeyboardInterrupt:
  428. ctx['interrupt'] = True
  429. except:
  430. traceback.print_exc()
  431. pass
  432. demo.close()
  433. def takeScreenshotOld(ctx,console,args):
  434. from PIL import Image
  435. display = console.display
  436. if len(args) > 0:
  437. f = args[0]
  438. else:
  439. f = "/tmp/screenshot.png"
  440. if len(args) > 3:
  441. screen = int(args[3])
  442. else:
  443. screen = 0
  444. (fbw, fbh, fbbpp) = display.getScreenResolution(screen)
  445. if len(args) > 1:
  446. w = int(args[1])
  447. else:
  448. w = fbw
  449. if len(args) > 2:
  450. h = int(args[2])
  451. else:
  452. h = fbh
  453. print "Saving screenshot (%d x %d) screen %d in %s..." %(w,h,screen,f)
  454. data = display.takeScreenShotToArray(screen, w,h)
  455. size = (w,h)
  456. mode = "RGBA"
  457. im = Image.frombuffer(mode, size, str(data), "raw", mode, 0, 1)
  458. im.save(f, "PNG")
  459. def takeScreenshot(ctx,console,args):
  460. display = console.display
  461. if len(args) > 0:
  462. f = args[0]
  463. else:
  464. f = "/tmp/screenshot.png"
  465. if len(args) > 3:
  466. screen = int(args[3])
  467. else:
  468. screen = 0
  469. (fbw, fbh, fbbpp) = display.getScreenResolution(screen)
  470. if len(args) > 1:
  471. w = int(args[1])
  472. else:
  473. w = fbw
  474. if len(args) > 2:
  475. h = int(args[2])
  476. else:
  477. h = fbh
  478. print "Saving screenshot (%d x %d) screen %d in %s..." %(w,h,screen,f)
  479. data = display.takeScreenShotPNGToArray(screen, w,h)
  480. size = (w,h)
  481. file = open(f, 'wb')
  482. file.write(data)
  483. file.close()
  484. def teleport(ctx,session,console,args):
  485. if args[0].find(":") == -1:
  486. print "Use host:port format for teleport target"
  487. return
  488. (host,port) = args[0].split(":")
  489. if len(args) > 1:
  490. passwd = args[1]
  491. else:
  492. passwd = ""
  493. if len(args) > 2:
  494. maxDowntime = int(args[2])
  495. else:
  496. maxDowntime = 250
  497. port = int(port)
  498. print "Teleporting to %s:%d..." %(host,port)
  499. progress = console.teleport(host, port, passwd, maxDowntime)
  500. if progressBar(ctx, progress, 100) and int(progress.resultCode) == 0:
  501. print "Success!"
  502. else:
  503. reportError(ctx,progress)
  504. def guestStats(ctx,console,args):
  505. guest = console.guest
  506. # we need to set up guest statistics
  507. if len(args) > 0 :
  508. update = args[0]
  509. else:
  510. update = 1
  511. if guest.statisticsUpdateInterval != update:
  512. guest.statisticsUpdateInterval = update
  513. try:
  514. time.sleep(float(update)+0.1)
  515. except:
  516. # to allow sleep interruption
  517. pass
  518. all_stats = ctx['const'].all_values('GuestStatisticType')
  519. cpu = 0
  520. for s in all_stats.keys():
  521. try:
  522. val = guest.getStatistic( cpu, all_stats[s])
  523. print "%s: %d" %(s, val)
  524. except:
  525. # likely not implemented
  526. pass
  527. def plugCpu(ctx,machine,session,args):
  528. cpu = int(args[0])
  529. print "Adding CPU %d..." %(cpu)
  530. machine.hotPlugCPU(cpu)
  531. def unplugCpu(ctx,machine,session,args):
  532. cpu = int(args[0])
  533. print "Removing CPU %d..." %(cpu)
  534. machine.hotUnplugCPU(cpu)
  535. def mountIso(ctx,machine,session,args):
  536. machine.mountMedium(args[0], args[1], args[2], args[3], args[4])
  537. machine.saveSettings()
  538. def cond(c,v1,v2):
  539. if c:
  540. return v1
  541. else:
  542. return v2
  543. def printHostUsbDev(ctx,ud):
  544. print " %s: %s (vendorId=%d productId=%d serial=%s) %s" %(ud.id, colored(ud.product,'blue'), ud.vendorId, ud.productId, ud.serialNumber,asEnumElem(ctx, 'USBDeviceState', ud.state))
  545. def printUsbDev(ctx,ud):
  546. print " %s: %s (vendorId=%d productId=%d serial=%s)" %(ud.id, colored(ud.product,'blue'), ud.vendorId, ud.productId, ud.serialNumber)
  547. def printSf(ctx,sf):
  548. print " name=%s host=%s %s %s" %(sf.name, colPath(ctx,sf.hostPath), cond(sf.accessible, "accessible", "not accessible"), cond(sf.writable, "writable", "read-only"))
  549. def ginfo(ctx,console, args):
  550. guest = console.guest
  551. if guest.additionsRunLevel != ctx['const'].AdditionsRunLevelType_None:
  552. print "Additions active, version %s" %(guest.additionsVersion)
  553. print "Support seamless: %s" %(getFacilityStatus(ctx, guest, ctx['const'].AdditionsFacilityType_Seamless))
  554. print "Support graphics: %s" %(getFacilityStatus(ctx, guest, ctx['const'].AdditionsFacilityType_Graphics))
  555. print "Balloon size: %d" %(guest.memoryBalloonSize)
  556. print "Statistic update interval: %d" %(guest.statisticsUpdateInterval)
  557. else:
  558. print "No additions"
  559. usbs = ctx['global'].getArray(console, 'USBDevices')
  560. print "Attached USB:"
  561. for ud in usbs:
  562. printUsbDev(ctx,ud)
  563. rusbs = ctx['global'].getArray(console, 'remoteUSBDevices')
  564. print "Remote USB:"
  565. for ud in rusbs:
  566. printHostUsbDev(ctx,ud)
  567. print "Transient shared folders:"
  568. sfs = rusbs = ctx['global'].getArray(console, 'sharedFolders')
  569. for sf in sfs:
  570. printSf(ctx,sf)
  571. def cmdExistingVm(ctx,mach,cmd,args):
  572. session = None
  573. try:
  574. vb = ctx['vb']
  575. session = ctx['mgr'].getSessionObject(vb)
  576. mach.lockMachine(session, ctx['global'].constants.LockType_Shared)
  577. except Exception,e:
  578. printErr(ctx, "Session to '%s' not open: %s" %(mach.name,str(e)))
  579. if g_verbose:
  580. traceback.print_exc()
  581. return
  582. if session.state != ctx['const'].SessionState_Locked:
  583. print "Session to '%s' in wrong state: %s" %(mach.name, session.state)
  584. session.unlockMachine()
  585. return
  586. # this could be an example how to handle local only (i.e. unavailable
  587. # in Webservices) functionality
  588. if ctx['remote'] and cmd == 'some_local_only_command':
  589. print 'Trying to use local only functionality, ignored'
  590. session.unlockMachine()
  591. return
  592. console=session.console
  593. ops={'pause': lambda: console.pause(),
  594. 'resume': lambda: console.resume(),
  595. 'powerdown': lambda: console.powerDown(),
  596. 'powerbutton': lambda: console.powerButton(),
  597. 'stats': lambda: perfStats(ctx, mach),
  598. 'guest': lambda: guestExec(ctx, mach, console, args),
  599. 'ginfo': lambda: ginfo(ctx, console, args),
  600. 'guestlambda': lambda: args[0](ctx, mach, console, args[1:]),
  601. 'save': lambda: progressBar(ctx,console.saveState()),
  602. 'screenshot': lambda: takeScreenshot(ctx,console,args),
  603. 'teleport': lambda: teleport(ctx,session,console,args),
  604. 'gueststats': lambda: guestStats(ctx, console, args),
  605. 'plugcpu': lambda: plugCpu(ctx, session.machine, session, args),
  606. 'unplugcpu': lambda: unplugCpu(ctx, session.machine, session, args),
  607. 'mountiso': lambda: mountIso(ctx, session.machine, session, args),
  608. }
  609. try:
  610. ops[cmd]()
  611. except KeyboardInterrupt:
  612. ctx['interrupt'] = True
  613. except Exception, e:
  614. printErr(ctx,e)
  615. if g_verbose:
  616. traceback.print_exc()
  617. session.unlockMachine()
  618. def cmdClosedVm(ctx,mach,cmd,args=[],save=True):
  619. session = ctx['global'].openMachineSession(mach, True)
  620. mach = session.machine
  621. try:
  622. cmd(ctx, mach, args)
  623. except Exception, e:
  624. save = False
  625. printErr(ctx,e)
  626. if g_verbose:
  627. traceback.print_exc()
  628. if save:
  629. try:
  630. mach.saveSettings()
  631. except Exception, e:
  632. printErr(ctx,e)
  633. if g_verbose:
  634. traceback.print_exc()
  635. ctx['global'].closeMachineSession(session)
  636. def cmdAnyVm(ctx,mach,cmd, args=[],save=False):
  637. session = ctx['global'].openMachineSession(mach)
  638. mach = session.machine
  639. try:
  640. cmd(ctx, mach, session.console, args)
  641. except Exception, e:
  642. save = False;
  643. printErr(ctx,e)
  644. if g_verbose:
  645. traceback.print_exc()
  646. if save:
  647. mach.saveSettings()
  648. ctx['global'].closeMachineSession(session)
  649. def machById(ctx,id):
  650. try:
  651. mach = ctx['vb'].getMachine(id)
  652. except:
  653. mach = ctx['vb'].findMachine(id)
  654. return mach
  655. class XPathNode:
  656. def __init__(self, parent, obj, type):
  657. self.parent = parent
  658. self.obj = obj
  659. self.type = type
  660. def lookup(self, subpath):
  661. children = self.enum()
  662. matches = []
  663. for e in children:
  664. if e.matches(subpath):
  665. matches.append(e)
  666. return matches
  667. def enum(self):
  668. return []
  669. def matches(self,subexp):
  670. if subexp == self.type:
  671. return True
  672. if not subexp.startswith(self.type):
  673. return False
  674. m = re.search(r"@(?P<a>\w+)=(?P<v>[^\'\[\]]+)", subexp)
  675. matches = False
  676. try:
  677. if m is not None:
  678. dict = m.groupdict()
  679. attr = dict['a']
  680. val = dict['v']
  681. matches = (str(getattr(self.obj, attr)) == val)
  682. except:
  683. pass
  684. return matches
  685. def apply(self, cmd):
  686. exec(cmd, {'obj':self.obj,'node':self,'ctx':self.getCtx()}, {})
  687. def getCtx(self):
  688. if hasattr(self,'ctx'):
  689. return self.ctx
  690. return self.parent.getCtx()
  691. class XPathNodeHolder(XPathNode):
  692. def __init__(self, parent, obj, attr, heldClass, xpathname):
  693. XPathNode.__init__(self, parent, obj, 'hld '+xpathname)
  694. self.attr = attr
  695. self.heldClass = heldClass
  696. self.xpathname = xpathname
  697. def enum(self):
  698. children = []
  699. for n in self.getCtx()['global'].getArray(self.obj, self.attr):
  700. node = self.heldClass(self, n)
  701. children.append(node)
  702. return children
  703. def matches(self,subexp):
  704. return subexp == self.xpathname
  705. class XPathNodeValue(XPathNode):
  706. def __init__(self, parent, obj, xpathname):
  707. XPathNode.__init__(self, parent, obj, 'val '+xpathname)
  708. self.xpathname = xpathname
  709. def matches(self,subexp):
  710. return subexp == self.xpathname
  711. class XPathNodeHolderVM(XPathNodeHolder):
  712. def __init__(self, parent, vbox):
  713. XPathNodeHolder.__init__(self, parent, vbox, 'machines', XPathNodeVM, 'vms')
  714. class XPathNodeVM(XPathNode):
  715. def __init__(self, parent, obj):
  716. XPathNode.__init__(self, parent, obj, 'vm')
  717. #def matches(self,subexp):
  718. # return subexp=='vm'
  719. def enum(self):
  720. return [XPathNodeHolderNIC(self, self.obj),
  721. XPathNodeValue(self, self.obj.BIOSSettings, 'bios'),
  722. XPathNodeValue(self, self.obj.USBController, 'usb')]
  723. class XPathNodeHolderNIC(XPathNodeHolder):
  724. def __init__(self, parent, mach):
  725. XPathNodeHolder.__init__(self, parent, mach, 'nics', XPathNodeVM, 'nics')
  726. self.maxNic = self.getCtx()['vb'].systemProperties.getMaxNetworkAdapters(self.obj.chipsetType)
  727. def enum(self):
  728. children = []
  729. for i in range(0, self.maxNic):
  730. node = XPathNodeNIC(self, self.obj.getNetworkAdapter(i))
  731. children.append(node)
  732. return children
  733. class XPathNodeNIC(XPathNode):
  734. def __init__(self, parent, obj):
  735. XPathNode.__init__(self, parent, obj, 'nic')
  736. def matches(self,subexp):
  737. return subexp=='nic'
  738. class XPathNodeRoot(XPathNode):
  739. def __init__(self, ctx):
  740. XPathNode.__init__(self, None, None, 'root')
  741. self.ctx = ctx
  742. def enum(self):
  743. return [XPathNodeHolderVM(self, self.ctx['vb'])]
  744. def matches(self,subexp):
  745. return True
  746. def eval_xpath(ctx,scope):
  747. pathnames = scope.split("/")[2:]
  748. nodes = [XPathNodeRoot(ctx)]
  749. for p in pathnames:
  750. seen = []
  751. while len(nodes) > 0:
  752. n = nodes.pop()
  753. seen.append(n)
  754. for s in seen:
  755. matches = s.lookup(p)
  756. for m in matches:
  757. nodes.append(m)
  758. if len(nodes) == 0:
  759. break
  760. return nodes
  761. def argsToMach(ctx,args):
  762. if len(args) < 2:
  763. print "usage: %s [vmname|uuid]" %(args[0])
  764. return None
  765. id = args[1]
  766. m = machById(ctx, id)
  767. if m == None:
  768. print "Machine '%s' is unknown, use list command to find available machines" %(id)
  769. return m
  770. def helpSingleCmd(cmd,h,sp):
  771. if sp != 0:
  772. spec = " [ext from "+sp+"]"
  773. else:
  774. spec = ""
  775. print " %s: %s%s" %(colored(cmd,'blue'),h,spec)
  776. def helpCmd(ctx, args):
  777. if len(args) == 1:
  778. print "Help page:"
  779. names = commands.keys()
  780. names.sort()
  781. for i in names:
  782. helpSingleCmd(i, commands[i][0], commands[i][2])
  783. else:
  784. cmd = args[1]
  785. c = commands.get(cmd)
  786. if c == None:
  787. print "Command '%s' not known" %(cmd)
  788. else:
  789. helpSingleCmd(cmd, c[0], c[2])
  790. return 0
  791. def asEnumElem(ctx,enum,elem):
  792. all = ctx['const'].all_values(enum)
  793. for e in all.keys():
  794. if str(elem) == str(all[e]):
  795. return colored(e, 'green')
  796. return colored("<unknown>", 'green')
  797. def enumFromString(ctx,enum,str):
  798. all = ctx['const'].all_values(enum)
  799. return all.get(str, None)
  800. def listCmd(ctx, args):
  801. for m in getMachines(ctx, True):
  802. try:
  803. if m.teleporterEnabled:
  804. tele = "[T] "
  805. else:
  806. tele = " "
  807. print "%sMachine '%s' [%s], machineState=%s, sessionState=%s" %(tele,colVm(ctx,m.name),m.id,asEnumElem(ctx, "MachineState", m.state), asEnumElem(ctx,"SessionState", m.sessionState))
  808. except Exception, e:
  809. printErr(ctx,e)
  810. if g_verbose:
  811. traceback.print_exc()
  812. return 0
  813. def infoCmd(ctx,args):
  814. if (len(args) < 2):
  815. print "usage: info [vmname|uuid]"
  816. return 0
  817. mach = argsToMach(ctx,args)
  818. if mach == None:
  819. return 0
  820. os = ctx['vb'].getGuestOSType(mach.OSTypeId)
  821. print " One can use setvar <mach> <var> <value> to change variable, using name in []."
  822. print " Name [name]: %s" %(colVm(ctx,mach.name))
  823. print " Description [description]: %s" %(mach.description)
  824. print " ID [n/a]: %s" %(mach.id)
  825. print " OS Type [via OSTypeId]: %s" %(os.description)
  826. print " Firmware [firmwareType]: %s (%s)" %(asEnumElem(ctx,"FirmwareType", mach.firmwareType),mach.firmwareType)
  827. print
  828. print " CPUs [CPUCount]: %d" %(mach.CPUCount)
  829. print " RAM [memorySize]: %dM" %(mach.memorySize)
  830. print " VRAM [VRAMSize]: %dM" %(mach.VRAMSize)
  831. print " Monitors [monitorCount]: %d" %(mach.monitorCount)
  832. print " Chipset [chipsetType]: %s (%s)" %(asEnumElem(ctx,"ChipsetType", mach.chipsetType), mach.chipsetType)
  833. print
  834. print " Clipboard mode [clipboardMode]: %s (%s)" %(asEnumElem(ctx,"ClipboardMode", mach.clipboardMode), mach.clipboardMode)
  835. print " Machine status [n/a]: %s (%s)" % (asEnumElem(ctx,"SessionState", mach.sessionState), mach.sessionState)
  836. print
  837. if mach.teleporterEnabled:
  838. print " Teleport target on port %d (%s)" %(mach.teleporterPort, mach.teleporterPassword)
  839. print
  840. bios = mach.BIOSSettings
  841. print " ACPI [BIOSSettings.ACPIEnabled]: %s" %(asState(bios.ACPIEnabled))
  842. print " APIC [BIOSSettings.IOAPICEnabled]: %s" %(asState(bios.IOAPICEnabled))
  843. hwVirtEnabled = mach.getHWVirtExProperty(ctx['global'].constants.HWVirtExPropertyType_Enabled)
  844. print " Hardware virtualization [guest win machine.setHWVirtExProperty(ctx[\\'const\\'].HWVirtExPropertyType_Enabled,value)]: " + asState(hwVirtEnabled)
  845. hwVirtVPID = mach.getHWVirtExProperty(ctx['const'].HWVirtExPropertyType_VPID)
  846. print " VPID support [guest win machine.setHWVirtExProperty(ctx[\\'const\\'].HWVirtExPropertyType_VPID,value)]: " + asState(hwVirtVPID)
  847. hwVirtNestedPaging = mach.getHWVirtExProperty(ctx['const'].HWVirtExPropertyType_NestedPaging)
  848. print " Nested paging [guest win machine.setHWVirtExProperty(ctx[\\'const\\'].HWVirtExPropertyType_NestedPaging,value)]: " + asState(hwVirtNestedPaging)
  849. print " Hardware 3d acceleration [accelerate3DEnabled]: " + asState(mach.accelerate3DEnabled)
  850. print " Hardware 2d video acceleration [accelerate2DVideoEnabled]: " + asState(mach.accelerate2DVideoEnabled)
  851. print " Use universal time [RTCUseUTC]: %s" %(asState(mach.RTCUseUTC))
  852. print " HPET [HPETEnabled]: %s" %(asState(mach.HPETEnabled))
  853. if mach.audioAdapter.enabled:
  854. print " Audio [via audioAdapter]: chip %s; host driver %s" %(asEnumElem(ctx,"AudioControllerType", mach.audioAdapter.audioController), asEnumElem(ctx,"AudioDriverType", mach.audioAdapter.audioDriver))
  855. if mach.USBController.enabled:
  856. print " USB [via USBController]: high speed %s" %(asState(mach.USBController.enabledEHCI))
  857. print " CPU hotplugging [CPUHotPlugEnabled]: %s" %(asState(mach.CPUHotPlugEnabled))
  858. print " Keyboard [keyboardHIDType]: %s (%s)" %(asEnumElem(ctx,"KeyboardHIDType", mach.keyboardHIDType), mach.keyboardHIDType)
  859. print " Pointing device [pointingHIDType]: %s (%s)" %(asEnumElem(ctx,"PointingHIDType", mach.pointingHIDType), mach.pointingHIDType)
  860. print " Last changed [n/a]: " + time.asctime(time.localtime(long(mach.lastStateChange)/1000))
  861. # OSE has no VRDE
  862. try:
  863. print " VRDE server [VRDEServer.enabled]: %s" %(asState(mach.VRDEServer.enabled))
  864. except:
  865. pass
  866. print
  867. print colCat(ctx," I/O subsystem info:")
  868. print " Cache enabled [IOCacheEnabled]: %s" %(asState(mach.IOCacheEnabled))
  869. print " Cache size [IOCacheSize]: %dM" %(mach.IOCacheSize)
  870. controllers = ctx['global'].getArray(mach, 'storageControllers')
  871. if controllers:
  872. print
  873. print colCat(ctx," Controllers:")
  874. for controller in controllers:
  875. print " '%s': bus %s type %s" % (controller.name, asEnumElem(ctx,"StorageBus", controller.bus), asEnumElem(ctx,"StorageControllerType", controller.controllerType))
  876. attaches = ctx['global'].getArray(mach, 'mediumAttachments')
  877. if attaches:
  878. print
  879. print colCat(ctx," Media:")
  880. for a in attaches:
  881. print " Controller: '%s' port/device: %d:%d type: %s (%s):" % (a.controller, a.port, a.device, asEnumElem(ctx,"DeviceType", a.type), a.type)
  882. m = a.medium
  883. if a.type == ctx['global'].constants.DeviceType_HardDisk:
  884. print " HDD:"
  885. print " Id: %s" %(m.id)
  886. print " Location: %s" %(colPath(ctx,m.location))
  887. print " Name: %s" %(m.name)
  888. print " Format: %s" %(m.format)
  889. if a.type == ctx['global'].constants.DeviceType_DVD:
  890. print " DVD:"
  891. if m:
  892. print " Id: %s" %(m.id)
  893. print " Name: %s" %(m.name)
  894. if m.hostDrive:
  895. print " Host DVD %s" %(colPath(ctx,m.location))
  896. if a.passthrough:
  897. print " [passthrough mode]"
  898. else:
  899. print " Virtual image at %s" %(colPath(ctx,m.location))
  900. print " Size: %s" %(m.size)
  901. if a.type == ctx['global'].constants.DeviceType_Floppy:
  902. print " Floppy:"
  903. if m:
  904. print " Id: %s" %(m.id)
  905. print " Name: %s" %(m.name)
  906. if m.hostDrive:
  907. print " Host floppy %s" %(colPath(ctx,m.location))
  908. else:
  909. print " Virtual image at %s" %(colPath(ctx,m.location))
  910. print " Size: %s" %(m.size)
  911. print
  912. print colCat(ctx," Shared folders:")
  913. for sf in ctx['global'].getArray(mach, 'sharedFolders'):
  914. printSf(ctx,sf)
  915. return 0
  916. def startCmd(ctx, args):
  917. if len(args) < 2:
  918. print "usage: start name <frontend>"
  919. return 0
  920. mach = argsToMach(ctx,args)
  921. if mach == None:
  922. return 0
  923. if len(args) > 2:
  924. type = args[2]
  925. else:
  926. type = "gui"
  927. startVm(ctx, mach, type)
  928. return 0
  929. def createVmCmd(ctx, args):
  930. if (len(args) != 3):
  931. print "usage: createvm name ostype"
  932. return 0
  933. name = args[1]
  934. oskind = args[2]
  935. try:
  936. ctx['vb'].getGuestOSType(oskind)
  937. except Exception, e:
  938. print 'Unknown OS type:',oskind
  939. return 0
  940. createVm(ctx, name, oskind)
  941. return 0
  942. def ginfoCmd(ctx,args):
  943. if (len(args) < 2):
  944. print "usage: ginfo [vmname|uuid]"
  945. return 0
  946. mach = argsToMach(ctx,args)
  947. if mach == None:
  948. return 0
  949. cmdExistingVm(ctx, mach, 'ginfo', '')
  950. return 0
  951. def execInGuest(ctx,console,args,env,user,passwd,tmo,inputPipe=None,outputPipe=None):
  952. if len(args) < 1:
  953. print "exec in guest needs at least program name"
  954. return
  955. guest = console.guest
  956. guestSession = guest.createSession(user, passwd, "", "vboxshell guest exec")
  957. # shall contain program name as argv[0]
  958. gargs = args
  959. print "executing %s with args %s as %s" %(args[0], gargs, user)
  960. flags = 0
  961. if inputPipe is not None:
  962. flags = 1 # set WaitForProcessStartOnly
  963. print args[0]
  964. process = guestSession.processCreate(args[0], gargs, env, [], tmo)
  965. print "executed with pid %d" %(process.PID)
  966. if pid != 0:
  967. try:
  968. while True:
  969. if inputPipe is not None:
  970. indata = inputPipe(ctx)
  971. if indata is not None:
  972. write = len(indata)
  973. off = 0
  974. while write > 0:
  975. w = guest.setProcessInput(pid, 0, 10*1000, indata[off:])
  976. off = off + w
  977. write = write - w
  978. else:
  979. # EOF
  980. try:
  981. guest.setProcessInput(pid, 1, 10*1000, " ")
  982. except:
  983. pass
  984. data = guest.getProcessOutput(pid, 0, 10000, 4096)
  985. if data and len(data) > 0:
  986. sys.stdout.write(data)
  987. continue
  988. progress.waitForCompletion(100)
  989. ctx['global'].waitForEvents(0)
  990. data = guest.getProcessOutput(pid, 0, 0, 4096)
  991. if data and len(data) > 0:
  992. if outputPipe is not None:
  993. outputPipe(ctx,data)
  994. else:
  995. sys.stdout.write(data)
  996. continue
  997. if progress.completed:
  998. break
  999. except KeyboardInterrupt:
  1000. print "Interrupted."
  1001. ctx['interrupt'] = True
  1002. if progress.cancelable:
  1003. progress.cancel()
  1004. (reason, code, flags) = guest.getProcessStatus(pid)
  1005. print "Exit code: %d" %(code)
  1006. return 0
  1007. else:
  1008. reportError(ctx, progress)
  1009. def copyToGuest(ctx,console,args,user,passwd):
  1010. src = args[0]
  1011. dst = args[1]
  1012. flags = 0
  1013. print "Copying host %s to guest %s" %(src,dst)
  1014. progress = console.guest.copyToGuest(src, dst, user, passwd, flags)
  1015. progressBar(ctx, progress)
  1016. def nh_raw_input(prompt=""):
  1017. stream = sys.stdout
  1018. prompt = str(prompt)
  1019. if prompt:
  1020. stream.write(prompt)
  1021. line = sys.stdin.readline()
  1022. if not line:
  1023. raise EOFError
  1024. if line[-1] == '\n':
  1025. line = line[:-1]
  1026. return line
  1027. def getCred(ctx):
  1028. import getpass
  1029. user = getpass.getuser()
  1030. user_inp = nh_raw_input("User (%s): " %(user))
  1031. if len (user_inp) > 0:
  1032. user = user_inp
  1033. passwd = getpass.getpass()
  1034. return (user,passwd)
  1035. def gexecCmd(ctx,args):
  1036. if (len(args) < 2):
  1037. print "usage: gexec [vmname|uuid] command args"
  1038. return 0
  1039. mach = argsToMach(ctx,args)
  1040. if mach == None:
  1041. return 0
  1042. gargs = args[2:]
  1043. env = [] # ["DISPLAY=:0"]
  1044. (user,passwd) = getCred(ctx)
  1045. gargs.insert(0, lambda ctx,mach,console,args: execInGuest(ctx,console,args,env,user,passwd,10000))
  1046. cmdExistingVm(ctx, mach, 'guestlambda', gargs)
  1047. return 0
  1048. def gcopyCmd(ctx,args):
  1049. if (len(args) < 2):
  1050. print "usage: gcopy [vmname|uuid] host_path guest_path"
  1051. return 0
  1052. mach = argsToMach(ctx,args)
  1053. if mach == None:
  1054. return 0
  1055. gargs = args[2:]
  1056. (user,passwd) = getCred(ctx)
  1057. gargs.insert(0, lambda ctx,mach,console,args: copyToGuest(ctx,console,args,user,passwd))
  1058. cmdExistingVm(ctx, mach, 'guestlambda', gargs)
  1059. return 0
  1060. def readCmdPipe(ctx,hcmd):
  1061. try:
  1062. return ctx['process'].communicate()[0]
  1063. except:
  1064. return None
  1065. def gpipeCmd(ctx,args):
  1066. if (len(args) < 4):
  1067. print "usage: gpipe [vmname|uuid] hostProgram guestProgram, such as gpipe linux '/bin/uname -a' '/bin/sh -c \"/usr/bin/tee; /bin/uname -a\"'"
  1068. return 0
  1069. mach = argsToMach(ctx,args)
  1070. if mach == None:
  1071. return 0
  1072. hcmd = args[2]
  1073. gcmd = args[3]
  1074. (user,passwd) = getCred(ctx)
  1075. import subprocess
  1076. ctx['process'] = subprocess.Popen(split_no_quotes(hcmd), stdout=subprocess.PIPE)
  1077. gargs = split_no_quotes(gcmd)
  1078. env = []
  1079. gargs.insert(0, lambda ctx,mach,console,args: execInGuest(ctx,console,args,env,user,passwd, 10000,lambda ctx:readCmdPipe(ctx, hcmd)))
  1080. cmdExistingVm(ctx, mach, 'guestlambda', gargs)
  1081. try:
  1082. ctx['process'].terminate()
  1083. except:
  1084. pass
  1085. ctx['process'] = None
  1086. return 0
  1087. def removeVmCmd(ctx, args):
  1088. mach = argsToMach(ctx,args)
  1089. if mach == None:
  1090. return 0
  1091. removeVm(ctx, mach)
  1092. return 0
  1093. def pauseCmd(ctx, args):
  1094. mach = argsToMach(ctx,args)
  1095. if mach == None:
  1096. return 0
  1097. cmdExistingVm(ctx, mach, 'pause', '')
  1098. return 0
  1099. def powerdownCmd(ctx, args):
  1100. mach = argsToMach(ctx,args)
  1101. if mach == None:
  1102. return 0
  1103. cmdExistingVm(ctx, mach, 'powerdown', '')
  1104. return 0
  1105. def powerbuttonCmd(ctx, args):
  1106. mach = argsToMach(ctx,args)
  1107. if mach == None:
  1108. return 0
  1109. cmdExistingVm(ctx, mach, 'powerbutton', '')
  1110. return 0
  1111. def resumeCmd(ctx, args):
  1112. mach = argsToMach(ctx,args)
  1113. if mach == None:
  1114. return 0
  1115. cmdExistingVm(ctx, mach, 'resume', '')
  1116. return 0
  1117. def saveCmd(ctx, args):
  1118. mach = argsToMach(ctx,args)
  1119. if mach == None:
  1120. return 0
  1121. cmdExistingVm(ctx, mach, 'save', '')
  1122. return 0
  1123. def statsCmd(ctx, args):
  1124. mach = argsToMach(ctx,args)
  1125. if mach == None:
  1126. return 0
  1127. cmdExistingVm(ctx, mach, 'stats', '')
  1128. return 0
  1129. def guestCmd(ctx, args):
  1130. if (len(args) < 3):
  1131. print "usage: guest name commands"
  1132. return 0
  1133. mach = argsToMach(ctx,args)
  1134. if mach == None:
  1135. return 0
  1136. if mach.state != ctx['const'].MachineState_Running:
  1137. cmdClosedVm(ctx, mach, lambda ctx, mach, a: guestExec (ctx, mach, None, ' '.join(args[2:])))
  1138. else:
  1139. cmdExistingVm(ctx, mach, 'guest', ' '.join(args[2:]))
  1140. return 0
  1141. def screenshotCmd(ctx, args):
  1142. if (len(args) < 2):
  1143. print "usage: screenshot vm <file> <width> <height> <monitor>"
  1144. return 0
  1145. mach = argsToMach(ctx,args)
  1146. if mach == None:
  1147. return 0
  1148. cmdExistingVm(ctx, mach, 'screenshot', args[2:])
  1149. return 0
  1150. def teleportCmd(ctx, args):
  1151. if (len(args) < 3):
  1152. print "usage: teleport name host:port <password>"
  1153. return 0
  1154. mach = argsToMach(ctx,args)
  1155. if mach == None:
  1156. return 0
  1157. cmdExistingVm(ctx, mach, 'teleport', args[2:])
  1158. return 0
  1159. def portalsettings(ctx,mach,args):
  1160. enabled = args[0]
  1161. mach.teleporterEnabled = enabled
  1162. if enabled:
  1163. port = args[1]
  1164. passwd = args[2]
  1165. mach.teleporterPort = port
  1166. mach.teleporterPassword = passwd
  1167. def openportalCmd(ctx, args):
  1168. if (len(args) < 3):
  1169. print "usage: openportal name port <password>"
  1170. return 0
  1171. mach = argsToMach(ctx,args)
  1172. if mach == None:
  1173. return 0
  1174. port = int(args[2])
  1175. if (len(args) > 3):
  1176. passwd = args[3]
  1177. else:
  1178. passwd = ""
  1179. if not mach.teleporterEnabled or mach.teleporterPort != port or passwd:
  1180. cmdClosedVm(ctx, mach, portalsettings, [True, port, passwd])
  1181. startVm(ctx, mach, "gui")
  1182. return 0
  1183. def closeportalCmd(ctx, args):
  1184. if (len(args) < 2):
  1185. print "usage: closeportal name"
  1186. return 0
  1187. mach = argsToMach(ctx,args)
  1188. if mach == None:
  1189. return 0
  1190. if mach.teleporterEnabled:
  1191. cmdClosedVm(ctx, mach, portalsettings, [False])
  1192. return 0
  1193. def gueststatsCmd(ctx, args):
  1194. if (len(args) < 2):
  1195. print "usage: gueststats name <check interval>"
  1196. return 0
  1197. mach = argsToMach(ctx,args)
  1198. if mach == None:
  1199. return 0
  1200. cmdExistingVm(ctx, mach, 'gueststats', args[2:])
  1201. return 0
  1202. def plugcpu(ctx,mach,args):
  1203. plug = args[0]
  1204. cpu = args[1]
  1205. if plug:
  1206. print "Adding CPU %d..." %(cpu)
  1207. mach.hotPlugCPU(cpu)
  1208. else:
  1209. print "Removing CPU %d..." %(cpu)
  1210. mach.hotUnplugCPU(cpu)
  1211. def plugcpuCmd(ctx, args):
  1212. if (len(args) < 2):
  1213. print "usage: plugcpu name cpuid"
  1214. return 0
  1215. mach = argsToMach(ctx,args)
  1216. if mach == None:
  1217. return 0
  1218. if str(mach.sessionState) != str(ctx['const'].SessionState_Locked):
  1219. if mach.CPUHotPlugEnabled:
  1220. cmdClosedVm(ctx, mach, plugcpu, [True, int(args[2])])
  1221. else:
  1222. cmdExistingVm(ctx, mach, 'plugcpu', args[2])
  1223. return 0
  1224. def unplugcpuCmd(ctx, args):
  1225. if (len(args) < 2):
  1226. print "usage: unplugcpu name cpuid"
  1227. return 0
  1228. mach = argsToMach(ctx,args)
  1229. if mach == None:
  1230. return 0
  1231. if str(mach.sessionState) != str(ctx['const'].SessionState_Locked):
  1232. if mach.CPUHotPlugEnabled:
  1233. cmdClosedVm(ctx, mach, plugcpu, [False, int(args[2])])
  1234. else:
  1235. cmdExistingVm(ctx, mach, 'unplugcpu', args[2])
  1236. return 0
  1237. def setvar(ctx,mach,args):
  1238. expr = 'mach.'+args[0]+' = '+args[1]
  1239. print "Executing",expr
  1240. exec expr
  1241. def setvarCmd(ctx, args):
  1242. if (len(args) < 4):
  1243. print "usage: setvar [vmname|uuid] expr value"
  1244. return 0
  1245. mach = argsToMach(ctx,args)
  1246. if mach == None:
  1247. return 0
  1248. cmdClosedVm(ctx, mach, setvar, args[2:])
  1249. return 0
  1250. def setvmextra(ctx,mach,args):
  1251. key = args[0]
  1252. value = args[1]
  1253. print "%s: setting %s to %s" %(mach.name, key, value)
  1254. mach.setExtraData(key, value)
  1255. def setExtraDataCmd(ctx, args):
  1256. if (len(args) < 3):
  1257. print "usage: setextra [vmname|uuid|global] key <value>"
  1258. return 0
  1259. key = args[2]
  1260. if len(args) == 4:
  1261. value = args[3]
  1262. else:
  1263. value = None
  1264. if args[1] == 'global':
  1265. ctx['vb'].setExtraData(key, value)
  1266. return 0
  1267. mach = argsToMach(ctx,args)
  1268. if mach == None:
  1269. return 0
  1270. cmdClosedVm(ctx, mach, setvmextra, [key, value])
  1271. return 0
  1272. def printExtraKey(obj, key, value):
  1273. print "%s: '%s' = '%s'" %(obj, key, value)
  1274. def getExtraDataCmd(ctx, args):
  1275. if (len(args) < 2):
  1276. print "usage: getextra [vmname|uuid|global] <key>"
  1277. return 0
  1278. if len(args) == 3:
  1279. key = args[2]
  1280. else:
  1281. key = None
  1282. if args[1] == 'global':
  1283. obj = ctx['vb']
  1284. else:
  1285. obj = argsToMach(ctx,args)
  1286. if obj == None:
  1287. return 0
  1288. if key == None:
  1289. keys = obj.getExtraDataKeys()
  1290. else:
  1291. keys = [ key ]
  1292. for k in keys:
  1293. printExtraKey(args[1], k, obj.getExtraData(k))
  1294. return 0
  1295. def quitCmd(ctx, args):
  1296. return 1
  1297. def aliasCmd(ctx, args):
  1298. if (len(args) == 3):
  1299. aliases[args[1]] = args[2]
  1300. return 0
  1301. for (k,v) in aliases.items():
  1302. print "'%s' is an alias for '%s'" %(k,v)
  1303. return 0
  1304. def verboseCmd(ctx, args):
  1305. global g_verbose
  1306. if (len(args) > 1):
  1307. g_verbose = (args[1]=='on')
  1308. else:
  1309. g_verbose = not g_verbose
  1310. return 0
  1311. def colorsCmd(ctx, args):
  1312. global g_hascolors
  1313. if (len(args) > 1):
  1314. g_hascolors = (args[1]=='on')
  1315. else:
  1316. g_hascolors = not g_hascolors
  1317. return 0
  1318. def hostCmd(ctx, args):
  1319. vb = ctx['vb']
  1320. print "VirtualBox version %s" %(colored(vb.version, 'blue'))
  1321. props = vb.systemProperties
  1322. print "Machines: %s" %(colPath(ctx,props.defaultMachineFolder))
  1323. #print "Global shared folders:"
  1324. #for ud in ctx['global'].getArray(vb, 'sharedFolders'):
  1325. # printSf(ctx,sf)
  1326. host = vb.host
  1327. cnt = host.processorCount
  1328. print colCat(ctx,"Processors:")
  1329. print " available/online: %d/%d " %(cnt,host.processorOnlineCount)
  1330. for i in range(0,cnt):
  1331. print " processor #%d speed: %dMHz %s" %(i,host.getProcessorSpeed(i), host.getProcessorDescription(i))
  1332. print colCat(ctx, "RAM:")
  1333. print " %dM (free %dM)" %(host.memorySize, host.memoryAvailable)
  1334. print colCat(ctx,"OS:");
  1335. print " %s (%s)" %(host.operatingSystem, host.OSVersion)
  1336. if host.acceleration3DAvailable:
  1337. print colCat(ctx,"3D acceleration available")
  1338. else:
  1339. print colCat(ctx,"3D acceleration NOT available")
  1340. print colCat(ctx,"Network interfaces:")
  1341. for ni in ctx['global'].getArray(host, 'networkInterfaces'):
  1342. print " %s (%s)" %(ni.name, ni.IPAddress)
  1343. print colCat(ctx,"DVD drives:")
  1344. for dd in ctx['global'].getArray(host, 'DVDDrives'):
  1345. print " %s - %s" %(dd.name, dd.description)
  1346. print colCat(ctx,"Floppy drives:")
  1347. for dd in ctx['global'].getArray(host, 'floppyDrives'):
  1348. print " %s - %s" %(dd.name, dd.description)
  1349. print colCat(ctx,"USB devices:")
  1350. for ud in ctx['global'].getArray(host, 'USBDevices'):
  1351. printHostUsbDev(ctx,ud)
  1352. if ctx['perf']:
  1353. for metric in ctx['perf'].query(["*"], [host]):
  1354. print metric['name'], metric['values_as_string']
  1355. return 0
  1356. def monitorGuestCmd(ctx, args):
  1357. if (l

Large files files are truncated, but you can click here to view the full file