summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/prserv/serv.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/prserv/serv.py')
-rw-r--r--bitbake/lib/prserv/serv.py198
1 files changed, 198 insertions, 0 deletions
diff --git a/bitbake/lib/prserv/serv.py b/bitbake/lib/prserv/serv.py
new file mode 100644
index 0000000000..ecafe4f94d
--- /dev/null
+++ b/bitbake/lib/prserv/serv.py
@@ -0,0 +1,198 @@
1import os,sys,logging
2import signal,time, atexit
3from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
4import xmlrpclib,sqlite3
5
6import bb.server.xmlrpc
7import prserv
8import prserv.db
9
10if sys.hexversion < 0x020600F0:
11 print("Sorry, python 2.6 or later is required.")
12 sys.exit(1)
13
14class Handler(SimpleXMLRPCRequestHandler):
15 def _dispatch(self,method,params):
16 try:
17 value=self.server.funcs[method](*params)
18 except:
19 import traceback
20 traceback.print_exc()
21 raise
22 return value
23
24class PRServer(SimpleXMLRPCServer):
25 pidfile="/tmp/PRServer.pid"
26 def __init__(self, dbfile, logfile, interface, daemon=True):
27 ''' constructor '''
28 SimpleXMLRPCServer.__init__(self, interface,
29 requestHandler=SimpleXMLRPCRequestHandler,
30 logRequests=False, allow_none=True)
31 self.dbfile=dbfile
32 self.daemon=daemon
33 self.logfile=logfile
34 self.host, self.port = self.socket.getsockname()
35 self.db=prserv.db.PRData(dbfile)
36 self.table=self.db["PRMAIN"]
37
38 self.register_function(self.getPR, "getPR")
39 self.register_function(self.quit, "quit")
40 self.register_function(self.ping, "ping")
41 self.register_introspection_functions()
42
43 def ping(self):
44 return not self.quit
45
46 def getPR(self, version, checksum):
47 try:
48 return self.table.getValue(version,checksum)
49 except prserv.NotFoundError:
50 logging.error("can not find value for (%s, %s)",version,checksum)
51 return None
52 except sqlite3.Error as exc:
53 logging.error(str(exc))
54 return None
55
56 def quit(self):
57 self.quit=True
58 return
59
60 def _serve_forever(self):
61 self.quit = False
62 self.timeout = 0.5
63 while not self.quit:
64 self.handle_request()
65
66 logging.info("PRServer: stopping...")
67 self.server_close()
68 return
69
70 def start(self):
71 if self.daemon is True:
72 logging.info("PRServer: starting daemon...")
73 self.daemonize()
74 else:
75 logging.info("PRServer: starting...")
76 self._serve_forever()
77
78 def delpid(self):
79 os.remove(PRServer.pidfile)
80
81 def daemonize(self):
82 """
83 See Advanced Programming in the UNIX, Sec 13.3
84 """
85 os.umask(0)
86
87 try:
88 pid = os.fork()
89 if pid > 0:
90 sys.exit(0)
91 except OSError,e:
92 sys.stderr.write("1st fork failed: %d %s\n" % (e.errno, e.strerror))
93 sys.exit(1)
94
95 os.setsid()
96 """
97 fork again to make sure the daemon is not session leader,
98 which prevents it from acquiring controlling terminal
99 """
100 try:
101 pid = os.fork()
102 if pid > 0: #parent
103 sys.exit(0)
104 except OSError,e:
105 sys.stderr.write("2nd fork failed: %d %s\n" % (e.errno, e.strerror))
106 sys.exit(1)
107
108 os.chdir("/")
109
110 sys.stdout.flush()
111 sys.stderr.flush()
112 si = file('/dev/null', 'r')
113 so = file(self.logfile, 'a+')
114 se = so
115 os.dup2(si.fileno(),sys.stdin.fileno())
116 os.dup2(so.fileno(),sys.stdout.fileno())
117 os.dup2(se.fileno(),sys.stderr.fileno())
118
119 # write pidfile
120 atexit.register(self.delpid)
121 pid = str(os.getpid())
122 pf = file(PRServer.pidfile, 'w+')
123 pf.write("%s\n" % pid)
124 pf.write("%s\n" % self.host)
125 pf.write("%s\n" % self.port)
126 pf.close()
127
128 self._serve_forever()
129
130class PRServerConnection():
131 def __init__(self, host, port):
132 self.connection = bb.server.xmlrpc._create_server(host, port)
133 self.host = host
134 self.port = port
135
136 def terminate(self):
137 # Don't wait for server indefinitely
138 import socket
139 socket.setdefaulttimeout(2)
140 try:
141 self.connection.quit()
142 except:
143 pass
144
145 def getPR(self, version, checksum):
146 return self.connection.getPR(version, checksum)
147
148 def ping(self):
149 return self.connection.ping()
150
151def start_daemon(options):
152 try:
153 pf = file(PRServer.pidfile,'r')
154 pid = int(pf.readline().strip())
155 pf.close()
156 except IOError:
157 pid = None
158
159 if pid:
160 sys.stderr.write("pidfile %s already exist. Daemon already running?\n"
161 % PRServer.pidfile)
162 sys.exit(1)
163
164 server = PRServer(options.dbfile, interface=(options.host, options.port),
165 logfile=os.path.abspath(options.logfile))
166 server.start()
167
168def stop_daemon():
169 try:
170 pf = file(PRServer.pidfile,'r')
171 pid = int(pf.readline().strip())
172 host = pf.readline().strip()
173 port = int(pf.readline().strip())
174 pf.close()
175 except IOError:
176 pid = None
177
178 if not pid:
179 sys.stderr.write("pidfile %s does not exist. Daemon not running?\n"
180 % PRServer.pidfile)
181 sys.exit(1)
182
183 PRServerConnection(host,port).terminate()
184 time.sleep(0.5)
185
186 try:
187 while 1:
188 os.kill(pid,signal.SIGTERM)
189 time.sleep(0.1)
190 except OSError, err:
191 err = str(err)
192 if err.find("No such process") > 0:
193 if os.path.exists(PRServer.pidfile):
194 os.remove(PRServer.pidfile)
195 else:
196 print err
197 sys.exit(1)
198