VirtualBox

source: vbox/trunk/src/VBox/Main/glue/vboxapi.py@ 21370

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

Python: glue array naming typo

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.6 KB
Line 
1#
2# Copyright (C) 2009 Sun Microsystems, Inc.
3#
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# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
13# Clara, CA 95054 USA or visit http://www.sun.com if you need
14# additional information or have any questions.
15#
16import sys,os
17import traceback
18
19VboxBinDir = os.environ.get("VBOX_PROGRAM_PATH", None)
20VboxSdkDir = os.environ.get("VBOX_SDK_PATH", None)
21
22if VboxBinDir is None:
23 # Will be set by the installer
24 VboxBinDir = "%VBOX_INSTALL_PATH%"
25
26if VboxSdkDir is None:
27 VboxSdkDir = VboxBinDir+"/sdk"
28
29os.environ["VBOX_PROGRAM_PATH"] = VboxBinDir
30os.environ["VBOX_SDK_PATH"] = VboxSdkDir
31sys.path.append(VboxBinDir)
32
33from VirtualBox_constants import VirtualBoxReflectionInfo
34
35class PerfCollector:
36 """ This class provides a wrapper over IPerformanceCollector in order to
37 get more 'pythonic' interface.
38
39 To begin collection of metrics use setup() method.
40
41 To get collected data use query() method.
42
43 It is possible to disable metric collection without changing collection
44 parameters with disable() method. The enable() method resumes metric
45 collection.
46 """
47
48 def __init__(self, vb):
49 """ Initializes the instance.
50
51 Pass an instance of IVirtualBox as parameter.
52 """
53 self.collector = vb.performanceCollector
54
55 def setup(self, names, objects, period, nsamples):
56 """ Discards all previously collected values for the specified
57 metrics, sets the period of collection and the number of retained
58 samples, enables collection.
59 """
60 self.collector.setupMetrics(names, objects, period, nsamples)
61
62 def enable(self, names, objects):
63 """ Resumes metric collection for the specified metrics.
64 """
65 self.collector.enableMetrics(names, objects)
66
67 def disable(self, names, objects):
68 """ Suspends metric collection for the specified metrics.
69 """
70 self.collector.disableMetrics(names, objects)
71
72 def query(self, names, objects):
73 """ Retrieves collected metric values as well as some auxiliary
74 information. Returns an array of dictionaries, one dictionary per
75 metric. Each dictionary contains the following entries:
76 'name': metric name
77 'object': managed object this metric associated with
78 'unit': unit of measurement
79 'scale': divide 'values' by this number to get float numbers
80 'values': collected data
81 'values_as_string': pre-processed values ready for 'print' statement
82 """
83 # Get around the problem with input arrays returned in output parameters (see #3953).
84 if sys.platform == 'win32':
85 (values, names, objects, names_out, objects_out, units, scales, sequence_numbers,
86 indices, lengths) = self.collector.queryMetricsData(names, objects)
87 else:
88 (values, names_out, objects_out, units, scales, sequence_numbers,
89 indices, lengths) = self.collector.queryMetricsData(names, objects)
90 out = []
91 for i in xrange(0, len(names_out)):
92 scale = int(scales[i])
93 if scale != 1:
94 fmt = '%.2f%s'
95 else:
96 fmt = '%d %s'
97 out.append({
98 'name':str(names_out[i]),
99 'object':str(objects_out[i]),
100 'unit':str(units[i]),
101 'scale':scale,
102 'values':[int(values[j]) for j in xrange(int(indices[i]), int(indices[i])+int(lengths[i]))],
103 'values_as_string':'['+', '.join([fmt % (int(values[j])/scale, units[i]) for j in xrange(int(indices[i]), int(indices[i])+int(lengths[i]))])+']'
104 })
105 return out
106
107def ComifyName(name):
108 return name[0].capitalize()+name[1:]
109
110_COMForward = { 'getattr' : None,
111 'setattr' : None}
112
113def CustomGetAttr(self, attr):
114 # fastpath
115 if self.__class__.__dict__.get(attr) != None:
116 return self.__class__.__dict__.get(attr)
117
118 # try case-insensitivity workaround for class attributes (COM methods)
119 for k in self.__class__.__dict__.keys():
120 if k.lower() == attr.lower():
121 self.__class__.__dict__[attr] = self.__class__.__dict__[k]
122 return getattr(self, k)
123 try:
124 return _COMForward['getattr'](self,ComifyName(attr))
125 except AttributeError:
126 return _COMForward['getattr'](self,attr)
127
128def CustomSetAttr(self, attr, value):
129 try:
130 return _COMForward['setattr'](self, ComifyName(attr), value)
131 except AttributeError:
132 return _COMForward['setattr'](self, attr, value)
133
134class PlatformMSCOM:
135 # Class to fake access to constants in style of foo.bar.boo
136 class ConstantFake:
137 def __init__(self, parent, name):
138 self.__dict__['_parent'] = parent
139 self.__dict__['_name'] = name
140 self.__dict__['_consts'] = {}
141 try:
142 self.__dict__['_depth']=parent.__dict__['_depth']+1
143 except:
144 self.__dict__['_depth']=0
145 if self.__dict__['_depth'] > 4:
146 raise AttributeError
147
148 def __getattr__(self, attr):
149 import win32com
150 from win32com.client import constants
151
152 if attr.startswith("__"):
153 raise AttributeError
154
155 consts = self.__dict__['_consts']
156
157 fake = consts.get(attr, None)
158 if fake != None:
159 return fake
160 try:
161 name = self.__dict__['_name']
162 parent = self.__dict__['_parent']
163 while parent != None:
164 if parent._name is not None:
165 name = parent._name+'_'+name
166 parent = parent._parent
167
168 if name is not None:
169 name += "_" + attr
170 else:
171 name = attr
172 return win32com.client.constants.__getattr__(name)
173 except AttributeError,e:
174 fake = PlatformMSCOM.ConstantFake(self, attr)
175 consts[attr] = fake
176 return fake
177
178
179 class InterfacesWrapper:
180 def __init__(self):
181 self.__dict__['_rootFake'] = PlatformMSCOM.ConstantFake(None, None)
182
183 def __getattr__(self, a):
184 import win32com
185 from win32com.client import constants
186 if a.startswith("__"):
187 raise AttributeError
188 try:
189 return win32com.client.constants.__getattr__(a)
190 except AttributeError,e:
191 return self.__dict__['_rootFake'].__getattr__(a)
192
193 VBOX_TLB_GUID = '{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}'
194 VBOX_TLB_LCID = 0
195 VBOX_TLB_MAJOR = 1
196 VBOX_TLB_MINOR = 0
197
198 def __init__(self, params):
199 from win32com import universal
200 from win32com.client import gencache, DispatchBaseClass
201 from win32com.client import constants, getevents
202 import win32com
203 import pythoncom
204 import win32api
205 self.constants = PlatformMSCOM.InterfacesWrapper()
206 from win32con import DUPLICATE_SAME_ACCESS
207 from win32api import GetCurrentThread,GetCurrentThreadId,DuplicateHandle,GetCurrentProcess
208 pid = GetCurrentProcess()
209 self.tid = GetCurrentThreadId()
210 handle = DuplicateHandle(pid, GetCurrentThread(), pid, 0, 0, DUPLICATE_SAME_ACCESS)
211 self.handles = []
212 self.handles.append(handle)
213 _COMForward['getattr'] = DispatchBaseClass.__dict__['__getattr__']
214 DispatchBaseClass.__dict__['__getattr__'] = CustomGetAttr
215 _COMForward['setattr'] = DispatchBaseClass.__dict__['__setattr__']
216 DispatchBaseClass.__dict__['__setattr__'] = CustomSetAttr
217 win32com.client.gencache.EnsureDispatch('VirtualBox.Session')
218 win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBox')
219
220 def getSessionObject(self, vbox):
221 import win32com
222 from win32com.client import Dispatch
223 return win32com.client.Dispatch("VirtualBox.Session")
224
225 def getVirtualBox(self):
226 import win32com
227 from win32com.client import Dispatch
228 return win32com.client.Dispatch("VirtualBox.VirtualBox")
229
230 def getConstants(self):
231 return self.constants
232
233 def getType(self):
234 return 'MSCOM'
235
236 def getRemote(self):
237 return False
238
239 def getArray(self, obj, field):
240 return obj.__getattr__(field)
241
242 def initPerThread(self):
243 import pythoncom
244 pythoncom.CoInitializeEx(0)
245
246 def deinitPerThread(self):
247 import pythoncom
248 pythoncom.CoUninitialize()
249
250 def createCallback(self, iface, impl, arg):
251 d = {}
252 d['BaseClass'] = impl
253 d['arg'] = arg
254 d['tlb_guid'] = PlatformMSCOM.VBOX_TLB_GUID
255 str = ""
256 str += "import win32com.server.util\n"
257 #str += "import win32com.server.register\n"
258 #str += "from win32com import universal\n"
259 str += "import pythoncom\n"
260 #str += "universal.RegisterInterfaces(tlb_guid, 0, 1, 0, ['"+iface+"'])\n"
261
262 str += "class "+iface+"Impl(BaseClass):\n"
263 str += " _com_interfaces_ = ['"+iface+"']\n"
264 str += " _typelib_guid_ = tlb_guid\n"
265 str += " _typelib_version_ = 1, 0\n"
266 #str += " _reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER\n"
267 #str += " _reg_clsid_ = '{F21202A2-959A-4149-B1C3-68B9013F3335}'\n"
268 #str += " _reg_progid_ = 'VirtualBox."+iface+"Impl'\n"
269 #str += " _reg_desc_ = 'Generated callback implementation class'\n"
270 #str += " _reg_policy_spec_ = 'win32com.server.policy.EventHandlerPolicy'\n"
271
272 # generate capitalized version of callbacks - that's how Python COM
273 # looks them up on Windows
274 for m in dir(impl):
275 if m.startswith("on"):
276 str += " "+ComifyName(m)+"=BaseClass."+m+"\n"
277
278 str += " def __init__(self): BaseClass.__init__(self, arg)\n"
279 #str += "win32com.server.register.UseCommandLine("+iface+"Impl)\n"
280
281 str += "result = win32com.server.util.wrap("+iface+"Impl())\n"
282 exec (str,d,d)
283 return d['result']
284
285 def waitForEvents(self, timeout):
286 from win32api import GetCurrentThreadId
287 from win32event import MsgWaitForMultipleObjects, \
288 QS_ALLINPUT, WAIT_TIMEOUT, WAIT_OBJECT_0
289 from pythoncom import PumpWaitingMessages
290
291 if (self.tid != GetCurrentThreadId()):
292 raise Exception("wait for events from the same thread you inited!")
293
294 rc = MsgWaitForMultipleObjects(self.handles, 0, timeout, QS_ALLINPUT)
295 if rc >= WAIT_OBJECT_0 and rc < WAIT_OBJECT_0+len(self.handles):
296 # is it possible?
297 pass
298 elif rc==WAIT_OBJECT_0 + len(self.handles):
299 # Waiting messages
300 PumpWaitingMessages()
301 else:
302 # Timeout
303 pass
304
305 def deinit(self):
306 import pythoncom
307 from win32file import CloseHandle
308
309 for h in self.handles:
310 if h is not None:
311 CloseHandle(h)
312 self.handles = None
313 pythoncom.CoUninitialize()
314 pass
315
316 def getPerfCollector(self, vbox):
317 return PerfCollector(vbox)
318
319
320class PlatformXPCOM:
321 def __init__(self, params):
322 sys.path.append(VboxSdkDir+'/bindings/xpcom/python/')
323 import xpcom.vboxxpcom
324 import xpcom
325 import xpcom.components
326
327 def getSessionObject(self, vbox):
328 import xpcom.components
329 return xpcom.components.classes["@virtualbox.org/Session;1"].createInstance()
330
331 def getVirtualBox(self):
332 import xpcom.components
333 return xpcom.components.classes["@virtualbox.org/VirtualBox;1"].createInstance()
334
335 def getConstants(self):
336 import xpcom.components
337 return xpcom.components.interfaces
338
339 def getType(self):
340 return 'XPCOM'
341
342 def getRemote(self):
343 return False
344
345 def getArray(self, obj, field):
346 return obj.__getattr__('get'+ComifyName(field))()
347
348 def initPerThread(self):
349 pass
350
351 def deinitPerThread(self):
352 pass
353
354 def createCallback(self, iface, impl, arg):
355 d = {}
356 d['BaseClass'] = impl
357 d['arg'] = arg
358 str = ""
359 str += "import xpcom.components\n"
360 str += "class "+iface+"Impl(BaseClass):\n"
361 str += " _com_interfaces_ = xpcom.components.interfaces."+iface+"\n"
362 str += " def __init__(self): BaseClass.__init__(self, arg)\n"
363 str += "result = "+iface+"Impl()\n"
364 exec (str,d,d)
365 return d['result']
366
367 def waitForEvents(self, timeout):
368 import xpcom
369 xpcom._xpcom.WaitForEvents(timeout)
370
371 def deinit(self):
372 import xpcom
373 xpcom._xpcom.DeinitCOM()
374
375 def getPerfCollector(self, vbox):
376 return PerfCollector(vbox)
377
378class PlatformWEBSERVICE:
379 def __init__(self, params):
380 sys.path.append(VboxSdkDir+'/bindings/webservice/python/lib')
381 import VirtualBox_services
382 import VirtualBox_wrappers
383 from VirtualBox_wrappers import IWebsessionManager2
384 if params is not None:
385 self.user = params.get("user", "")
386 self.password = params.get("password", "")
387 self.url = params.get("url", "")
388 else:
389 self.user = ""
390 self.password = ""
391 self.url = None
392 self.wsmgr = IWebsessionManager2(self.url)
393
394 def getSessionObject(self, vbox):
395 return self.wsmgr.getSessionObject(vbox)
396
397 def getVirtualBox(self):
398 self.vbox = self.wsmgr.logon(self.user, self.password)
399
400 def getConstants(self):
401 return None
402
403 def getType(self):
404 return 'WEBSERVICE'
405
406 def getRemote(self):
407 return True
408
409 def getArray(self, obj, field):
410 return obj.__getattr__(field)
411
412 def initPerThread(self):
413 pass
414
415 def deinitPerThread(self):
416 pass
417
418 def createCallback(self, iface, impl, arg):
419 raise Exception("no callbacks for webservices")
420
421 def waitForEvents(self, timeout):
422 # Webservices cannot do that yet
423 pass
424
425 def deinit(self):
426 try:
427 if self.vbox is not None:
428 self.wsmg.logoff(self.vbox)
429 self.vbox = None
430 except:
431 pass
432
433 def getPerfCollector(self, vbox):
434 return PerfCollector(vbox)
435
436class SessionManager:
437 def __init__(self, mgr):
438 self.mgr = mgr
439
440 def getSessionObject(self, vbox):
441 return self.mgr.platform.getSessionObject(vbox)
442
443class VirtualBoxManager:
444 def __init__(self, style, platparams):
445 if style is None:
446 if sys.platform == 'win32':
447 style = "MSCOM"
448 else:
449 style = "XPCOM"
450 try:
451 exec "self.platform = Platform"+style+"(platparams)"
452 self.vbox = self.platform.getVirtualBox()
453 self.mgr = SessionManager(self)
454 self.constants = VirtualBoxReflectionInfo()
455 self.type = self.platform.getType()
456 self.remote = self.platform.getRemote()
457 self.style = style
458 except Exception,e:
459 print "init exception: ",e
460 traceback.print_exc()
461 raise e
462
463 def getArray(self, obj, field):
464 return self.platform.getArray(obj, field)
465
466 def getVirtualBox(self):
467 return self.platform.getVirtualBox()
468
469 def __del__(self):
470 self.deinit()
471
472 def deinit(self):
473 if hasattr(self, "vbox"):
474 del self.vbox
475 self.vbox = None
476 if hasattr(self, "platform"):
477 self.platform.deinit()
478 self.platform = None
479
480 def initPerThread(self):
481 self.platform.initPerThread()
482
483 def openMachineSession(self, machineId):
484 session = self.mgr.getSessionObject(self.vbox)
485 self.vbox.openSession(session, machineId)
486 return session
487
488 def closeMachineSession(self, session):
489 session.close()
490
491 def deinitPerThread(self):
492 self.platform.deinitPerThread()
493
494 def createCallback(self, iface, impl, arg):
495 return self.platform.createCallback(iface, impl, arg)
496
497 def waitForEvents(self, timeout):
498 return self.platform.waitForEvents(timeout)
499
500 def getPerfCollector(self, vbox):
501 return PerfCollector(vbox)
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