Exemple #1
0
class VirtualBox(Wrapper):
    # Properties directly inherited from IVirtualMachine
    _passthruProperties = [
        "homeFolder",
        "packageType",
        "revision",
        "settingsFilePath",
        "version",

        # Also allow direct access to these methods. These shouldn't
        # be used directly, buy only by other pyVBox classes.
        "createMachine",
        "findMachine",
        "getMachine",
        "openExistingSession",
        "openMachine",
        "openRemoteSession",
        "openSession",
        "registerMachine",
        ]

    def __init__(self):
        self._manager = VirtualBoxManager()
        self._wrappedInstance = self._manager.getIVirtualBox()

    def getGuestOSType(self, osTypeId):
        """Returns an object describing the specified guest OS type."""
        iosType = self._wrappedInstance.getGuestOSType(osTypeId)
        return GuestOSType(iosType)

    @property
    def guestOSTypes(self):
        """Return an array of all available guest OS Types."""
        return [GuestOSType(t) for t in self._getArray('guestOSTypes')]

    @property
    def machines(self):
        """Return array of machine objects registered within this VirtualBox instance."""
        from VirtualMachine import VirtualMachine
        return [VirtualMachine(vm) for vm in self._getArray('machines')]

    def waitForEvent(self):
        self._manager.waitForEvents()

    def _getArray(self, arrayName):
        """Return the array identified by the given name"""
        return self._manager.getArray(self._wrappedInstance, arrayName)
Exemple #2
0
class VirtualBox(Wrapper):
    # Properties directly inherited from IVirtualMachine
    _passthruProperties = [
        "homeFolder",
        "packageType",
        "revision",
        "settingsFilePath",
        "version",

        # Also allow direct access to these methods. These shouldn't
        # be used directly, buy only by other pyVBox classes.
        "createMachine",
        "findMachine",
        "getMachine",
        "openExistingSession",
        "openMachine",
        "openRemoteSession",
        "openSession",
        "registerMachine",
    ]

    def __init__(self):
        self._manager = VirtualBoxManager()
        self._wrappedInstance = self._manager.getIVirtualBox()

    def getGuestOSType(self, osTypeId):
        """Returns an object describing the specified guest OS type."""
        iosType = self._wrappedInstance.getGuestOSType(osTypeId)
        return GuestOSType(iosType)

    @property
    def guestOSTypes(self):
        """Return an array of all available guest OS Types."""
        return [GuestOSType(t) for t in self._getArray('guestOSTypes')]

    @property
    def machines(self):
        """Return array of machine objects registered within this VirtualBox instance."""
        from VirtualMachine import VirtualMachine
        return [VirtualMachine(vm) for vm in self._getArray('machines')]

    def waitForEvent(self):
        self._manager.waitForEvents()

    def _getArray(self, arrayName):
        """Return the array identified by the given name"""
        return self._manager.getArray(self._wrappedInstance, arrayName)
Exemple #3
0
class VirtualBoxMonitor:
    def __init__(self, vbox):
        self._vbox = vbox
        self._manager = VirtualBoxManager()
        self._isMscom = self._manager.isMSCOM()

    def onMachineStateChange(self, id, state):
        pass

    def onMachineDataChange(self, id):
        pass

    def onExtraDataCanChange(self, id, key, value):
        # Witty COM bridge thinks if someone wishes to return tuple, hresult
        # is one of values we want to return
        if self._isMscom:
            return "", 0, True
        else:
            return True, ""

    def onExtraDataChange(self, id, key, value):
        pass

    def onMediaRegistered(self, id, type, registered):
        pass

    def onMachineRegistered(self, id, registred):
        pass

    def onSessionStateChange(self, id, state):
        pass

    def onSnapshotTaken(self, mach, id):
        pass

    def onSnapshotDiscarded(self, mach, id):
        pass

    def onSnapshotChange(self, mach, id):
        pass

    def onGuestPropertyChange(self, id, name, newValue, flags):
        pass
