]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/commitdiff
bitbake/server: Move server specific code into the server backend and create a server API
authorRichard Purdie <richard.purdie@linuxfoundation.org>
Wed, 8 Jun 2011 12:08:52 +0000 (13:08 +0100)
committerRichard Purdie <richard.purdie@linuxfoundation.org>
Wed, 8 Jun 2011 12:08:52 +0000 (13:08 +0100)
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>
bin/bitbake
lib/bb/server/process.py
lib/bb/server/xmlrpc.py

index c22e29ad1c824e7323e5fe6fcee96a9395ba2ebd..1ed46d9b53d91da4c6b1dbb2f177138f358b90d4 100755 (executable)
@@ -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
 
index a5239400c608591724065fe091683f6ec5b4509d..44b8e4d496c8a8efe31b568c2ded5094ec2a2379 100644 (file)
@@ -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)
 
index c43c6cde66166a6d319e807329b5c58e80bebfbd..a7ac969ae22d66f55feb032c1861fb8062053c3c 100644 (file)
@@ -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)
+
+