VirtualBox

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

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

Python Shell: update remove command with HDD detach code

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 15.5 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 session.close()
157
158def removeVm(ctx,mach):
159 mgr = ctx['mgr']
160 vb = ctx['vb']
161 id = mach.id
162 print "removing machine ",mach.name,"with UUID",id
163 session = ctx['mgr'].getSessionObject(vb)
164 vb.openSession(session, id)
165 mach=session.machine
166 for d in mach.getHardDiskAttachments():
167 mach.detachHardDisk(d.controller, d.port, d.device)
168 session.close()
169 mach = vb.unregisterMachine(id)
170 if mach:
171 mach.deleteSettings()
172
173def startVm(ctx,mach,type):
174 mgr = ctx['mgr']
175 vb = ctx['vb']
176 perf = ctx['perf']
177 session = mgr.getSessionObject(vb)
178 uuid = mach.id
179 progress = vb.openRemoteSession(session, uuid, type, "")
180 progress.waitForCompletion(-1)
181 completed = progress.completed
182 rc = int(progress.resultCode)
183 print "Completed:", completed, "rc:",hex(rc&0xffffffff)
184 if rc == 0:
185 # we ignore exceptions to allow starting VM even if
186 # perf collector cannot be started
187 if perf:
188 try:
189 perf.setup(['*'], [mach], 10, 15)
190 except Exception,e:
191 print e
192 if g_verbose:
193 traceback.print_exc()
194 pass
195 # if session not opened, close doesn't make sense
196 session.close()
197 else:
198 # Not yet implemented error string query API for remote API
199 if not ctx['remote']:
200 print session.QueryErrorObject(rc)
201
202def getMachines(ctx):
203 # XPCOM brigde has trouble with array attributes
204 if ctx['type'] == 'xpcom':
205 return ctx['vb'].getMachines()
206 else:
207 return ctx['vb'].machines
208
209def asState(var):
210 if var:
211 return 'on'
212 else:
213 return 'off'
214
215def guestStats(ctx,mach):
216 if not ctx['perf']:
217 return
218 for metric in ctx['perf'].query(["*"], [mach]):
219 print metric['name'], metric['values_as_string']
220
221def guestExec(ctx, machine, console, cmds):
222 exec cmds
223
224def cmdExistingVm(ctx,mach,cmd,args):
225 mgr=ctx['mgr']
226 vb=ctx['vb']
227 session = mgr.getSessionObject(vb)
228 uuid = mach.id
229 try:
230 progress = vb.openExistingSession(session, uuid)
231 except Exception,e:
232 print "Session to '%s' not open: %s" %(mach.name,e)
233 if g_verbose:
234 traceback.print_exc()
235 return
236 if session.state != ctx['ifaces'].SessionState.Open:
237 print "Session to '%s' in wrong state: %s" %(mach.name, session.state)
238 return
239 # unfortunately IGuest is suppressed, thus WebServices knows not about it
240 # this is an example how to handle local only functionality
241 if ctx['remote'] and cmd == 'stats2':
242 print 'Trying to use local only functionality, ignored'
243 return
244 console=session.console
245 ops={'pause' : lambda: console.pause(),
246 'resume': lambda: console.resume(),
247 'powerdown': lambda: console.powerDown(),
248 'stats': lambda: guestStats(ctx, mach),
249 'guest': lambda: guestExec(ctx, mach, console, args)
250 }
251 try:
252 ops[cmd]()
253 except Exception, e:
254 print 'failed: ',e
255 if g_verbose:
256 traceback.print_exc()
257
258 session.close()
259
260# can cache known machines, if needed
261def machById(ctx,id):
262 mach = None
263 for m in getMachines(ctx):
264 if m.name == id:
265 mach = m
266 break
267 mid = str(m.id)
268 if mid[0] == '{':
269 mid = mid[1:-1]
270 if mid == id:
271 mach = m
272 break
273 return mach
274
275def argsToMach(ctx,args):
276 if len(args) < 2:
277 print "usage: %s [vmname|uuid]" %(args[0])
278 return None
279 id = args[1]
280 m = machById(ctx, id)
281 if m == None:
282 print "Machine '%s' is unknown, use list command to find available machines" %(id)
283 return m
284
285def helpCmd(ctx, args):
286 if len(args) == 1:
287 print "Help page:"
288 for i in commands:
289 print " ",i,":", commands[i][0]
290 else:
291 c = commands.get(args[1], None)
292 if c == None:
293 print "Command '%s' not known" %(args[1])
294 else:
295 print " ",args[1],":", c[0]
296 return 0
297
298def listCmd(ctx, args):
299 for m in getMachines(ctx):
300 print "Machine '%s' [%s], state=%s" %(m.name,m.id,m.sessionState)
301 return 0
302
303def infoCmd(ctx,args):
304 if (len(args) < 2):
305 print "usage: info [vmname|uuid]"
306 return 0
307 mach = argsToMach(ctx,args)
308 if mach == None:
309 return 0
310 os = ctx['vb'].getGuestOSType(mach.OSTypeId)
311 print " Name: ",mach.name
312 print " ID: ",mach.id
313 print " OS Type: ",os.description
314 print " RAM: %dM" %(mach.memorySize)
315 print " VRAM: %dM" %(mach.VRAMSize)
316 print " Clipboard mode: %d" %(mach.clipboardMode)
317 print " Machine status: " ,mach.sessionState
318 bios = mach.BIOSSettings
319 print " BIOS ACPI: ",bios.ACPIEnabled
320 print " PAE: ",mach.PAEEnabled
321 print " Hardware virtualization: ",asState(mach.HWVirtExEnabled)
322 print " Nested paging: ",asState(mach.HWVirtExNestedPagingEnabled)
323 print " Last changed: ",mach.lastStateChange
324
325 return 0
326
327def startCmd(ctx, args):
328 mach = argsToMach(ctx,args)
329 if mach == None:
330 return 0
331 if len(args) > 2:
332 type = args[2]
333 else:
334 type = "gui"
335 startVm(ctx, mach, type)
336 return 0
337
338def createCmd(ctx, args):
339 if (len(args) < 3 or len(args) > 4):
340 print "usage: create name ostype <basefolder>"
341 return 0
342 name = args[1]
343 oskind = args[2]
344 if len(args) == 4:
345 base = args[3]
346 else:
347 base = ''
348 try:
349 ctx['vb'].getGuestOSType(oskind)
350 except Exception, e:
351 print 'Unknown OS type:',oskind
352 return 0
353 createVm(ctx, name, oskind, base)
354 return 0
355
356def removeCmd(ctx, args):
357 mach = argsToMach(ctx,args)
358 if mach == None:
359 return 0
360 removeVm(ctx, mach)
361 return 0
362
363def pauseCmd(ctx, args):
364 mach = argsToMach(ctx,args)
365 if mach == None:
366 return 0
367 cmdExistingVm(ctx, mach, 'pause', '')
368 return 0
369
370def powerdownCmd(ctx, args):
371 mach = argsToMach(ctx,args)
372 if mach == None:
373 return 0
374 cmdExistingVm(ctx, mach, 'powerdown', '')
375 return 0
376
377def resumeCmd(ctx, args):
378 mach = argsToMach(ctx,args)
379 if mach == None:
380 return 0
381 cmdExistingVm(ctx, mach, 'resume', '')
382 return 0
383
384def statsCmd(ctx, args):
385 mach = argsToMach(ctx,args)
386 if mach == None:
387 return 0
388 cmdExistingVm(ctx, mach, 'stats', '')
389 return 0
390
391def guestCmd(ctx, args):
392 if (len(args) < 3):
393 print "usage: guest name commands"
394 return 0
395 mach = argsToMach(ctx,args)
396 if mach == None:
397 return 0
398 cmdExistingVm(ctx, mach, 'guest', ' '.join(args[2:]))
399 return 0
400
401def setvarCmd(ctx, args):
402 if (len(args) < 4):
403 print "usage: setvar [vmname|uuid] expr value"
404 return 0
405 mach = argsToMach(ctx,args)
406 if mach == None:
407 return 0
408 vbox = ctx['vb']
409 session = ctx['mgr'].getSessionObject(vbox)
410 vbox.openSession(session, mach.id)
411 mach = session.machine
412 expr = 'mach.'+args[2]+' = '+args[3]
413 print "Executing",expr
414 try:
415 exec expr
416 except Exception, e:
417 print 'failed: ',e
418 if g_verbose:
419 traceback.print_exc()
420 mach.saveSettings()
421 session.close()
422 return 0
423
424def quitCmd(ctx, args):
425 return 1
426
427def aliasesCmd(ctx, args):
428 for (k,v) in aliases.items():
429 print "'%s' is an alias for '%s'" %(k,v)
430 return 0
431
432def verboseCmd(ctx, args):
433 global g_verbose
434 g_verbose = not g_verbose
435 return 0
436
437def hostCmd(ctx, args):
438 host = ctx['vb'].host
439 cnt = host.processorCount
440 print "Processor count:",cnt
441 for i in range(0,cnt):
442 print "Processor #%d speed: %dMHz" %(i,host.getProcessorSpeed(i))
443
444 if ctx['perf']:
445 for metric in ctx['perf'].query(["*"], [host]):
446 print metric['name'], metric['values_as_string']
447
448 return 0
449
450
451def evalCmd(ctx, args):
452 expr = ' '.join(args[1:])
453 try:
454 exec expr
455 except Exception, e:
456 print 'failed: ',e
457 if g_verbose:
458 traceback.print_exc()
459 return 0
460
461aliases = {'s':'start',
462 'i':'info',
463 'l':'list',
464 'h':'help',
465 'a':'aliases',
466 'q':'quit', 'exit':'quit',
467 'v':'verbose'}
468
469commands = {'help':['Prints help information', helpCmd],
470 'start':['Start virtual machine by name or uuid', startCmd],
471 'create':['Create virtual machine', createCmd],
472 'remove':['Remove virtual machine', removeCmd],
473 'pause':['Pause virtual machine', pauseCmd],
474 'resume':['Resume virtual machine', resumeCmd],
475 'stats':['Stats for virtual machine', statsCmd],
476 'powerdown':['Power down virtual machine', powerdownCmd],
477 'list':['Shows known virtual machines', listCmd],
478 'info':['Shows info on machine', infoCmd],
479 'aliases':['Shows aliases', aliasesCmd],
480 'verbose':['Toggle verbosity', verboseCmd],
481 'setvar':['Set VMs variable: setvar Fedora BIOSSettings.ACPIEnabled True', setvarCmd],
482 'eval':['Evaluate arbitrary Python construction: eval for m in getMachines(ctx): print m.name,"has",m.memorySize,"M"', evalCmd],
483 'quit':['Exits', quitCmd],
484 'host':['Show host information', hostCmd],
485 'guest':['Execute command for guest: guest Win32 console.mouse.putMouseEvent(20, 20, 0, 0)', guestCmd],
486 }
487
488def runCommand(ctx, cmd):
489 if len(cmd) == 0: return 0
490 args = split_no_quotes(cmd)
491 if len(args) == 0: return 0
492 c = args[0]
493 if aliases.get(c, None) != None:
494 c = aliases[c]
495 ci = commands.get(c,None)
496 if ci == None:
497 print "Unknown command: '%s', type 'help' for list of known commands" %(c)
498 return 0
499 return ci[1](ctx, args)
500
501
502def interpret(ctx):
503 vbox = ctx['vb']
504 print "Running VirtualBox version %s" %(vbox.version)
505
506 # MSCOM doesn't work with collector yet
507 if ctx['type'] != 'mscom':
508 ctx['perf'] = PerfCollector(vbox)
509 else:
510 ctx['perf'] = None
511
512 autoCompletion(commands, ctx)
513
514 # to allow to print actual host information, we collect info for
515 # last 150 secs maximum, (sample every 10 secs and keep up to 15 samples)
516 if ctx['perf']:
517 try:
518 ctx['perf'].setup(['*'], [vbox.host], 10, 15)
519 except:
520 pass
521
522 while True:
523 try:
524 cmd = raw_input("vbox> ")
525 done = runCommand(ctx, cmd)
526 if done != 0: break
527 except KeyboardInterrupt:
528 print '====== You can type quit or q to leave'
529 break
530 except EOFError:
531 break;
532 except Exception,e:
533 print e
534 if g_verbose:
535 traceback.print_exc()
536
537 try:
538 # There is no need to disable metric collection. This is just an example.
539 if ct['perf']:
540 ctx['perf'].disable(['*'], [vbox.host])
541 except:
542 pass
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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