Exemple #4
0
class VirtualBoxMonitor:
    def __init__(self, vbox):
        self._vbox = vbox
        self._manager = VirtualBoxManager()
        self._isMscom = self._manager.isMSCOM()

    def onMachineStateChange(self, id, state):
        pass

    def onMachineDataChange(self, id):
        pass

    def onExtraDataCanChange(self, id, key, value):
        # Witty COM bridge thinks if someone wishes to return tuple, hresult
        # is one of values we want to return
        if self._isMscom:
            return "", 0, True
        else:
            return True, ""

    def onExtraDataChange(self, id, key, value):
        pass

    def onMediaRegistered(self, id, type, registered):
        pass

    def onMachineRegistered(self, id, registred):
        pass

    def onSessionStateChange(self, id, state):
        pass

    def onSnapshotTaken(self, mach, id):
        pass

    def onSnapshotDiscarded(self, mach, id):
        pass

    def onSnapshotChange(self, mach, id):
        pass

    def onGuestPropertyChange(self, id, name, newValue, flags):
        pass
Exemple #5
0
class VirtualMachine(Wrapper):
    # Properties directly inherited from IMachine
    _passthruProperties = [
        "accelerate2DVideoEnabled",
        "accelerate3DEnabled",
        "accessible",
        "CPUCount",
        "currentStateModified",
        "description",
        "guestPropertyNotificationPatterns",
        "HardwareVersion",
        "hardwareUUID",
        "id",
        "lastStateChange",
        "lockMachine",
        "logFolder",
        "memorySize",
        "monitorCount",
        "name",
        "OSTypeId",
        "sessionPid",
        "sessionState",
        "sessionType",
        "settingsFilePath",
        "settingsModified",
        "snapshotCount",
        "snapshotFolder",
        "state",
        "stateFilePath",
        "statisticsUpdateInterval",
        "teleporterAddress",
        "teleporterEnabled",
        "teleporterPassword",
        "teleporterPort",
        "unregister",
        "VRAMSize",
        ]

    _manager = VirtualBoxManager()
    _vbox = VirtualBox()

    def __init__(self, machine, session=None):
        """Return a VirtualMachine wrapper around given IMachine instance"""
        self._wrappedInstance = machine

    def __del__(self):
        pass

    def __str__(self):
        return self.name

    #
    # Top-level controls
    #
    def pause(self, wait=False):
        """Pause a running VM.

        If wait is True, then wait until machine is actually paused before returning."""
        with self.lock() as session:
            with VirtualBoxException.ExceptionHandler():
                session.console.pause()
        # XXX Note sure if we need a lock for this or not
        if wait:
            self.waitUntilPaused()

    def resume(self):
        """Resume a paused VM."""
        with self.lock() as session:
            with VirtualBoxException.ExceptionHandler():
                session.console.resume()

    def powerOff(self, wait=False):
        """Power off a running VM.

        If wait is True, then wait for power down and session closureto complete."""
        with self.lock() as session:
            with VirtualBoxException.ExceptionHandler():
                session.console.powerDown()
        # XXX Not sure we need a lock for the following
        if wait:
            self.waitUntilDown()
            self.waitUntilUnlocked()

    def powerOn(self, type="gui", env=""):
        """Spawns a new process that executes a virtual machine.

        This is spawning a "remote session" in VirtualBox terms."""
        # TODO: Add a wait argument
        if not self.isRegistered():
            raise VirtualBoxException.VirtualBoxInvalidVMStateException(
                "VM is not registered")
        with VirtualBoxException.ExceptionHandler():
            iMachine = self.getIMachine()
            session = Session.create()
            iprogress = iMachine.launchVMProcess(session.getISession(),
                                                 type, env)
            progress = Progress(iprogress)
            progress.waitForCompletion()
            session.unlockMachine()

    def eject(self):
        """Do what ever it takes to unregister the VM"""
        if not self.isRegistered():
            # Nothing to do
            return
        if self.isRunning():
            self.powerOff(wait=True)
        self.unregister(cleanup_mode=Constants.CleanupMode_DetachAllReturnNone)

    def delete(self):
        """Delete the VM.

        VM must be locked or unregistered"""
        with VirtualBoxException.ExceptionHandler():
            iMachine = self.getIMachine()
            iprogress = iMachine.delete(None)
            progress = Progress(iprogress)
            progress.waitForCompletion()

    #
    # Creation methods
    #

    @classmethod
    def open(cls, path):
        """Opens a virtual machine from the existing settings file.

        Note that calling open() on a VM that is already registered will
        throw a VirtualBoxFileNotFoundException except.

        Throws VirtualBoxFileNotFoundException if file not found."""
        with VirtualBoxException.ExceptionHandler():
            path = cls._canonicalizeVMPath(path)
            machine = cls._vbox.openMachine(path)
        return VirtualMachine(machine)

    @classmethod
    def find(cls, nameOrId):
        """Attempts to find a virtual machine given its name or UUID."""
        with VirtualBoxException.ExceptionHandler():
            machine = cls._vbox.findMachine(nameOrId)
        return VirtualMachine(machine)

    @classmethod
    def get(cls, id):
        """Attempts to find a virtual machine given its UUID."""
        return cls.find(id)

    @classmethod
    def create(cls, name, osTypeId, settingsFile=None, id=None, register=True,
               forceOverwrite=False):
        """Create a new virtual machine with the given name and osType.
    
        If settingsFile is not None, it should be a path to use instead
        of the default for the settings file.

        If id is not None, it will be used as the UUID of the
        machine. Otherwise one will be automatically generated.

        If register is True, register machine after creation."""
        with VirtualBoxException.ExceptionHandler():
            machine = cls._vbox.createMachine(settingsFile,
                                              name,
                                              osTypeId,
                                              id,
                                              forceOverwrite)
        vm = VirtualMachine(machine)
        vm.saveSettings()
        if register:
            vm.register()
        return vm

    def clone(self, name, settingsFile=None, id=None, register=True,
              description=None):
        """Clone this virtual machine as new VM with given name.

        Clones basic properties of machine plus any storage
        controllers. Does not clone any attached storage.

        If settingsFile is not None, it should be a path to use instead
        of the default for the settingsFile

        If id is not None, it will be used as the UUID of the
        new machine. Otherwise one will be automatically generated.

        If register is True, register new machine after creation.

        If description is None, copy description from source, otherwise use description."""
        vm = VirtualMachine.create(name,
                                   self.OSTypeId,
                                   settingsFile=settingsFile,
                                   id=id,
                                   # Once we register, we cannot make
                                   # changes without opening a
                                   # session, so defer any
                                   # registration.
                                   register=False)
        if description:
            vm.description = description
        else:
            vm.description = self.description
        vm.CPUCount = self.CPUCount
        vm.memorySize = self.memorySize
        vm.VRAMSize = self.VRAMSize
        vm.accelerate3DEnabled = self.accelerate3DEnabled
        vm.accelerate2DVideoEnabled = self.accelerate2DVideoEnabled
        vm.monitorCount = self.monitorCount
        controllers = self.getStorageControllers()
        vm.register()
        for controller in controllers:
            vm.addStorageController(controller.bus,
                                    name = controller.name)
        if not register:
            clone.unregister()
        return vm

    @classmethod
    def getAll(cls):
        """Return an array of all known virtual machines"""
        return [VirtualMachine(vm) for vm in cls._vbox.machines]
            
    #
    # Registration methods
    #

    def register(self):
        """Registers the machine within this VirtualBox installation."""
        with VirtualBoxException.ExceptionHandler():
            self._vbox.registerMachine(self.getIMachine())

    def unregister(self,
                   cleanup_mode=Constants.CleanupMode_DetachAllReturnNone):
        """Unregisters the machine previously registered using register()."""
        with VirtualBoxException.ExceptionHandler():
            machine = self.getIMachine()
            machine.unregister(cleanup_mode)

    def isRegistered(self):
        """Is this virtual machine registered?"""
        from VirtualBoxException import VirtualBoxObjectNotFoundException
        try:
            VirtualMachine.get(self.id)
            registered = True
        except VirtualBoxObjectNotFoundException, e:
            registered = False
        except Exception, e:
            raise
