VirtualBox

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

Last change on this file since 16366 was 16366, checked in by vboxsync, 16 years ago

removed stale XPCOM attribute from info command implementation

  • Property svn:eol-style set to native
File size: 12.8 KB
Line 
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 startVm(mgr,vb,mach,type,perf):
148 session = mgr.getSessionObject(vb)
149 uuid = mach.id
150 progress = vb.openRemoteSession(session, uuid, type, "")
151 progress.waitForCompletion(-1)
152 completed = progress.completed
153 rc = progress.resultCode
154 print "Completed:", completed, "rc:",rc
155 if int(rc) == 0:
156 # we ignore exceptions to allow starting VM even if
157 # perf collector cannot be started
158 try:
159 perf.setup(['*'], [mach], 10, 15)
160 except:
161 print e
162 if g_verbose:
163 traceback.print_exc()
164 pass
165 session.close()
166
167def getMachines(ctx):
168 return ctx['vb'].getMachines2()
169
170def asState(var):
171 if var:
172 return 'on'
173 else:
174 return 'off'
175
176def guestStats(ctx,mach):
177 for metric in ctx['perf'].query(["*"], [mach]):
178 print metric['name'], metric['values_as_string']
179
180def cmdExistingVm(ctx,mach,cmd):
181 mgr=ctx['mgr']
182 vb=ctx['vb']
183 session = mgr.getSessionObject(vb)
184 uuid = mach.id
185 try:
186 progress = vb.openExistingSession(session, uuid)
187 except Exception,e:
188 print "Session to '%s' not open: %s" %(mach.name,e)
189 if g_verbose:
190 traceback.print_exc()
191 return
192 if session.state != ctx['ifaces'].SessionState.Open:
193 print "Session to '%s' in wrong state: %s" %(mach.name, session.state)
194 return
195 # unfortunately IGuest is suppressed, thus WebServices knows not about it
196 # this is an example how to handle local only functionality
197 if ctx['remote'] and cmd == 'stats2':
198 print 'Trying to use local only functionality, ignored'
199 return
200 console=session.console
201 ops={'pause' : lambda: console.pause(),
202 'resume': lambda: console.resume(),
203 'powerdown': lambda: console.powerDown(),
204 'stats': lambda: guestStats(ctx, mach),
205 }
206 ops[cmd]()
207 session.close()
208
209# can cache known machines, if needed
210def machById(ctx,id):
211 mach = None
212 for m in getMachines(ctx):
213 if m.name == id:
214 mach = m
215 break
216 mid = str(m.id)
217 if mid[0] == '{':
218 mid = mid[1:-1]
219 if mid == id:
220 mach = m
221 break
222 return mach
223
224def argsToMach(ctx,args):
225 if len(args) < 2:
226 print "usage: %s [vmname|uuid]" %(args[0])
227 return None
228 id = args[1]
229 m = machById(ctx, id)
230 if m == None:
231 print "Machine '%s' is unknown, use list command to find available machines" %(id)
232 return m
233
234def helpCmd(ctx, args):
235 if len(args) == 1:
236 print "Help page:"
237 for i in commands:
238 print " ",i,":", commands[i][0]
239 else:
240 c = commands.get(args[1], None)
241 if c == None:
242 print "Command '%s' not known" %(args[1])
243 else:
244 print " ",args[1],":", c[0]
245 return 0
246
247def listCmd(ctx, args):
248 for m in getMachines(ctx):
249 print "Machine '%s' [%s], state=%s" %(m.name,m.id,m.sessionState)
250 return 0
251
252def infoCmd(ctx,args):
253 if (len(args) < 2):
254 print "usage: info [vmname|uuid]"
255 return 0
256 mach = argsToMach(ctx,args)
257 if mach == None:
258 return 0
259 os = ctx['vb'].getGuestOSType(mach.OSTypeId)
260 print " Name: ",mach.name
261 print " ID: ",mach.id
262 print " OS Type: ",os.description
263 print " RAM: %dM" %(mach.memorySize)
264 print " VRAM: %dM" %(mach.VRAMSize)
265 print " Clipboard mode: %d" %(mach.clipboardMode)
266 print " Machine status: " ,mach.sessionState
267 bios = mach.BIOSSettings
268 print " BIOS ACPI: ",bios.ACPIEnabled
269 print " PAE: ",mach.PAEEnabled
270 print " Hardware virtualization: ",asState(mach.HWVirtExEnabled)
271 print " Nested paging: ",asState(mach.HWVirtExNestedPagingEnabled)
272 print " Last changed: ",mach.lastStateChange
273
274 return 0
275
276def startCmd(ctx, args):
277 mach = argsToMach(ctx,args)
278 if mach == None:
279 return 0
280 if len(args) > 2:
281 type = args[2]
282 else:
283 type = "gui"
284 startVm(ctx['mgr'], ctx['vb'], mach, type, ctx['perf'])
285 return 0
286
287def pauseCmd(ctx, args):
288 mach = argsToMach(ctx,args)
289 if mach == None:
290 return 0
291 cmdExistingVm(ctx, mach, 'pause')
292 return 0
293
294def powerdownCmd(ctx, args):
295 mach = argsToMach(ctx,args)
296 if mach == None:
297 return 0
298 cmdExistingVm(ctx, mach, 'powerdown')
299 return 0
300
301def resumeCmd(ctx, args):
302 mach = argsToMach(ctx,args)
303 if mach == None:
304 return 0
305 cmdExistingVm(ctx, mach, 'resume')
306 return 0
307
308def statsCmd(ctx, args):
309 mach = argsToMach(ctx,args)
310 if mach == None:
311 return 0
312 cmdExistingVm(ctx, mach, 'stats')
313 return 0
314
315def setvarCmd(ctx, args):
316 if (len(args) < 4):
317 print "usage: setvar [vmname|uuid] expr value"
318 return 0
319 mach = argsToMach(ctx,args)
320 if mach == None:
321 return 0
322 vbox = ctx['vb']
323 session = ctx['mgr'].getSessionObject(vbox)
324 vbox.openSession(session, mach.id)
325 mach = session.machine
326 expr = 'mach.'+args[2]+' = '+args[3]
327 print "Executing",expr
328 try:
329 exec expr
330 except Exception, e:
331 print 'failed: ',e
332 if g_verbose:
333 traceback.print_exc()
334 mach.saveSettings()
335 session.close()
336 return 0
337
338def quitCmd(ctx, args):
339 return 1
340
341def aliasesCmd(ctx, args):
342 for (k,v) in aliases.items():
343 print "'%s' is an alias for '%s'" %(k,v)
344 return 0
345
346def verboseCmd(ctx, args):
347 global g_verbose
348 g_verbose = not g_verbose
349 return 0
350
351def hostCmd(ctx, args):
352 host = ctx['vb'].host
353 cnt = host.processorCount
354 print "Processor count:",cnt
355 for i in range(0,cnt):
356 print "Processor #%d speed: %dMHz" %(i,host.getProcessorSpeed(i))
357
358 for metric in ctx['perf'].query(["*"], [host]):
359 print metric['name'], metric['values_as_string']
360
361 return 0
362
363
364def evalCmd(ctx, args):
365 expr = ' '.join(args[1:])
366 try:
367 exec expr
368 except Exception, e:
369 print 'failed: ',e
370 if g_verbose:
371 traceback.print_exc()
372 return 0
373
374aliases = {'s':'start',
375 'i':'info',
376 'l':'list',
377 'h':'help',
378 'a':'aliases',
379 'q':'quit', 'exit':'quit',
380 'v':'verbose'}
381
382commands = {'help':['Prints help information', helpCmd],
383 'start':['Start virtual machine by name or uuid', startCmd],
384 'pause':['Pause virtual machine', pauseCmd],
385 'resume':['Resume virtual machine', resumeCmd],
386 'stats':['Stats for virtual machine', statsCmd],
387 'powerdown':['Power down virtual machine', powerdownCmd],
388 'list':['Shows known virtual machines', listCmd],
389 'info':['Shows info on machine', infoCmd],
390 'aliases':['Shows aliases', aliasesCmd],
391 'verbose':['Toggle verbosity', verboseCmd],
392 'setvar':['Set VMs variable: setvar Fedora BIOSSettings.ACPIEnabled True', setvarCmd],
393 'eval':['Evaluate arbitrary Python construction: eval for m in getMachines(ctx): print m.name,"has",m.memorySize,"M"', evalCmd],
394 'quit':['Exits', quitCmd],
395 'host':['Show host information', hostCmd]}
396
397def runCommand(ctx, cmd):
398 if len(cmd) == 0: return 0
399 args = split_no_quotes(cmd)
400 if len(args) == 0: return 0
401 c = args[0]
402 if aliases.get(c, None) != None:
403 c = aliases[c]
404 ci = commands.get(c,None)
405 if ci == None:
406 print "Unknown command: '%s', type 'help' for list of known commands" %(c)
407 return 0
408 return ci[1](ctx, args)
409
410
411def interpret(ctx):
412 vbox = ctx['vb']
413 print "Running VirtualBox version %s" %(vbox.version)
414
415 ctx['perf'] = PerfCollector(vbox)
416
417 autoCompletion(commands, ctx)
418
419 # to allow to print actual host information, we collect info for
420 # last 150 secs maximum, (sample every 10 secs and keep up to 15 samples)
421 try:
422 ctx['perf'].setup(['*'], [vbox.host], 10, 15)
423 except:
424 pass
425
426 while True:
427 try:
428 cmd = raw_input("vbox> ")
429 done = runCommand(ctx, cmd)
430 if done != 0: break
431 except KeyboardInterrupt:
432 print '====== You can type quit or q to leave'
433 break
434 except EOFError:
435 break;
436 except Exception,e:
437 print e
438 if g_verbose:
439 traceback.print_exc()
440
441 try:
442 # There is no need to disable metric collection. This is just an example.
443 ctx['perf'].disable(['*'], [vbox.host])
444 except:
445 pass
Note: See TracBrowser for help on using the repository browser.

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