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

vboxrunner_sdl_cs.py

#!/usr/bin/python

# 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/>.



# Client/Server VBoxRunner. Allows the iterface to exit without stopping the VMs

import os
import socket     
import threading
import cPickle
import gobject

import vmvdi
import util

class VBoxRunnerSDLClient:    
    def __init__(self):
        self.vboxiface = None
        self.lockfile = os.path.expanduser('~') + '/.VirtualBox/.lock.server'
        self.port = 10010
        self.running_vms = []

    def init(self):
        if os.path.isfile(self.lockfile):
            f = open(self.lockfile,'r')
            self.port = int(f.read())
            try:
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                s.connect(('', self.port))
                s.send('**start**')
                s.close()
                return
            except:     
                print 'Server running but unable to connect.\nKill process and remove lockfile ' + self.lockfile
                exit()
        server = VBoxRunnerSDLServer(self.lockfile)
        self.port = server.init()

    def mgr_finished(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            s.connect(('', self.port))
            s.send('**end**')
            s.close()
        except: pass
        return False

    def query_vm_states(self, vms, vdis):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(('', self.port))
        s.send('**query**')
        recv = s.recv(4096)
        while recv != '**end**':
            running_vm = cPickle.loads(recv)
            for vm in vms:
                if vm.name != running_vm.name: continue
                vm.state = 'running'
                for shared in running_vm.hw.shared_folders:
                    if shared.transient == False: continue
                    vm.hw.shared_folders.append(shared)
                self.running_vms.append(vm)
                if running_vm.hw.transient_dvd == None: break
                for vdi in vdis:
                    if vdi.path != running_vm.hw.transient_dvd.path: continue
                    vm.hw.transient_dvd = vdi
                    break
                break
            new_s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            new_s.connect(('', self.port))
            gobject.io_add_watch(new_s, gobject.IO_IN, self.listener)
            recv = s.recv(4096)
        s.close()

    def execute_vm(self, vm):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            s.connect(('', self.port))
        except:
            print 'client: could not connect to server'
            return None
        s.send(cPickle.dumps(vm))
        self.running_vms.append(vm)
        gobject.io_add_watch(s, gobject.IO_IN, self.listener)

    def listener(self, socket, args):
        recv = socket.recv(4096)
        if not len(recv): return False
        else:
            (vm_name, msg) = cPickle.loads(recv)
            if msg != '': self.vboxiface.show_msg(msg, True, True)
            for vm in self.running_vms:
                if vm.name != vm_name: continue
                vm.stop()
                self.running_vms.remove(vm)
                self.vboxiface.update_state(vm)
            return True       

    def swap_dvd(self, vm, dvd):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(('', self.port))
        s.send('**dvd**')
        s.recv(128)
        s.send(cPickle.dumps((vm.name, dvd)))
        s.close()

    def add_shared(self, vm, shared):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(('', self.port))
        s.send('**addshared**')
        s.recv(128)
        s.send(cPickle.dumps((vm.name, shared)))
        s.close()

    def del_shared(self, vm, shared_num):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(('', self.port))
        s.send('**delshared**')
        s.recv(128)
        s.send(cPickle.dumps((vm.name, shared_num)))
        s.close()
        



class VBoxRunnerSDLServerThread(threading.Thread):
    def __init__(self, vm, runner):
        threading.Thread.__init__(self)
        self.vm = vm
        self.runner = runner
    def run(self):
        status, msg = util.command_run(['VBoxSDL', '-vm', self.vm.name])
        self.runner.vm_finished(status, msg, self.vm)
            
            
            
class VBoxRunnerSDLServer:
    def __init__(self, lockfile):
        self.lockfile = lockfile
        self.port = 10010
        self.running_vms = []
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.exit_when_done = False
        self.open_sockets = []

    def init(self):
        while True:
            try: 
                self.server_socket.bind(('', self.port))
                break
            except:
                self.port += 1
        self.server_socket.listen(1)
        f = open(self.lockfile, 'w')
        f.write(str(self.port))
        f.close()
        if not os.fork():
            self.listen()
        return self.port

    def listen(self):
        while True:
            conn, addr = self.server_socket.accept()
            recv = conn.recv(4096)
            if recv  == '**end**':
                conn.close()
                self.exit_when_done = True
                if self.running_vms == []: self.exit_server()
            elif recv  == '**start**':
                conn.close()
                self.exit_when_done = False
            elif recv == '**query**':
                for i, vm in enumerate(self.running_vms):
                    conn.send(cPickle.dumps(vm))
                    newconn, newaddr = self.server_socket.accept()
                    self.open_sockets[i] = newconn
                conn.send('**end**')
                conn.close()
            elif recv == '**dvd**':
                conn.send('**ok**')
                dvd_msg = conn.recv(4096)
                vm_name, dvd = cPickle.loads(dvd_msg)
                for vm in self.running_vms:
                    if vm.name != vm_name: continue
                    vm.hw.transient_dvd = dvd
            elif recv == '**addshared**':
                conn.send('**ok**')
                shared_msg = conn.recv(4096)
                vm_name, shared = cPickle.loads(shared_msg)
                for vm in self.running_vms:
                    if vm.name != vm_name: continue
                    vm.hw.shared_folders.append(shared)
            elif recv == '**delshared**':
                conn.send('**ok**')
                shared_msg = conn.recv(4096)
                vm_name, shared_num = cPickle.loads(shared_msg)
                for vm in self.running_vms:
                    if vm.name != vm_name: continue
                    del vm.hw.shared_folders[shared_num]
            else: # Run
                vm = cPickle.loads(recv)
                vm.hw.transient_dvd = vm.hw.dvd
                vm.state = 'running'
                self.running_vms.append(vm)
                self.open_sockets.append(conn)
                thread = VBoxRunnerSDLServerThread(vm, self)
                thread.start()

    def vm_finished(self, status, msg, vm):
        for i, vmi in enumerate(self.running_vms):
            if vmi != vm: continue
            s = self.open_sockets[i]
            if status != 0: s.send(cPickle.dumps((vm.name,msg)))
            else: s.send(cPickle.dumps((vm.name,'')))
            s.close()
            self.running_vms.remove(vm)
            self.open_sockets.remove(s)
            if self.running_vms == [] and self.exit_when_done: 
                # Lame, there should be a way to exit the program from a thread
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                s.connect(('', self.port))
                s.send('**end**')
                s.close
            break
            
    def exit_server(self):
        os.remove(self.lockfile)
        exit()

Generated by  Doxygen 1.6.0   Back to index