Source code for virtualbox

"""Virtualbox API wrapper and Reference

Copyright (c) 2013 Michael Dorman (mjdorma@gmail.com). All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from __future__ import absolute_import
from contextlib import contextmanager
import os
import sys
import platform
import copy
import atexit
from multiprocessing import current_process

from virtualbox.library_ext import library


# Adopt on the library API root documentation
__doc__ = library.__doc__


VirtualBox = library.IVirtualBox
Session = library.ISession


[docs]@contextmanager def import_vboxapi(): """This import is designed to help when loading vboxapi inside of alternative Python environments (virtualenvs etc). :rtype: vboxapi module """ try: import vboxapi except ImportError: system = platform.system() py_mm_ver = sys.version_info[:2] packages = ['vboxapi'] if system == 'Windows': packages.extend(['win32com', 'win32', 'win32api', 'pywintypes', 'win32comext']) search = ['C:\\Python%s%s\\Lib\\site-packages' % py_mm_ver, 'C:\\Python%s%s\\Lib\\site-packages\\win32' % py_mm_ver, 'C:\\Python%s%s\\Lib\\site-packages\\win32\\lib' % py_mm_ver, 'C:\\Program Files\\Oracle\\VirtualBox\\sdk\\install', 'C:\\Program Files (x86)\\Oracle\\VirtualBox\\sdk\\install'] elif system == 'Linux': search = ['/usr/lib/python%s.%s/dist-packages' % py_mm_ver, '/usr/lib/python%s.%s/site-packages' % py_mm_ver, '/usr/share/pyshared'] elif system == 'Darwin': search = ['/Library/Python/%s.%s/site-packages' % py_mm_ver] else: # No idea where to look... search = [] # Generates a common prefix from sys.executable in the # case that vboxapi is installed in a virtualenv. # This will also help with when we don't know where # to search because of an unknown platform. # These paths also help if the system Python is installed # in a non-standard location. # # NOTE: We don't have to worry if these directories don't # exist as they're checked below. prefix = os.path.dirname(os.path.dirname(sys.executable)) search.extend([os.path.join(prefix, 'Lib', 'site-packages'), os.path.join(prefix, 'Lib', 'site-packages', 'win32'), os.path.join(prefix, 'Lib', 'site-packages', 'win32', 'lib'), os.path.join(prefix, 'lib', 'site-packages'), os.path.join(prefix, 'lib', 'dist-packages')]) packages = set(packages) original_path = copy.copy(sys.path) for path in search: if not os.path.isdir(path): continue listing = set([os.path.splitext(f)[0] for f in os.listdir(path)]) if packages.intersection(listing): sys.path.append(path) packages -= listing if not packages: break else: # After search each path we still failed to find # the required set of packages. raise import vboxapi try: yield vboxapi finally: sys.path = original_path else: yield vboxapi
_managers = {}
[docs]class Manager(object): """The Manager maintains a single point of entry into vboxapi. This object is responsible for the construction of :py:class:`virtualbox.library_ext.ISession` and :py:class:`virtualbox.library_ext.IVirtualBox`. :param mtype: Type of manager i.e. WEBSERVICE. :type mtype: str (Default None) :param mparams: The params that the mtype manager object accepts. :type mparams: tuple|list (Default None) """ def __init__(self, mtype=None, mparams=None): pid = current_process().ident if _managers is None: raise RuntimeError("Can not create a new manager following a system exit.") if pid not in _managers: with import_vboxapi() as vboxapi: self.manager = vboxapi.VirtualBoxManager(mtype, mparams) @property def manager(self): """Create a default Manager object Builds a singleton VirtualBoxManager object. Note: It is not necessary to build this object when defining a Session or VirtualBox object as both of these classes will default to this object's global singleton during construction. """ if _managers is None: raise RuntimeError("Can not get the manager following a system exit.") return _managers[current_process().ident] @manager.setter def manager(self, value): "Set the manager object in the global _managers dict." pid = current_process().ident if _managers is None: raise RuntimeError("Can not set the manager following a system exit.") if pid not in _managers: _managers[pid] = value else: raise Exception("Manager already set for pid %s" % pid)
[docs] def get_virtualbox(self): """Return a VirtualBox interface :rtype: library.IVirtualBox """ return VirtualBox(interface=self.manager.getVirtualBox())
[docs] def get_session(self): """Return a Session interface :rtype: library.ISession """ # The inconsistent vboxapi implementation makes this annoying... if hasattr(self.manager, 'mgr'): manager = getattr(self.manager, 'mgr') else: manager = self.manager return Session(interface=manager.getSessionObject(None))
[docs] def cast_object(self, interface_object, interface_class): """Cast the obj to the interface class :rtype: interface_class(interface_object) """ name = interface_class.__name__ i = self.manager.queryInterface(interface_object._i, name) return interface_class(interface=i)
@property def bin_path(self): """return the virtualbox install directory :rtype: str """ return self.manager.getBinDir()
# Attempt to close left over manager objects cleanly. def _cleanup_managers(): global _managers managers = _managers _managers = None for manager in managers.values(): try: del manager except: pass managers.clear() atexit.register(_cleanup_managers)
[docs]class WebServiceManager(Manager): """The WebServiceManager extends the base Manager to include the ability to build a WEBSERVICE type vboxapi interface. """ def __init__(self, url='http://localhost/', user='', password=''): """Create a VirtualBoxManager WEBSERVICE manager for IVirtualBox Options: url - url to connect with the VirtualBox server user - username used to auth to the VirtualBox server service password - password used to auth to the VirtualBox server service Example: manager = WebServiceManager(user="mick", password="password") vbox = VirtualBox(manager=manager) ... """ params = {"url": url, "user": user, "password": password} super(WebServiceManager, self).__init__("WEBSERVICE", params)
# Lazy include... from virtualbox import pool # noqa: F401 from virtualbox import events # noqa: F401 from virtualbox import version # noqa: F401 from virtualbox.version import __version__ # noqa: F401