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