Exemple #6
0
 def __init__(self, vbox):
     self._vbox = vbox
     self._manager = VirtualBoxManager()
     self._isMscom = self._manager.isMSCOM()
Exemple #7
0
 def __init__(self):
     self._manager = VirtualBoxManager()
     self._wrappedInstance = self._manager.getIVirtualBox()
Exemple #8
0
 def __init__(self, vbox):
     self._vbox = vbox
     self._manager = VirtualBoxManager()
     self._isMscom = self._manager.isMSCOM()
Exemple #9
0
 def __init__(self):
     self._manager = VirtualBoxManager()
     self._wrappedInstance = self._manager.getIVirtualBox()
Exemple #10
0
class Session(Wrapper):
    # Properties directly inherited from IMachine
    _passthruProperties = [
        "console",
        "state",
        "type",
    ]

    _manager = VirtualBoxManager()
    _vbox = VirtualBox()

    def __init__(self, isession):
        self._wrappedInstance = isession
        self._machine = None

    @classmethod
    def create(cls):
        """Return a new Session instance"""
        return cls(cls._createSession())

    @classmethod
    def _createSession(cls):
        """Create and return an ISesison object."""
        return cls._manager.mgr.getSessionObject(cls._vbox)

    def __del__(self):
        self.unlockMachine(wait=False)

    def saveSettings(self):
        """Save changes to VM associated with session."""
        with VirtualBoxException.ExceptionHandler():
            self.getIMachine().saveSettings()

    def _setMachine(self, machine):
        """Set the machine associated with this session."""
        self._machine = machine

    def getMachine(self):
        """Return the mutable machine associated with the session."""
        return self._machine

    def unlockMachine(self, wait=True):
        """Close any open session, unlocking the machine."""
        if self.isLocked():
            with VirtualBoxException.ExceptionHandler():
                self._wrappedInstance.unlockMachine()
                if wait:
                    while self.isLocked():
                        self._vbox.waitForEvent()

    def getISession(self):
        """Return ISession instance wrapped by Session"""
        return self._wrappedInstance

    def getIMachine(self):
        """Return mutable IMachine object associated with session."""
        return self._wrappedInstance.machine

    def isDirect(self):
        """Is this a direct session?"""
        return (self.type != Constants.SessionType_Remote)

    def isLocked(self):
        """Is this session locked?"""
        return (self.state == Constants.SessionState_Locked)

    def isUnlocked(self):
        """Is this session unlocked?"""
        return (self.state == Constants.SessionState_Unlocked)
