VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/python/sample/shellcommon.py@ 12972

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

PerfAPI: Fixed the problem with passing null/empty arrays to PerfAPI methods.
Enabled attributes of type IUnknown in SOAP, JAX-WS, WSDL, CPP and Python style sheets.
Added PerfCollector python class to shellcommon.py to provide more 'pythonic' way to access metric data.
Added the reference to shellcommon.py to IDL docs as an example of PerfAPI usage in python.

  • 屬性 svn:eol-style 設為 native
檔案大小: 13.1 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 _update_metric_params(self):
26 metrics = self.collector.getMetrics(['*'], None)
27 self.metrics = {}
28 for m in metrics:
29 self.metrics[str(m.object) + "/" + str(m.metricName)] = m
30
31 def setup(self, names, objects, period, nsamples):
32 """ Discards all previously collected values for the specified
33 metrics, sets the period of collection and the number of retained
34 samples, enables collection.
35 """
36 self.collector.setupMetrics(names, objects, period, nsamples)
37 self._update_metric_params()
38
39 def enable(self, names, objects):
40 """ Resumes metric collection for the specified metrics.
41 """
42 self.collector.enableMetrics(names, objects)
43
44 def disable(self, names, objects):
45 """ Suspends metric collection for the specified metrics.
46 """
47 self.collector.disableMetrics(names, objects)
48
49 def query(self, names, objects):
50 """ Retrieves collected metric values as well as some auxiliary
51 information. Returns an array of dictionaries, one dictionary per
52 metric. Each dictionary contains the following entries:
53 'name': metric name
54 'object': managed object this metric associated with
55 'unit': unit of measurement
56 'scale': divide 'values' by this number to get float numbers
57 'values': collected data
58 'values_as_string': pre-processed values ready for 'print' statement
59 """
60 (values, names_out, objects_out, indices, lengths) = self.collector.queryMetricsData(names, objects)
61 out = []
62 for i in xrange(0, len(names_out)):
63 metric = self.metrics[str(objects_out[i]) + "/" + str(names_out[i])]
64 unit = str(metric.getUnit())
65 if unit == '%':
66 scale = 1000.
67 fmt = '%.2f%s'
68 else:
69 scale = 1
70 fmt = '%d %s'
71 out.append({
72 'name':str(names_out[i]),
73 'object':str(objects_out[i]),
74 'unit':str(metric.getUnit()),
75 'scale':scale,
76 'values':[int(values[j]) for j in xrange(int(indices[i]), int(indices[i])+int(lengths[i]))],
77 'values_as_string':'['+', '.join([fmt % (int(values[j])/scale, unit) for j in xrange(int(indices[i]), int(indices[i])+int(lengths[i]))])+']'
78 })
79 return out
80
81g_hasreadline = 1
82try:
83 import readline
84 import rlcompleter
85except:
86 g_hasreadline = 0
87
88
89if g_hasreadline:
90 class CompleterNG(rlcompleter.Completer):
91 def __init__(self, dic, ctx):
92 self.ctx = ctx
93 return rlcompleter.Completer.__init__(self,dic)
94
95 def complete(self, text, state):
96 """
97 taken from:
98 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496812
99 """
100 if text == "":
101 return ['\t',None][state]
102 else:
103 return rlcompleter.Completer.complete(self,text,state)
104
105 def global_matches(self, text):
106 """
107 Compute matches when text is a simple name.
108 Return a list of all names currently defined
109 in self.namespace that match.
110 """
111
112 matches = []
113 n = len(text)
114
115 for list in [ self.namespace ]:
116 for word in list:
117 if word[:n] == text:
118 matches.append(word)
119
120
121 try:
122 for m in getMachines(self.ctx):
123 # although it has autoconversion, we need to cast
124 # explicitly for subscripts to work
125 word = str(m.name)
126 if word[:n] == text:
127 matches.append(word)
128 word = str(m.id)
129 if word[0] == '{':
130 word = word[1:-1]
131 if word[:n] == text:
132 matches.append(word)
133 except Exception,e:
134 traceback.print_exc()
135 print e
136
137 return matches
138
139
140def autoCompletion(commands, ctx):
141 if not g_hasreadline:
142 return
143
144 comps = {}
145 for (k,v) in commands.items():
146 comps[k] = None
147 completer = CompleterNG(comps, ctx)
148 readline.set_completer(completer.complete)
149 readline.parse_and_bind("tab: complete")
150
151g_verbose = True
152
153def split_no_quotes(s):
154 return s.split()
155
156def startVm(mgr,vb,mach,type,perf):
157 session = mgr.getSessionObject(vb)
158 uuid = mach.id
159 progress = vb.openRemoteSession(session, uuid, type, "")
160 progress.waitForCompletion(-1)
161 completed = progress.completed
162 rc = progress.resultCode
163 print "Completed:", completed, "rc:",rc
164 if int(rc) == 0:
165 # @todo Nikolay, what is the point in ignoring exceptions?
166 try:
167 perf.setup(['*'], [mach], 10, 15)
168 except:
169 pass
170 session.close()
171
172def getMachines(ctx):
173 return ctx['vb'].getMachines2()
174
175def asState(var):
176 if var:
177 return 'on'
178 else:
179 return 'off'
180
181def guestStats(ctx,mach):
182 for metric in ctx['perf'].query(["*"], [mach]):
183 print metric['name'], metric['values_as_string']
184
185def cmdExistingVm(ctx,mach,cmd):
186 mgr=ctx['mgr']
187 vb=ctx['vb']
188 session = mgr.getSessionObject(vb)
189 uuid = mach.id
190 try:
191 progress = vb.openExistingSession(session, uuid)
192 except Exception,e:
193 print "Session to '%s' not open: %s" %(mach.name,e)
194 if g_verbose:
195 traceback.print_exc()
196 return
197 if session.state != ctx['ifaces'].SessionState.Open:
198 print "Session to '%s' in wrong state: %s" %(mach.name, session.state)
199 return
200 # unfortunately IGuest is suppressed, thus WebServices knows not about it
201 # this is an example how to handle local only functionality
202 if ctx['remote'] and cmd == 'stats2':
203 print 'Trying to use local only functionality, ignored'
204 return
205 console=session.console
206 ops={'pause' : lambda: console.pause(),
207 'resume': lambda: console.resume(),
208 'powerdown': lambda: console.powerDown(),
209 'stats': lambda: guestStats(ctx, mach),
210 }
211 ops[cmd]()
212 session.close()
213
214# can cache known machines, if needed
215def machById(ctx,id):
216 mach = None
217 for m in getMachines(ctx):
218 if m.name == id:
219 mach = m
220 break
221 mid = str(m.id)
222 if mid[0] == '{':
223 mid = mid[1:-1]
224 if mid == id:
225 mach = m
226 break
227 return mach
228
229def argsToMach(ctx,args):
230 if len(args) < 2:
231 print "usage: %s [vmname|uuid]" %(args[0])
232 return None
233 id = args[1]
234 m = machById(ctx, id)
235 if m == None:
236 print "Machine '%s' is unknown, use list command to find available machines" %(id)
237 return m
238
239def helpCmd(ctx, args):
240 if len(args) == 1:
241 print "Help page:"
242 for i in commands:
243 print " ",i,":", commands[i][0]
244 else:
245 c = commands.get(args[1], None)
246 if c == None:
247 print "Command '%s' not known" %(args[1])
248 else:
249 print " ",args[1],":", c[0]
250 return 0
251
252def listCmd(ctx, args):
253 for m in getMachines(ctx):
254 print "Machine '%s' [%s], state=%s" %(m.name,m.id,m.sessionState)
255 return 0
256
257def infoCmd(ctx,args):
258 if (len(args) < 2):
259 print "usage: info [vmname|uuid]"
260 return 0
261 mach = argsToMach(ctx,args)
262 if mach == None:
263 return 0
264 os = ctx['vb'].getGuestOSType(mach.OSTypeId)
265 print " Name: ",mach.name
266 print " ID: ",mach.id
267 print " OS Type: ",os.description
268 print " RAM: %dM" %(mach.memorySize)
269 print " VRAM: %dM" %(mach.VRAMSize)
270 print " Monitors: %d" %(mach.MonitorCount)
271 print " Clipboard mode: %d" %(mach.clipboardMode)
272 print " Machine status: " ,mach.sessionState
273 bios = mach.BIOSSettings
274 print " BIOS ACPI: ",bios.ACPIEnabled
275 print " PAE: ",mach.PAEEnabled
276 print " Hardware virtualization: ",asState(mach.HWVirtExEnabled)
277 print " Nested paging: ",asState(mach.HWVirtExNestedPagingEnabled)
278 print " Last changed: ",mach.lastStateChange
279
280 return 0
281
282def startCmd(ctx, args):
283 mach = argsToMach(ctx,args)
284 if mach == None:
285 return 0
286 if len(args) > 2:
287 type = args[2]
288 else:
289 type = "gui"
290 startVm(ctx['mgr'], ctx['vb'], mach, type, ctx['perf'])
291 return 0
292
293def pauseCmd(ctx, args):
294 mach = argsToMach(ctx,args)
295 if mach == None:
296 return 0
297 cmdExistingVm(ctx, mach, 'pause')
298 return 0
299
300def powerdownCmd(ctx, args):
301 mach = argsToMach(ctx,args)
302 if mach == None:
303 return 0
304 cmdExistingVm(ctx, mach, 'powerdown')
305 return 0
306
307def resumeCmd(ctx, args):
308 mach = argsToMach(ctx,args)
309 if mach == None:
310 return 0
311 cmdExistingVm(ctx, mach, 'resume')
312 return 0
313
314def statsCmd(ctx, args):
315 mach = argsToMach(ctx,args)
316 if mach == None:
317 return 0
318 cmdExistingVm(ctx, mach, 'stats')
319 return 0
320
321def setvarCmd(ctx, args):
322 if (len(args) < 4):
323 print "usage: setvar [vmname|uuid] expr value"
324 return 0
325 mach = argsToMach(ctx,args)
326 if mach == None:
327 return 0
328 vbox = ctx['vb']
329 session = ctx['mgr'].getSessionObject(vbox)
330 vbox.openSession(session, mach.id)
331 mach = session.machine
332 expr = 'mach.'+args[2]+' = '+args[3]
333 print "Executing",expr
334 try:
335 exec expr
336 except Exception, e:
337 print 'failed: ',e
338 if g_verbose:
339 traceback.print_exc()
340 mach.saveSettings()
341 session.close()
342 return 0
343
344def quitCmd(ctx, args):
345 return 1
346
347def aliasesCmd(ctx, args):
348 for (k,v) in aliases.items():
349 print "'%s' is an alias for '%s'" %(k,v)
350 return 0
351
352def verboseCmd(ctx, args):
353 global g_verbose
354 g_verbose = not g_verbose
355 return 0
356
357def hostCmd(ctx, args):
358 host = ctx['vb'].host
359 cnt = host.processorCount
360 print "Processor count:",cnt
361 for i in range(0,cnt):
362 print "Processor #%d speed: %dMHz" %(i,host.getProcessorSpeed(i))
363
364 for metric in ctx['perf'].query(["*"], [host]):
365 print metric['name'], metric['values_as_string']
366
367 return 0
368
369
370def evalCmd(ctx, args):
371 expr = ' '.join(args[1:])
372 try:
373 exec expr
374 except Exception, e:
375 print 'failed: ',e
376 if g_verbose:
377 traceback.print_exc()
378 return 0
379
380aliases = {'s':'start',
381 'i':'info',
382 'l':'list',
383 'h':'help',
384 'a':'aliases',
385 'q':'quit', 'exit':'quit',
386 'v':'verbose'}
387
388commands = {'help':['Prints help information', helpCmd],
389 'start':['Start virtual machine by name or uuid', startCmd],
390 'pause':['Pause virtual machine', pauseCmd],
391 'resume':['Resume virtual machine', resumeCmd],
392 'stats':['Stats for virtual machine', statsCmd],
393 'powerdown':['Power down virtual machine', powerdownCmd],
394 'list':['Shows known virtual machines', listCmd],
395 'info':['Shows info on machine', infoCmd],
396 'aliases':['Shows aliases', aliasesCmd],
397 'verbose':['Toggle verbosity', verboseCmd],
398 'setvar':['Set VMs variable: setvar Fedora BIOSSettings.ACPIEnabled True', setvarCmd],
399 'eval':['Evaluate arbitrary Python construction: eval for m in getMachines(ctx): print m.name,"has",m.memorySize,"M"', evalCmd],
400 'quit':['Exits', quitCmd],
401 'host':['Show host information', hostCmd]}
402
403def runCommand(ctx, cmd):
404 if len(cmd) == 0: return 0
405 args = split_no_quotes(cmd)
406 if len(args) == 0: return 0
407 c = args[0]
408 if aliases.get(c, None) != None:
409 c = aliases[c]
410 ci = commands.get(c,None)
411 if ci == None:
412 print "Unknown command: '%s', type 'help' for list of known commands" %(c)
413 return 0
414 return ci[1](ctx, args)
415
416
417def interpret(ctx):
418 vbox = ctx['vb']
419 print "Running VirtualBox version %s" %(vbox.version)
420
421 autoCompletion(commands, ctx)
422
423 # to allow to print actual host information, we collect info for
424 # last 150 secs maximum, (sample every 10 secs and keep up to 15 samples)
425 try:
426 ctx['perf'].setup(['*'], [vbox.host], 10, 15)
427 except:
428 pass
429
430 while True:
431 try:
432 cmd = raw_input("vbox> ")
433 done = runCommand(ctx, cmd)
434 if done != 0: break
435 except KeyboardInterrupt:
436 print '====== You can type quit or q to leave'
437 break
438 except EOFError:
439 break;
440 except Exception,e:
441 print e
442 if g_verbose:
443 traceback.print_exc()
444
445 try:
446 # There is no need to disable metric collection. This is just an example.
447 ctx['perf'].disable(['*'], [vbox.host])
448 except:
449 pass
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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