summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2011-06-08 13:08:52 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2011-06-08 13:08:52 +0100
commitd21d5954d0c08b1c80b72c5f37becc2e58ec916a (patch)
tree1e6adc292c780bcc3311b28908a96bac439a2ae6
parent93059e36200b61f87f61578d9774172212446644 (diff)
downloadbitbake-d21d5954d0c08b1c80b72c5f37becc2e58ec916a.tar.gz
bitbake/server: Move server specific code into the server backend and create a server API
Move the server implementation specific code into the server backend where it belongs and replace this with a set of object method calls which establish the server, detach it and then connect to it using appropriate IPC. Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rwxr-xr-xbin/bitbake65
-rw-r--r--lib/bb/server/process.py66
-rw-r--r--lib/bb/server/xmlrpc.py50
3 files changed, 125 insertions, 56 deletions
diff --git a/bin/bitbake b/bin/bitbake
index c22e29ad1..1ed46d9b5 100755
--- a/bin/bitbake
+++ b/bin/bitbake
@@ -29,7 +29,6 @@ sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)),
import optparse
import warnings
-import signal
from traceback import format_exception
try:
import bb
@@ -40,10 +39,9 @@ import bb.msg
from bb import cooker
from bb import ui
from bb import server
-from bb.server.process import ProcessServer, ServerCommunicator, ProcessEventQueue
-
-from Queue import Empty
-from multiprocessing import Queue, Pipe
+#from bb.server import none
+from bb.server import process
+#from bb.server import xmlrpc
__version__ = "1.13.0"
logger = logging.getLogger("BitBake")
@@ -175,6 +173,10 @@ Default BBFILES are the .bb files in the current directory.""")
ui_main = get_ui(configuration)
+ # Save a logfile for cooker into the current working directory. When the
+ # server is daemonized this logfile will be truncated.
+ cooker_logfile = os.path.join(os.getcwd(), "cooker.log")
+
bb.utils.init_logger(bb.msg, configuration.verbose, configuration.debug,
configuration.debug_domains)
@@ -187,45 +189,32 @@ Default BBFILES are the .bb files in the current directory.""")
# of the UIs (e.g. for DISPLAY, etc.)
bb.utils.clean_environment()
- # establish communication channels. We use bidirectional pipes for
- # ui <--> server command/response pairs
- # and a queue for server -> ui event notifications
- #
- ui_channel, server_channel = Pipe()
- event_queue = ProcessEventQueue()
+ #server = bb.server.none.BitBakeServer()
+ server = bb.server.process.BitBakeServer()
+ #server = bb.server.xmlrpc.BitBakeServer()
+
+ server.initServer()
+ idle = server.getServerIdleCB()
- server = ProcessServer(server_channel, event_queue, configuration)
- server.start()
+ cooker = bb.cooker.BBCooker(configuration, idle)
+ cooker.parseCommandLine()
+
+ server.addcooker(cooker)
+ server.saveConnectionDetails()
+ server.detach(cooker_logfile)
+
+ # Should no longer need to ever reference cooker
+ del cooker
logger.removeHandler(handler)
- def shutdown(force=False):
- signal.signal(signal.SIGINT, signal.SIG_IGN)
- server.stop()
- if force:
- server.join(0.5)
- if server.is_alive():
- server.terminate()
- server.join()
- else:
- server.join()
- while True:
- try:
- event = event_queue.get(block=False)
- except (Empty, IOError):
- break
- if isinstance(event, logging.LogRecord):
- logger.handle(event)
- ui_channel.close()
- event_queue.close()
- if force:
- sys.exit(1)
-
- signal.signal(signal.SIGTERM, lambda i, s: shutdown(force=True))
+ # Setup a connection to the server (cooker)
+ server_connection = server.establishConnection()
+
try:
- return ui_main(ServerCommunicator(ui_channel), event_queue)
+ return server.launchUI(ui_main, server_connection.connection, server_connection.events)
finally:
- shutdown()
+ server_connection.terminate()
return 1
diff --git a/lib/bb/server/process.py b/lib/bb/server/process.py
index a5239400c..44b8e4d49 100644
--- a/lib/bb/server/process.py
+++ b/lib/bb/server/process.py
@@ -29,7 +29,6 @@ import os
import signal
import sys
import time
-from bb.cooker import BBCooker
from Queue import Empty
from multiprocessing import Event, Process, util, Queue, Pipe, queues
@@ -73,13 +72,11 @@ class ProcessServer(Process):
profile_filename = "profile.log"
profile_processed_filename = "profile.log.processed"
- def __init__(self, command_channel, event_queue, configuration):
+ def __init__(self, command_channel, event_queue):
Process.__init__(self)
self.command_channel = command_channel
self.event_queue = event_queue
self.event = EventAdapter(event_queue)
- self.configuration = configuration
- self.cooker = BBCooker(configuration, self.register_idle_function)
self._idlefunctions = {}
self.event_handle = bb.event.register_UIHhandler(self)
self.quit = False
@@ -195,6 +192,35 @@ class ProcessServer(Process):
if (2, 6, 0) <= sys.version_info < (2, 6, 3):
_bootstrap = bootstrap_2_6_6
+class BitBakeServerConnection():
+ def __init__(self, server):
+ self.server = server
+ self.procserver = server.server
+ self.connection = ServerCommunicator(server.ui_channel)
+ self.events = server.event_queue
+
+ def terminate(self, force = False):
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+ self.procserver.stop()
+ if force:
+ self.procserver.join(0.5)
+ if self.procserver.is_alive():
+ self.procserver.terminate()
+ self.procserver.join()
+ else:
+ self.procserver.join()
+ while True:
+ try:
+ event = self.server.event_queue.get(block=False)
+ except (Empty, IOError):
+ break
+ if isinstance(event, logging.LogRecord):
+ logger.handle(event)
+ self.server.ui_channel.close()
+ self.server.event_queue.close()
+ if force:
+ sys.exit(1)
+
# Wrap Queue to provide API which isn't server implementation specific
class ProcessEventQueue(multiprocessing.queues.Queue):
def waitEvent(self, timeout):
@@ -210,4 +236,36 @@ class ProcessEventQueue(multiprocessing.queues.Queue):
return None
+class BitBakeServer(object):
+ def initServer(self):
+ # establish communication channels. We use bidirectional pipes for
+ # ui <--> server command/response pairs
+ # and a queue for server -> ui event notifications
+ #
+ self.ui_channel, self.server_channel = Pipe()
+ self.event_queue = ProcessEventQueue(0)
+
+ self.server = ProcessServer(self.server_channel, self.event_queue)
+
+ def addcooker(self, cooker):
+ self.cooker = cooker
+ self.server.cooker = cooker
+
+ def getServerIdleCB(self):
+ return self.server.register_idle_function
+
+ def saveConnectionDetails(self):
+ return
+
+ def detach(self, cooker_logfile):
+ self.server.start()
+ return
+
+ def establishConnection(self):
+ self.connection = BitBakeServerConnection(self)
+ signal.signal(signal.SIGTERM, lambda i, s: self.connection.terminate(force=True))
+ return self.connection
+
+ def launchUI(self, uifunc, *args):
+ return bb.cooker.server_main(self.cooker, uifunc, *args)
diff --git a/lib/bb/server/xmlrpc.py b/lib/bb/server/xmlrpc.py
index c43c6cde6..a7ac969ae 100644
--- a/lib/bb/server/xmlrpc.py
+++ b/lib/bb/server/xmlrpc.py
@@ -122,8 +122,7 @@ def _create_server(host, port):
return s
class BitBakeServerCommands():
- def __init__(self, server, cooker):
- self.cooker = cooker
+ def __init__(self, server):
self.server = server
def registerEventHandler(self, host, port):
@@ -160,11 +159,11 @@ class BitBakeServerCommands():
"""
return True
-class BitBakeServer(SimpleXMLRPCServer):
+class BitBakeXMLRPCServer(SimpleXMLRPCServer):
# remove this when you're done with debugging
# allow_reuse_address = True
- def __init__(self, cooker, interface = ("localhost", 0)):
+ def __init__(self, interface = ("localhost", 0)):
"""
Constructor
"""
@@ -174,9 +173,12 @@ class BitBakeServer(SimpleXMLRPCServer):
self._idlefuns = {}
self.host, self.port = self.socket.getsockname()
#self.register_introspection_functions()
- commands = BitBakeServerCommands(self, cooker)
- self.autoregister_all_functions(commands, "")
+ self.commands = BitBakeServerCommands(self)
+ self.autoregister_all_functions(self.commands, "")
+
+ def addcooker(self, cooker):
self.cooker = cooker
+ self.commands.cooker = cooker
def autoregister_all_functions(self, context, prefix):
"""
@@ -244,14 +246,6 @@ class BitbakeServerInfo():
self.host = server.host
self.port = server.port
-class BitBakeServerFork():
- def __init__(self, cooker, server, serverinfo, logfile):
- daemonize.createDaemon(server.serve_forever, logfile)
-
-class BitbakeUILauch():
- def launch(self, serverinfo, uifunc, *args):
- return uifunc(*args)
-
class BitBakeServerConnection():
def __init__(self, serverinfo):
self.connection = _create_server(serverinfo.host, serverinfo.port)
@@ -271,3 +265,31 @@ class BitBakeServerConnection():
self.connection.terminateServer()
except:
pass
+
+class BitBakeServer(object):
+ def initServer(self):
+ self.server = BitBakeXMLRPCServer()
+
+ def addcooker(self, cooker):
+ self.cooker = cooker
+ self.server.addcooker(cooker)
+
+ def getServerIdleCB(self):
+ return self.server.register_idle_function
+
+ def saveConnectionDetails(self):
+ self.serverinfo = BitbakeServerInfo(self.server)
+
+ def detach(self, cooker_logfile):
+ daemonize.createDaemon(self.server.serve_forever, cooker_logfile)
+ del self.cooker
+ del self.server
+
+ def establishConnection(self):
+ self.connection = BitBakeServerConnection(self.serverinfo)
+ return self.connection
+
+ def launchUI(self, uifunc, *args):
+ return uifunc(*args)
+
+