Exemple #11
0
class Medium(Wrapper):
    # Properties directly inherited from IMedium
    _passthruProperties = [
        "autoResize",
        "description",
        "format",
        "hostDrive",
        "id",
        "lastAccessError",
        "location",
        "logicalSize",
        "name",
        "readOnly",
        "size",
        "state",
        "type"
        ]

    # These properties are converted by given function before being returned.
    _wrappedProperties = [
        ("deviceType", Device.class_from_type),
        ]

    _manager = VirtualBoxManager()

    def __init__(self, imedium):
        """Return a Medium wrapper around given IMedium instance"""
        assert(imedium is not None)
        self._wrappedInstance = imedium

    #
    # Creation methods
    #
    @classmethod
    def open(cls, path, deviceType, accessMode = None, forceNewUuid=False):
        """Opens a medium from an existing location.

        Throws VirtualBoxFileError if file not found."""
        with VirtualBoxException.ExceptionHandler():
            if accessMode is None:
                accessMode = Constants.AccessMode_ReadWrite
            # path must be absolute path
            path = cls._canonicalizeMediumPath(path)
            medium = cls._getVBox().openMedium(path,
                                               deviceType,
                                               accessMode,
                                               forceNewUuid)
        return Medium(medium)

    @classmethod
    def find(cls, path, deviceType):
        """Returns a medium that uses the given path or UUID to store medium data."""
        with VirtualBoxException.ExceptionHandler():
            if not UUID.isUUID(path):
                path = cls._canonicalizeMediumPath(path)
            medium = cls._getVBox().findMedium(path, deviceType)
        return Medium(medium)

    def clone(self, path, newUUID=True, wait=True):
        """Create a clone of this medium at the given location.

        If wait is True, does not return until process completes.
        if newUUID is true, clone will have new UUID and will be registered, otherwise will have same UUID as source medium.
        Returns Progress instance."""
        with VirtualBoxException.ExceptionHandler():
            path = self._canonicalizeMediumPath(path)
            if newUUID:
                # If target doesn't have storage, new UUID is created.
                target= self.create(path)
            else:
                # If target does have storage, UUID is copied.
                target = self.createWithStorage(path, self.logicalSize)
            progress = self.cloneTo(target, wait=wait)
        if wait:
            progress.waitForCompletion()
        return progress

    @classmethod
    def create(cls, path, format=None):
        """Create a new hard disk at the given location."""
        with VirtualBoxException.ExceptionHandler():
            path = cls._canonicalizeMediumPath(path)
        if os.path.exists(path):
            # Todo: Better exception here
            raise VirtualBoxException.VirtualBoxException(
                "Cannot create %s - file already exists." % path)
        with VirtualBoxException.ExceptionHandler():
            # Despire the name of this method it returns an IMedium
            # instance
            imedium = cls._getVBox().createHardDisk(format, path)
        return cls(imedium)
    
    @classmethod
    def createWithStorage(cls, path, size,
                          format=None, variant=None, wait=True):
        """Create a new hard disk at given location with given size (in MB).

        This is a wrapper around the create() and createBaseStorage() methods."""
        disk = cls.create(path, format)
        disk.createBaseStorage(size, variant, wait)
        return disk

    def getIMedium(self):
        """Return IMedium object."""
        return self._wrappedInstance

    def close(self):
        """Closes this medium."""
        self._wrappedInstance.close()

    def basename(self):
        """Return the basename of the location of the storage unit holding medium data."""
        return os.path.basename(self.location)

    def dirname(self):
        """Return the dirname of the location of the storage unit holding medium data."""
        return os.path.dirname(self.location)

    #
    # Internal string representations 
    #
    def __str__(self):
        return self.name

    # IMedium apparently defines this and its method will sometimes
    # be called in preference to our __str__() method.
    def __unicode__(self):
        return self.name

    #
    # Instantiation of other methods
    #
    def cloneTo(self, target, variant=None, parent=None, wait=True):
        """Clone to the target hard drive.
        
        Returns Progress instance. If wait is True, does not return until process completes."""
        if variant is None:
            variant = Constants.MediumVariant_Standard
        with VirtualBoxException.ExceptionHandler():
            progress = self.getIMedium().cloneTo(target.getIMedium(),
                                                 variant,
                                                 parent)
        progress = Progress(progress)
        if wait:
            progress.waitForCompletion()
        return progress

    def createBaseStorage(self, size, variant=None, wait=True):
        """Create storage for the drive of the given size (in MB).

        Returns Progress instance. If wait is True, does not return until process completes."""
        if variant is None:
            variant = Constants.MediumVariant_Standard
        with VirtualBoxException.ExceptionHandler():
            progress = self.getIMedium().createBaseStorage(size, variant)
        progress = Progress(progress)
        if wait:
            progress.waitForCompletion()
        return progress

    #
    # Internal methods
    #
    @classmethod
    def _canonicalizeMediumPath(cls, path):
        """Given a path to a hard drive (or other medium) do any needed clean up."""
        # path must be absolute path
        return os.path.abspath(path)

    @classmethod
    def _getVBox(cls):
        """Return the VirtualBox object associated with this VirtualMachine."""
        return cls._manager.getIVirtualBox()