VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxShell/shellcommon.py@ 19320

最後變更 在這個檔案從19320是 19320,由 vboxsync 提交於 16 年 前

Python bindings: fixed keyword conflict, minor cleanup

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 15.3 KB
 
1import traceback
2import sys
3import pdb
4
5class PerfCollector:
6 """ This class provides a wrapper over IPerformanceCollector in order to
7 get more 'pythonic' interface.
8
9 To begin collection of metrics use setup() method.
10
11 To get collected data use query() method.
12
13 It is possible to disable metric collection without changing collection
14 parameters with disable() method. The enable() method resumes metric
15 collection.
16 """
17
18 def __init__(self, vb):
19 """ Initializes the instance.
20
21 Pass an instance of IVirtualBox as parameter.
22 """
23 self.collector = vb.performanceCollector
24
25 def setup(self, names, objects, period, nsamples):
26 """ Discards all previously collected values for the specified
27 metrics, sets the period of collection and the number of retained
28 samples, enables collection.
29 """
30 self.collector.setupMetrics(names, objects, period, nsamples)
31
32 def enable(self, names, objects):
33 """ Resumes metric collection for the specified metrics.
34 """
35 self.collector.enableMetrics(names, objects)
36
37 def disable(self, names, objects):
38 """ Suspends metric collection for the specified metrics.
39 """
40 self.collector.disableMetrics(names, objects)
41
42 def query(self, names, objects):
43 """ Retrieves collected metric values as well as some auxiliary
44 information. Returns an array of dictionaries, one dictionary per
45 metric. Each dictionary contains the following entries:
46 'name': metric name
47 'object': managed object this metric associated with
48 'unit': unit of measurement
49 'scale': divide 'values' by this number to get float numbers
50 'values': collected data
51 'values_as_string': pre-processed values ready for 'print' statement
52 """
53 (values, names_out, objects_out, units, scales, sequence_numbers,
54 indices, lengths) = self.collector.queryMetricsData(names, objects)
55 out = []
56 for i in xrange(0, len(names_out)):
57 scale = int(scales[i])
58 if scale != 1:
59 fmt = '%.2f%s'
60 else:
61 fmt = '%d %s'
62 out.append({
63 'name':str(names_out[i]),
64 'object':str(objects_out[i]),
65 'unit':str(units[i]),
66 'scale':scale,
67 'values':[int(values[j]) for j in xrange(int(indices[i]), int(indices[i])+int(lengths[i]))],
68 'values_as_string':'['+', '.join([fmt % (int(values[j])/scale, units[i]) for j in xrange(int(indices[i]), int(indices[i])+int(lengths[i]))])+']'
69 })
70 return out
71
72g_hasreadline = 1
73try:
74 import readline
75 import rlcompleter
76except:
77 g_hasreadline = 0
78
79
80if g_hasreadline:
81 class CompleterNG(rlcompleter.Completer):
82 def __init__(self, dic, ctx):
83 self.ctx = ctx
84 return rlcompleter.Completer.__init__(self,dic)
85
86 def complete(self, text, state):
87 """
88 taken from:
89 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496812
90 """
91 if text == "":
92 return ['\t',None][state]
93 else:
94 return rlcompleter.Completer.complete(self,text,state)
95
96 def global_matches(self, text):
97 """
98 Compute matches when text is a simple name.
99 Return a list of all names currently defined
100 in self.namespace that match.
101 """
102
103 matches = []
104 n = len(text)
105
106 for list in [ self.namespace ]:
107 for word in list:
108 if word[:n] == text:
109 matches.append(word)
110
111
112 try:
113 for m in getMachines(self.ctx):
114 # although it has autoconversion, we need to cast
115 # explicitly for subscripts to work
116 word = str(m.name)
117 if word[:n] == text:
118 matches.append(word)
119 word = str(m.id)
120 if word[0] == '{':
121 word = word[1:-1]
122 if word[:n] == text:
123 matches.append(word)
124 except Exception,e:
125 traceback.print_exc()
126 print e
127
128 return matches
129
130
131def autoCompletion(commands, ctx):
132 if not g_hasreadline:
133 return
134
135 comps = {}
136 for (k,v) in commands.items():
137 comps[k] = None
138 completer = CompleterNG(comps, ctx)
139 readline.set_completer(completer.complete)
140 readline.parse_and_bind("tab: complete")
141
142g_verbose = True
143
144def split_no_quotes(s):
145 return s.split()
146
147def createVm(ctx,name,kind,base):
148 mgr = ctx['mgr']
149 vb = ctx['vb']
150 session = mgr.getSessionObject(vb)
151 mach = vb.createMachine(name, kind, base,
152 "00000000-0000-0000-0000-000000000000")
153 mach.saveSettings()
154 print "created machine with UUID",mach.id
155 vb.registerMachine(mach)
156
157def removeVm(ctx,mach):
158 mgr = ctx['mgr']
159 vb = ctx['vb']
160 print "removing machine ",mach.name,"with UUID",mach.id
161 mach = vb.unregisterMachine(mach.id)
162 if mach:
163 mach.deleteSettings()
164
165def startVm(ctx,mach,type):
166 mgr = ctx['mgr']
167 vb = ctx['vb']
168 perf = ctx['perf']
169 session = mgr.getSessionObject(vb)
170 uuid = mach.id
171 progress = vb.openRemoteSession(session, uuid, type, "")
172 progress.waitForCompletion(-1)
173 completed = progress.completed
174 rc = int(progress.resultCode)
175 print "Completed:", completed, "rc:",hex(rc&0xffffffff)
176 if rc == 0:
177 # we ignore exceptions to allow starting VM even if
178 # perf collector cannot be started
179 if perf:
180 try:
181 perf.setup(['*'], [mach], 10, 15)
182 except Exception,e:
183 print e
184 if g_verbose:
185 traceback.print_exc()
186 pass
187 # if session not opened, close doesn't make sense
188 session.close()
189 else:
190 # Not yet implemented error string query API for remote API
191 if not ctx['remote']:
192 print session.QueryErrorObject(rc)
193
194def getMachines(ctx):
195 # XPCOM brigde has trouble with array attributes
196 if ctx['type'] == 'xpcom':
197 return ctx['vb'].getMachines()
198 else:
199 return ctx['vb'].machines
200
201def asState(var):
202 if var:
203 return 'on'
204 else:
205 return 'off'
206
207def guestStats(ctx,mach):
208 if not ctx['perf']:
209 return
210 for metric in ctx['perf'].query(["*"], [mach]):
211 print metric['name'], metric['values_as_string']
212
213def guestExec(ctx, machine, console, cmds):
214 exec cmds
215
216def cmdExistingVm(ctx,mach,cmd,args):
217 mgr=ctx['mgr']
218 vb=ctx['vb']
219 session = mgr.getSessionObject(vb)
220 uuid = mach.id
221 try:
222 progress = vb.openExistingSession(session, uuid)
223 except Exception,e:
224 print "Session to '%s' not open: %s" %(mach.name,e)
225 if g_verbose:
226 traceback.print_exc()
227 return
228 if session.state != ctx['ifaces'].SessionState.Open:
229 print "Session to '%s' in wrong state: %s" %(mach.name, session.state)
230 return
231 # unfortunately IGuest is suppressed, thus WebServices knows not about it
232 # this is an example how to handle local only functionality
233 if ctx['remote'] and cmd == 'stats2':
234 print 'Trying to use local only functionality, ignored'
235 return
236 console=session.console
237 ops={'pause' : lambda: console.pause(),
238 'resume': lambda: console.resume(),
239 'powerdown': lambda: console.powerDown(),
240 'stats': lambda: guestStats(ctx, mach),
241 'guest': lambda: guestExec(ctx, mach, console, args)
242 }
243 try:
244 ops[cmd]()
245 except Exception, e:
246 print 'failed: ',e
247 if g_verbose:
248 traceback.print_exc()
249
250 session.close()
251
252# can cache known machines, if needed
253def machById(ctx,id):
254 mach = None
255 for m in getMachines(ctx):
256 if m.name == id:
257 mach = m
258 break
259 mid = str(m.id)
260 if mid[0] == '{':
261 mid = mid[1:-1]
262 if mid == id:
263 mach = m
264 break
265 return mach
266
267def argsToMach(ctx,args):
268 if len(args) < 2:
269 print "usage: %s [vmname|uuid]" %(args[0])
270 return None
271 id = args[1]
272 m = machById(ctx, id)
273 if m == None:
274 print "Machine '%s' is unknown, use list command to find available machines" %(id)
275 return m
276
277def helpCmd(ctx, args):
278 if len(args) == 1:
279 print "Help page:"
280 for i in commands:
281 print " ",i,":", commands[i][0]
282 else:
283 c = commands.get(args[1], None)
284 if c == None:
285 print "Command '%s' not known" %(args[1])
286 else:
287 print " ",args[1],":", c[0]
288 return 0
289
290def listCmd(ctx, args):
291 for m in getMachines(ctx):
292 print "Machine '%s' [%s], state=%s" %(m.name,m.id,m.sessionState)
293 return 0
294
295def infoCmd(ctx,args):
296 if (len(args) < 2):
297 print "usage: info [vmname|uuid]"
298 return 0
299 mach = argsToMach(ctx,args)
300 if mach == None:
301 return 0
302 os = ctx['vb'].getGuestOSType(mach.OSTypeId)
303 print " Name: ",mach.name
304 print " ID: ",mach.id
305 print " OS Type: ",os.description
306 print " RAM: %dM" %(mach.memorySize)
307 print " VRAM: %dM" %(mach.VRAMSize)
308 print " Clipboard mode: %d" %(mach.clipboardMode)
309 print " Machine status: " ,mach.sessionState
310 bios = mach.BIOSSettings
311 print " BIOS ACPI: ",bios.ACPIEnabled
312 print " PAE: ",mach.PAEEnabled
313 print " Hardware virtualization: ",asState(mach.HWVirtExEnabled)
314 print " Nested paging: ",asState(mach.HWVirtExNestedPagingEnabled)
315 print " Last changed: ",mach.lastStateChange
316
317 return 0
318
319def startCmd(ctx, args):
320 mach = argsToMach(ctx,args)
321 if mach == None:
322 return 0
323 if len(args) > 2:
324 type = args[2]
325 else:
326 type = "gui"
327 startVm(ctx, mach, type)
328 return 0
329
330def createCmd(ctx, args):
331 if (len(args) < 3 or len(args) > 4):
332 print "usage: create name ostype <basefolder>"
333 return 0
334 name = args[1]
335 oskind = args[2]
336 if len(args) == 4:
337 base = args[3]
338 else:
339 base = ''
340 try:
341 ctx['vb'].getGuestOSType(oskind)
342 except Exception, e:
343 print 'Unknown OS type:',oskind
344 return 0
345 createVm(ctx, name, oskind, base)
346 return 0
347
348def removeCmd(ctx, args):
349 mach = argsToMach(ctx,args)
350 if mach == None:
351 return 0
352 removeVm(ctx, mach)
353 return 0
354
355def pauseCmd(ctx, args):
356 mach = argsToMach(ctx,args)
357 if mach == None:
358 return 0
359 cmdExistingVm(ctx, mach, 'pause', '')
360 return 0
361
362def powerdownCmd(ctx, args):
363 mach = argsToMach(ctx,args)
364 if mach == None:
365 return 0
366 cmdExistingVm(ctx, mach, 'powerdown', '')
367 return 0
368
369def resumeCmd(ctx, args):
370 mach = argsToMach(ctx,args)
371 if mach == None:
372 return 0
373 cmdExistingVm(ctx, mach, 'resume', '')
374 return 0
375
376def statsCmd(ctx, args):
377 mach = argsToMach(ctx,args)
378 if mach == None:
379 return 0
380 cmdExistingVm(ctx, mach, 'stats', '')
381 return 0
382
383def guestCmd(ctx, args):
384 if (len(args) < 3):
385 print "usage: guest name commands"
386 return 0
387 mach = argsToMach(ctx,args)
388 if mach == None:
389 return 0
390 cmdExistingVm(ctx, mach, 'guest', ' '.join(args[2:]))
391 return 0
392
393def setvarCmd(ctx, args):
394 if (len(args) < 4):
395 print "usage: setvar [vmname|uuid] expr value"
396 return 0
397 mach = argsToMach(ctx,args)
398 if mach == None:
399 return 0
400 vbox = ctx['vb']
401 session = ctx['mgr'].getSessionObject(vbox)
402 vbox.openSession(session, mach.id)
403 mach = session.machine
404 expr = 'mach.'+args[2]+' = '+args[3]
405 print "Executing",expr
406 try:
407 exec expr
408 except Exception, e:
409 print 'failed: ',e
410 if g_verbose:
411 traceback.print_exc()
412 mach.saveSettings()
413 session.close()
414 return 0
415
416def quitCmd(ctx, args):
417 return 1
418
419def aliasesCmd(ctx, args):
420 for (k,v) in aliases.items():
421 print "'%s' is an alias for '%s'" %(k,v)
422 return 0
423
424def verboseCmd(ctx, args):
425 global g_verbose
426 g_verbose = not g_verbose
427 return 0
428
429def hostCmd(ctx, args):
430 host = ctx['vb'].host
431 cnt = host.processorCount
432 print "Processor count:",cnt
433 for i in range(0,cnt):
434 print "Processor #%d speed: %dMHz" %(i,host.getProcessorSpeed(i))
435
436 if ctx['perf']:
437 for metric in ctx['perf'].query(["*"], [host]):
438 print metric['name'], metric['values_as_string']
439
440 return 0
441
442
443def evalCmd(ctx, args):
444 expr = ' '.join(args[1:])
445 try:
446 exec expr
447 except Exception, e:
448 print 'failed: ',e
449 if g_verbose:
450 traceback.print_exc()
451 return 0
452
453aliases = {'s':'start',
454 'i':'info',
455 'l':'list',
456 'h':'help',
457 'a':'aliases',
458 'q':'quit', 'exit':'quit',
459 'v':'verbose'}
460
461commands = {'help':['Prints help information', helpCmd],
462 'start':['Start virtual machine by name or uuid', startCmd],
463 'create':['Create virtual machine', createCmd],
464 'remove':['Remove virtual machine', removeCmd],
465 'pause':['Pause virtual machine', pauseCmd],
466 'resume':['Resume virtual machine', resumeCmd],
467 'stats':['Stats for virtual machine', statsCmd],
468 'powerdown':['Power down virtual machine', powerdownCmd],
469 'list':['Shows known virtual machines', listCmd],
470 'info':['Shows info on machine', infoCmd],
471 'aliases':['Shows aliases', aliasesCmd],
472 'verbose':['Toggle verbosity', verboseCmd],
473 'setvar':['Set VMs variable: setvar Fedora BIOSSettings.ACPIEnabled True', setvarCmd],
474 'eval':['Evaluate arbitrary Python construction: eval for m in getMachines(ctx): print m.name,"has",m.memorySize,"M"', evalCmd],
475 'quit':['Exits', quitCmd],
476 'host':['Show host information', hostCmd],
477 'guest':['Execute command for guest: guest Win32 console.mouse.putMouseEvent(20, 20, 0, 0)', guestCmd],
478 }
479
480def runCommand(ctx, cmd):
481 if len(cmd) == 0: return 0
482 args = split_no_quotes(cmd)
483 if len(args) == 0: return 0
484 c = args[0]
485 if aliases.get(c, None) != None:
486 c = aliases[c]
487 ci = commands.get(c,None)
488 if ci == None:
489 print "Unknown command: '%s', type 'help' for list of known commands" %(c)
490 return 0
491 return ci[1](ctx, args)
492
493
494def interpret(ctx):
495 vbox = ctx['vb']
496 print "Running VirtualBox version %s" %(vbox.version)
497
498 # MSCOM doesn't work with collector yet
499 if ctx['type'] != 'mscom':
500 ctx['perf'] = PerfCollector(vbox)
501 else:
502 ctx['perf'] = None
503
504 autoCompletion(commands, ctx)
505
506 # to allow to print actual host information, we collect info for
507 # last 150 secs maximum, (sample every 10 secs and keep up to 15 samples)
508 if ctx['perf']:
509 try:
510 ctx['perf'].setup(['*'], [vbox.host], 10, 15)
511 except:
512 pass
513
514 while True:
515 try:
516 cmd = raw_input("vbox> ")
517 done = runCommand(ctx, cmd)
518 if done != 0: break
519 except KeyboardInterrupt:
520 print '====== You can type quit or q to leave'
521 break
522 except EOFError:
523 break;
524 except Exception,e:
525 print e
526 if g_verbose:
527 traceback.print_exc()
528
529 try:
530 # There is no need to disable metric collection. This is just an example.
531 if ct['perf']:
532 ctx['perf'].disable(['*'], [vbox.host])
533 except:
534 pass
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette