Logo Search packages:      
Sourcecode: vboxgtk version File versions  Download package

vboxdao_xpcom.py

# VBoxGtk: A VirtualBox GTK+ GUI
# Copyright (C) 2008 Francisco J. Vazquez-Araujo, Spain
# franjva at gmail dot com

# This file is part of VBoxGtk.

# VBoxGtk is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# VBoxGtk is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with VBoxGtk.  If not, see <http://www.gnu.org/licenses/>.



"""
Adapter for the VirtualBox XPCOM API.
"""


import threading

import xpcom.vboxxpcom
import xpcom
import xpcom.components


class ListenerThread(threading.Thread):

    def __init__(self, vbox):
        threading.Thread.__init__(self)
        self.vbox = vbox
        
    def run(self):
        import time
        while True:
            time.sleep(0.5)
            # Random VirtualBox API function. Needed to activate the 
            # callback. Will be fixed VirtualBox 3.0:
            self.vbox.getGuestOSTypes()  
        return 0
        

class VBoxGtkCallback:

    _com_interfaces_ = xpcom.components.interfaces.IVirtualBoxCallback
    
    def __init__(self, vboxdao):
        self.vboxdao = vboxdao 
        
    def onMachineStateChange(self, id, state):
        vm = self.vboxdao.vbox.getMachine(id)
        self.vboxdao.vboxiface.update_state(vm, True)
        
    def onMachineDataChange(self, id): pass
    def onExtraDataCanChange(self, id, key, value): pass
    def onExtraDataChange(self, id, key, value): pass
    def onMediaRegistered(self, id, media_type, registered): pass
    def onMachineRegistered(self, id, registered): pass
    def onSessionStateChange(self, id, state): pass
    def onSnapshotTaken(self, id, snapshot_id): pass
    def onSnapshotDiscarded(self, id, snapshot_id): pass
    def onSnapshotChange(self, id, snapshot_id): pass
    def onGuestPropertyChange(self, id, name, value, flags): pass


