summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/server
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-01-20 18:46:02 +0000
committerRichard Purdie <rpurdie@linux.intel.com>2010-01-20 18:46:02 +0000
commit22c29d8651668195f72e2f6a8e059d625eb511c3 (patch)
treedd1dd43f0ec47a9964c8a766eb8b3ad75cf51a64 /bitbake/lib/bb/server
parent1bfd6edef9db9c9175058ae801d1b601e4f15263 (diff)
downloadpoky-22c29d8651668195f72e2f6a8e059d625eb511c3.tar.gz
bitbake: Switch to bitbake-dev version (bitbake master upstream)
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'bitbake/lib/bb/server')
-rw-r--r--bitbake/lib/bb/server/__init__.py2
-rw-r--r--bitbake/lib/bb/server/none.py181
-rw-r--r--bitbake/lib/bb/server/xmlrpc.py187
3 files changed, 370 insertions, 0 deletions
diff --git a/bitbake/lib/bb/server/__init__.py b/bitbake/lib/bb/server/__init__.py
new file mode 100644
index 0000000000..1a732236e2
--- /dev/null
+++ b/bitbake/lib/bb/server/__init__.py
@@ -0,0 +1,2 @@
1import xmlrpc
2import none
diff --git a/bitbake/lib/bb/server/none.py b/bitbake/lib/bb/server/none.py
new file mode 100644
index 0000000000..ebda111582
--- /dev/null
+++ b/bitbake/lib/bb/server/none.py
@@ -0,0 +1,181 @@
1#
2# BitBake 'dummy' Passthrough Server
3#
4# Copyright (C) 2006 - 2007 Michael 'Mickey' Lauer
5# Copyright (C) 2006 - 2008 Richard Purdie
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20"""
21 This module implements an xmlrpc server for BitBake.
22
23 Use this by deriving a class from BitBakeXMLRPCServer and then adding
24 methods which you want to "export" via XMLRPC. If the methods have the
25 prefix xmlrpc_, then registering those function will happen automatically,
26 if not, you need to call register_function.
27
28 Use register_idle_function() to add a function which the xmlrpc server
29 calls from within server_forever when no requests are pending. Make sure
30 that those functions are non-blocking or else you will introduce latency
31 in the server's main loop.
32"""
33
34import time
35import bb
36from bb.ui import uievent
37import xmlrpclib
38import pickle
39
40DEBUG = False
41
42from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
43import inspect, select
44
45class BitBakeServerCommands():
46 def __init__(self, server, cooker):
47 self.cooker = cooker
48 self.server = server
49
50 def runCommand(self, command):
51 """
52 Run a cooker command on the server
53 """
54 #print "Running Command %s" % command
55 return self.cooker.command.runCommand(command)
56
57 def terminateServer(self):
58 """
59 Trigger the server to quit
60 """
61 self.server.server_exit()
62 #print "Server (cooker) exitting"
63 return
64
65 def ping(self):
66 """
67 Dummy method which can be used to check the server is still alive
68 """
69 return True
70
71eventQueue = []
72
73class BBUIEventQueue:
74 class event:
75 def __init__(self, parent):
76 self.parent = parent
77 @staticmethod
78 def send(event):
79 bb.server.none.eventQueue.append(pickle.loads(event))
80 @staticmethod
81 def quit():
82 return
83
84 def __init__(self, BBServer):
85 self.eventQueue = bb.server.none.eventQueue
86 self.BBServer = BBServer
87 self.EventHandle = bb.event.register_UIHhandler(self)
88
89 def getEvent(self):
90 if len(self.eventQueue) == 0:
91 return None
92
93 return self.eventQueue.pop(0)
94
95 def waitEvent(self, delay):
96 event = self.getEvent()
97 if event:
98 return event
99 self.BBServer.idle_commands(delay)
100 return self.getEvent()
101
102 def queue_event(self, event):
103 self.eventQueue.append(event)
104
105 def system_quit( self ):
106 bb.event.unregister_UIHhandler(self.EventHandle)
107
108class BitBakeServer():
109 # remove this when you're done with debugging
110 # allow_reuse_address = True
111
112 def __init__(self, cooker):
113 self._idlefuns = {}
114 self.commands = BitBakeServerCommands(self, cooker)
115
116 def register_idle_function(self, function, data):
117 """Register a function to be called while the server is idle"""
118 assert callable(function)
119 self._idlefuns[function] = data
120
121 def idle_commands(self, delay):
122 #print "Idle queue length %s" % len(self._idlefuns)
123 #print "Idle timeout, running idle functions"
124 #if len(self._idlefuns) == 0:
125 nextsleep = delay
126 for function, data in self._idlefuns.items():
127 try:
128 retval = function(self, data, False)
129 #print "Idle function returned %s" % (retval)
130 if retval is False:
131 del self._idlefuns[function]
132 elif retval is True:
133 nextsleep = None
134 elif nextsleep is None:
135 continue
136 elif retval < nextsleep:
137 nextsleep = retval
138 except SystemExit:
139 raise
140 except:
141 import traceback
142 traceback.print_exc()
143 pass
144 if nextsleep is not None:
145 #print "Sleeping for %s (%s)" % (nextsleep, delay)
146 time.sleep(nextsleep)
147
148 def server_exit(self):
149 # Tell idle functions we're exiting
150 for function, data in self._idlefuns.items():
151 try:
152 retval = function(self, data, True)
153 except:
154 pass
155
156class BitbakeServerInfo():
157 def __init__(self, server):
158 self.server = server
159 self.commands = server.commands
160
161class BitBakeServerFork():
162 def __init__(self, serverinfo, command, logfile):
163 serverinfo.forkCommand = command
164 serverinfo.logfile = logfile
165
166class BitBakeServerConnection():
167 def __init__(self, serverinfo):
168 self.server = serverinfo.server
169 self.connection = serverinfo.commands
170 self.events = bb.server.none.BBUIEventQueue(self.server)
171
172 def terminate(self):
173 try:
174 self.events.system_quit()
175 except:
176 pass
177 try:
178 self.connection.terminateServer()
179 except:
180 pass
181
diff --git a/bitbake/lib/bb/server/xmlrpc.py b/bitbake/lib/bb/server/xmlrpc.py
new file mode 100644
index 0000000000..3364918c77
--- /dev/null
+++ b/bitbake/lib/bb/server/xmlrpc.py
@@ -0,0 +1,187 @@
1#
2# BitBake XMLRPC Server
3#
4# Copyright (C) 2006 - 2007 Michael 'Mickey' Lauer
5# Copyright (C) 2006 - 2008 Richard Purdie
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20"""
21 This module implements an xmlrpc server for BitBake.
22
23 Use this by deriving a class from BitBakeXMLRPCServer and then adding
24 methods which you want to "export" via XMLRPC. If the methods have the
25 prefix xmlrpc_, then registering those function will happen automatically,
26 if not, you need to call register_function.
27
28 Use register_idle_function() to add a function which the xmlrpc server
29 calls from within server_forever when no requests are pending. Make sure
30 that those functions are non-blocking or else you will introduce latency
31 in the server's main loop.
32"""
33
34import bb
35import xmlrpclib, sys
36from bb import daemonize
37from bb.ui import uievent
38
39DEBUG = False
40
41from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
42import inspect, select
43
44if sys.hexversion < 0x020600F0:
45 print "Sorry, python 2.6 or later is required for bitbake's XMLRPC mode"
46 sys.exit(1)
47
48class BitBakeServerCommands():
49 def __init__(self, server, cooker):
50 self.cooker = cooker
51 self.server = server
52
53 def registerEventHandler(self, host, port):
54 """
55 Register a remote UI Event Handler
56 """
57 s = xmlrpclib.Server("http://%s:%d" % (host, port), allow_none=True)
58 return bb.event.register_UIHhandler(s)
59
60 def unregisterEventHandler(self, handlerNum):
61 """
62 Unregister a remote UI Event Handler
63 """
64 return bb.event.unregister_UIHhandler(handlerNum)
65
66 def runCommand(self, command):
67 """
68 Run a cooker command on the server
69 """
70 return self.cooker.command.runCommand(command)
71
72 def terminateServer(self):
73 """
74 Trigger the server to quit
75 """
76 self.server.quit = True
77 print "Server (cooker) exitting"
78 return
79
80 def ping(self):
81 """
82 Dummy method which can be used to check the server is still alive
83 """
84 return True
85
86class BitBakeServer(SimpleXMLRPCServer):
87 # remove this when you're done with debugging
88 # allow_reuse_address = True
89
90 def __init__(self, cooker, interface = ("localhost", 0)):
91 """
92 Constructor
93 """
94 SimpleXMLRPCServer.__init__(self, interface,
95 requestHandler=SimpleXMLRPCRequestHandler,
96 logRequests=False, allow_none=True)
97 self._idlefuns = {}
98 self.host, self.port = self.socket.getsockname()
99 #self.register_introspection_functions()
100 commands = BitBakeServerCommands(self, cooker)
101 self.autoregister_all_functions(commands, "")
102
103 def autoregister_all_functions(self, context, prefix):
104 """
105 Convenience method for registering all functions in the scope
106 of this class that start with a common prefix
107 """
108 methodlist = inspect.getmembers(context, inspect.ismethod)
109 for name, method in methodlist:
110 if name.startswith(prefix):
111 self.register_function(method, name[len(prefix):])
112
113 def register_idle_function(self, function, data):
114 """Register a function to be called while the server is idle"""
115 assert callable(function)
116 self._idlefuns[function] = data
117
118 def serve_forever(self):
119 """
120 Serve Requests. Overloaded to honor a quit command
121 """
122 self.quit = False
123 self.timeout = 0 # Run Idle calls for our first callback
124 while not self.quit:
125 #print "Idle queue length %s" % len(self._idlefuns)
126 self.handle_request()
127 #print "Idle timeout, running idle functions"
128 nextsleep = None
129 for function, data in self._idlefuns.items():
130 try:
131 retval = function(self, data, False)
132 if retval is False:
133 del self._idlefuns[function]
134 elif retval is True:
135 nextsleep = 0
136 elif nextsleep is 0:
137 continue
138 elif nextsleep is None:
139 nextsleep = retval
140 elif retval < nextsleep:
141 nextsleep = retval
142 except SystemExit:
143 raise
144 except:
145 import traceback
146 traceback.print_exc()
147 pass
148 if nextsleep is None and len(self._idlefuns) > 0:
149 nextsleep = 0
150 self.timeout = nextsleep
151 # Tell idle functions we're exiting
152 for function, data in self._idlefuns.items():
153 try:
154 retval = function(self, data, True)
155 except:
156 pass
157
158 self.server_close()
159 return
160
161class BitbakeServerInfo():
162 def __init__(self, server):
163 self.host = server.host
164 self.port = server.port
165
166class BitBakeServerFork():
167 def __init__(self, serverinfo, command, logfile):
168 daemonize.createDaemon(command, logfile)
169
170class BitBakeServerConnection():
171 def __init__(self, serverinfo):
172 self.connection = xmlrpclib.Server("http://%s:%s" % (serverinfo.host, serverinfo.port), allow_none=True)
173 self.events = uievent.BBUIEventQueue(self.connection)
174
175 def terminate(self):
176 # Don't wait for server indefinitely
177 import socket
178 socket.setdefaulttimeout(2)
179 try:
180 self.events.system_quit()
181 except:
182 pass
183 try:
184 self.connection.terminateServer()
185 except:
186 pass
187