class VBoxDaoXpcom():

    def __init__(self):
        vbox_c = xpcom.components.classes["@virtualbox.org/VirtualBox;1"]
        self.vbox = vbox_c.createInstance()
        self.sessions = {}
        self.vboxiface = None
        (self.min_ram, self.max_ram, self.max_vram, self.max_image, 
            self.default_media_folder) = self.get_system_properties()
        (self.vm_states, self.nic_atts, self.nic_devs, 
            self.audio_drivers) = self.get_enums()
        self.os_types = self.get_os_types()
        self.hard_disks = self.get_hard_disks()
        self.dvd_images = self.get_dvd_images()
        self.dvd_host_drives = self.get_dvd_host_drives()
        self.vms = self.get_vms()
        self.thread = None
        self.cb = VBoxGtkCallback(self)

    def get_system_properties(self):
        props = self.vbox.systemProperties
        return (props.minGuestRAM, props.maxGuestRAM, props.maxGuestVRAM, 
                props.maxVDISize, props.defaultHardDiskFolder)

    def get_enums(self):
        vm_states = xpcom.components.interfaces.MachineState
        nic_atts = xpcom.components.interfaces.NetworkAttachmentType
        nic_devs = xpcom.components.interfaces.NetworkAdapterType
        audio_drivers = xpcom.components.interfaces.AudioDriverType
        return (vm_states, nic_atts, nic_devs, audio_drivers)
        
    def get_os_types(self):
        return self.vbox.getGuestOSTypes()

    def get_hard_disks(self):
        return self.vbox.getHardDisks()

    def get_dvd_images(self):
        return self.vbox.getDVDImages()

    def get_dvd_host_drives(self):
        return self.vbox.host.getDVDDrives()

    def set_iface(self, vboxiface):
        self.vboxiface = vboxiface

    def start(self):
        self.vbox.registerCallback(self.cb)
        thread = ListenerThread(self.vbox);
        thread.daemon = True
        thread.start()        

    def exit(self):
        return False

    ## Session

    def get_session(self, vm = None):
        if vm is None:
            session_c = xpcom.components.classes["@virtualbox.org/Session;1"]
            return session_c.createInstance()
        elif vm.id in self.sessions:
            session = self.sessions[vm.id]
        else:
            session = self.get_session()
            if vm.state == self.vm_states.Running:
                self.vbox.openExistingSession(session, vm.id)
            else:
                self.vbox.openSession(session, vm.id)
            self.sessions[vm.id] = session
        return session

    def close_session(self, session):
        del self.sessions[session.machine.id]
        session.close()
        
    ## Media
    
    def create_hd_image(self, hd_path, hd_size, dynamic):
        try:
            hd = self.vbox.createHardDisk('VDI', hd_path)
            if dynamic:
                progress = hd.createBaseStorage(hd_size, 0)
            else:
                progress = hd.createFixedStorage(hd_size)
            progress.waitForCompletion(-1)
            self.hard_disks.append(hd)
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)

    def add_hd(self, path):
        try:
            mode = xpcom.components.interfaces.AccessMode.ReadWrite
            hd = self.vbox.openHardDisk(path, mode)
            self.hard_disks.append(hd)
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)

    def remove_hd(self, hd_num, delete_file):
        hd = self.hard_disks[hd_num]
        try:
            if delete_file:
                progress = hd.deleteStorage()
                progress.waitForCompletion(-1)
            hd.close()
            del self.hard_disks[hd_num]
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)

    def add_dvd_image(self, path):
        try:
            new_id = '00000000-0000-0000-0000-000000000000'
            dvd = self.vbox.openDVDImage(path, new_id)
            self.dvd_images.append(dvd)
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)

    def remove_dvd_image(self, dvd_num):
        dvd = self.dvd_images[dvd_num]
        try:
            dvd.close()
            del self.dvd_images[dvd_num]
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)

    ## VM
    
    def get_vms(self):
        return self.vbox.getMachines()
    
    def create_vm(self, vm_name, os_type):
        try:
            new_id = '00000000-0000-0000-0000-000000000000'
            vm = self.vbox.createMachine(vm_name, os_type, '', new_id)
            self.vbox.registerMachine(vm)
            self.vms.append(vm)
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)

    def delete_vm(self, vm_number):
        vm = self.vms[vm_number]        
        try:
            self.attach_hd(vm_number, None)
            self.prepare_vm(vm_number)
            self.vbox.unregisterMachine(vm.id)
            vm.deleteSettings()
            del self.vms[vm_number]
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)
      
    def prepare_vm(self, vm_number):
        vm = self.vms[vm_number]
        if vm.id in self.sessions:
            self.close_session(self.sessions[vm.id])

    def start_vm(self, vm_number):
        vm = self.vms[vm_number]
        session = self.get_session()
        progress = self.vbox.openRemoteSession(session, vm.id, 'sdl', None)
        progress.waitForCompletion(-1)
        try:
            session.close()
        except xpcom.Exception as e:
            return (1, e.message)
        return (0, None)
    
    def stop_vm(self, vm_number):
        vm = self.vms[vm_number]
        session = self.get_session(vm)
        console = session.console
        console.powerDown()
        self.close_session(session)
        return 0

    def sleep_vm(self, vm_number):
        vm = self.vms[vm_number]
        session = self.get_session(vm)
        console = session.console
        console.saveState()
        self.close_session(session)
        return 0

    def get_hd_id(self, vm_number):
        vm = self.vms[vm_number]
        try:
            sc = vm.getStorageControllers()[0].name
            hd = vm.getHardDisk(sc, 0, 0)
            return str(hd.id)
        except xpcom.Exception:
            return None

    def attach_hd(self, vm_number, hd_id):
        vm = self.vms[vm_number]
        try:
            session = self.get_session(vm)
            sc = session.machine.getStorageControllers()[0].name
            try:
                session.machine.detachHardDisk(sc, 0, 0)
            except:
                pass
            if hd_id is not None:
                session.machine.attachHardDisk(hd_id, sc, 0, 0)
            session.machine.saveSettings()
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)
        
    def get_dvd_id(self, vm_number):
        dvd = self.vms[vm_number].DVDDrive
        if dvd.state == 1:
            return None
        elif dvd.state == 2:
            return str(dvd.getImage().id)
        elif dvd.state == 3:
            return str(dvd.getHostDrive().name)
        
    def attach_dvd(self, vm_number, dvd_id):
        vm = self.vms[vm_number]
        try:
            session = self.get_session(vm)
            if dvd_id is None:
                session.machine.DVDDrive.unmount()
            elif dvd_id[0] == '/':
                host_drive = self.vbox.host.findHostDVDDrive(dvd_id)
                session.machine.DVDDrive.captureHostDrive(host_drive)
            else:
                session.machine.DVDDrive.mountImage(dvd_id)
            session.machine.saveSettings()
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)

    def update_settings(self, vm_number, os_type, hw_virt_ext, mem, vmem, 
                        dvd_passthrough):
        vm = self.vms[vm_number]
        session = self.get_session(vm)
        session.machine.OSTypeId = os_type
        session.machine.HWVirtExEnabled = hw_virt_ext
        session.machine.memorySize = mem
        session.machine.VRAMSize = vmem
        session.machine.DVDDrive.passthrough = dvd_passthrough
        session.machine.saveSettings()
        
    def update_devices(self, vm_number, attachment, device, intnet, hostif, 
                       mac, cable, trace, trace_file, audiodev):
        vm = self.vms[vm_number]
        session = self.get_session(vm)
        net = session.machine.getNetworkAdapter(0)
        net.adapterType = device
        net.internalNetwork = intnet
        net.hostInterface = hostif
        net.MACAddress = mac
        net.cableConnected = cable
        net.traceEnabled = trace
        net.traceFile = trace_file
        net_atts = xpcom.components.interfaces.NetworkAttachmentType
        if attachment == net_atts.Null:
            net.detach()
        elif attachment == net_atts.NAT:
            net.attachToNAT()
        elif attachment == net_atts.Bridged:
            net.attachToBridgedInterface()
        elif attachment == net_atts.Internal:
            net.attachToInternalNetwork() 
        if audiodev == -1:
            session.machine.audioAdapter.enabled = False
        else:
            session.machine.audioAdapter.enabled = True
            session.machine.audioAdapter.audioDriver = audiodev
        session.machine.saveSettings()
    
    def create_shared(self, vm_number, name, folder, writable):
        vm = self.vms[vm_number]
        try:
            session = self.get_session(vm)
            session.machine.createSharedFolder(name, folder, writable)
            session.machine.saveSettings()
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)
        
    def remove_shared(self, vm_number, shared_name):
        vm = self.vms[vm_number]
        try:
            session = self.get_session(vm)
            session.machine.removeSharedFolder(shared_name)
            session.machine.saveSettings()
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)

    def get_snapshot_tree(self, vm_number):
        vm = self.vms[vm_number]
        try:
            root = vm.getSnapshot('00000000-0000-0000-0000-000000000000')
        except:
            return []
        tree = [(root, None)]
        def traverse_tree(root):
            for child in root.getChildren():
                tree.append((child, root.id))
                traverse_tree(child)
        traverse_tree(root)
        return tree
        
    def take_snapshot(self, vm_number, name, description = ''):
        vm = self.vms[vm_number]
        try:
            session = self.get_session(vm)
            console = session.console
            progress = console.takeSnapshot(name, description)
            progress.waitForCompletion(-1)
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)

    def edit_snapshot(self, vm_number, uuid, name):
        vm = self.vms[vm_number]
        try:       
            snapshot = vm.getSnapshot(uuid)
            snapshot.name = name
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)

    def discard_snapshot(self, vm_number, uuid):
        vm = self.vms[vm_number]
        try:
            session = self.get_session(vm)
            console = session.console
            progress = console.discardSnapshot(uuid)
            progress.waitForCompletion(-1)
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)
      
    def discard_current_state(self, vm_number):
        vm = self.vms[vm_number]
        try:
            session = self.get_session(vm)
            console = session.console
            progress = console.discardCurrentState()
            progress.waitForCompletion(-1)
            return (0, None)
        except xpcom.Exception as e:
            return (1, e.message)
   

Generated by  Doxygen 1.6.0   Back to index