summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/prserv/serv.py
diff options
context:
space:
mode:
authorLianhao Lu <lianhao.lu@intel.com>2012-01-10 14:13:49 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-01-11 10:36:20 +0000
commit30a9bc6c92a8920d6e9c4a4b93b83bdbe5d48e78 (patch)
tree6cce4db7619f35e16cdab7961ef44adfdd859b9e /bitbake/lib/prserv/serv.py
parent4a8a3c503fd896593b787c26edbe46a7324e494e (diff)
downloadpoky-30a9bc6c92a8920d6e9c4a4b93b83bdbe5d48e78.tar.gz
bitbake/PRservice: Added no_hist mode and export/import.
[YOCTO #1556] 1. Added the package_arch into the index to the DB table. Because the change in PACKAGE_ARCH will results in different checksum, and it is better to have seperate PR value domains for differnt PACKAGE_ARCH of the same pakcage. 2. Changed the PR service to operate in no history mode. In this mode, the for a given query tuple (version, pkgarch, checksum), the returned value will be the largest among all the values of the same (version, pkgarch). This means the PR value returned can NOT be decremented. 3. Added export function. For each (version, pkgarch) tuple, only the record with the maximum value will be exported. 4. Added import function. The record will only be imported if the imported value is larger than the value stored in the DB with the same (version, pkgarch, checksum) tuple. (Bitbake rev: 379567ee879dcdc09a51f7f1212bde1076147a6f) Signed-off-by: Lianhao Lu <lianhao.lu@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/prserv/serv.py')
-rw-r--r--bitbake/lib/prserv/serv.py106
1 files changed, 69 insertions, 37 deletions
diff --git a/bitbake/lib/prserv/serv.py b/bitbake/lib/prserv/serv.py
index 2f488f4898..7bcffa7744 100644
--- a/bitbake/lib/prserv/serv.py
+++ b/bitbake/lib/prserv/serv.py
@@ -21,6 +21,8 @@ class Handler(SimpleXMLRPCRequestHandler):
21 raise 21 raise
22 return value 22 return value
23 23
24PIDPREFIX = "/tmp/PRServer_%s_%s.pid"
25
24class PRServer(SimpleXMLRPCServer): 26class PRServer(SimpleXMLRPCServer):
25 pidfile="/tmp/PRServer.pid" 27 pidfile="/tmp/PRServer.pid"
26 def __init__(self, dbfile, logfile, interface, daemon=True): 28 def __init__(self, dbfile, logfile, interface, daemon=True):
@@ -34,20 +36,33 @@ class PRServer(SimpleXMLRPCServer):
34 self.host, self.port = self.socket.getsockname() 36 self.host, self.port = self.socket.getsockname()
35 self.db=prserv.db.PRData(dbfile) 37 self.db=prserv.db.PRData(dbfile)
36 self.table=self.db["PRMAIN"] 38 self.table=self.db["PRMAIN"]
39 self.pidfile=PIDPREFIX % interface
37 40
38 self.register_function(self.getPR, "getPR") 41 self.register_function(self.getPR, "getPR")
39 self.register_function(self.quit, "quit") 42 self.register_function(self.quit, "quit")
40 self.register_function(self.ping, "ping") 43 self.register_function(self.ping, "ping")
44 self.register_function(self.export, "export")
45 self.register_function(self.importone, "importone")
41 self.register_introspection_functions() 46 self.register_introspection_functions()
47
48 def export(self, version=None, pkgarch=None, checksum=None, colinfo=True):
49 try:
50 return self.table.export(version, pkgarch, checksum, colinfo)
51 except sqlite3.Error as exc:
52 logging.error(str(exc))
53 return None
54
55 def importone(self, version, pkgarch, checksum, value):
56 return self.table.importone(version, pkgarch, checksum, value)
42 57
43 def ping(self): 58 def ping(self):
44 return not self.quit 59 return not self.quit
45 60
46 def getPR(self, version, checksum): 61 def getPR(self, version, pkgarch, checksum):
47 try: 62 try:
48 return self.table.getValue(version,checksum) 63 return self.table.getValue(version, pkgarch, checksum)
49 except prserv.NotFoundError: 64 except prserv.NotFoundError:
50 logging.error("can not find value for (%s, %s)",version,checksum) 65 logging.error("can not find value for (%s, %s)",version, checksum)
51 return None 66 return None
52 except sqlite3.Error as exc: 67 except sqlite3.Error as exc:
53 logging.error(str(exc)) 68 logging.error(str(exc))
@@ -69,28 +84,34 @@ class PRServer(SimpleXMLRPCServer):
69 84
70 def start(self): 85 def start(self):
71 if self.daemon is True: 86 if self.daemon is True:
72 logging.info("PRServer: starting daemon...") 87 logging.info("PRServer: try to start daemon...")
73 self.daemonize() 88 self.daemonize()
74 else: 89 else:
75 logging.info("PRServer: starting...") 90 atexit.register(self.delpid)
91 pid = str(os.getpid())
92 pf = file(self.pidfile, 'w+')
93 pf.write("%s\n" % pid)
94 pf.write("%s\n" % self.host)
95 pf.write("%s\n" % self.port)
96 pf.close()
97 logging.info("PRServer: start success! DBfile: %s, IP: %s, PORT: %d" %
98 (self.dbfile, self.host, self.port))
76 self._serve_forever() 99 self._serve_forever()
77 100
78 def delpid(self): 101 def delpid(self):
79 os.remove(PRServer.pidfile) 102 os.remove(self.pidfile)
80 103
81 def daemonize(self): 104 def daemonize(self):
82 """ 105 """
83 See Advanced Programming in the UNIX, Sec 13.3 106 See Advanced Programming in the UNIX, Sec 13.3
84 """ 107 """
85 os.umask(0)
86
87 try: 108 try:
88 pid = os.fork() 109 pid = os.fork()
89 if pid > 0: 110 if pid > 0:
90 sys.exit(0) 111 #parent return instead of exit to give control
112 return
91 except OSError as e: 113 except OSError as e:
92 sys.stderr.write("1st fork failed: %d %s\n" % (e.errno, e.strerror)) 114 raise Exception("%s [%d]" % (e.strerror, e.errno))
93 sys.exit(1)
94 115
95 os.setsid() 116 os.setsid()
96 """ 117 """
@@ -102,9 +123,9 @@ class PRServer(SimpleXMLRPCServer):
102 if pid > 0: #parent 123 if pid > 0: #parent
103 sys.exit(0) 124 sys.exit(0)
104 except OSError as e: 125 except OSError as e:
105 sys.stderr.write("2nd fork failed: %d %s\n" % (e.errno, e.strerror)) 126 raise Exception("%s [%d]" % (e.strerror, e.errno))
106 sys.exit(1)
107 127
128 os.umask(0)
108 os.chdir("/") 129 os.chdir("/")
109 130
110 sys.stdout.flush() 131 sys.stdout.flush()
@@ -119,13 +140,15 @@ class PRServer(SimpleXMLRPCServer):
119 # write pidfile 140 # write pidfile
120 atexit.register(self.delpid) 141 atexit.register(self.delpid)
121 pid = str(os.getpid()) 142 pid = str(os.getpid())
122 pf = file(PRServer.pidfile, 'w+') 143 pf = file(self.pidfile, 'w')
123 pf.write("%s\n" % pid) 144 pf.write("%s\n" % pid)
124 pf.write("%s\n" % self.host)
125 pf.write("%s\n" % self.port)
126 pf.close() 145 pf.close()
127 146
147 logging.info("PRServer: starting daemon success! DBfile: %s, IP: %s, PORT: %s, PID: %s" %
148 (self.dbfile, self.host, self.port, pid))
149
128 self._serve_forever() 150 self._serve_forever()
151 exit(0)
129 152
130class PRServerConnection(): 153class PRServerConnection():
131 def __init__(self, host, port): 154 def __init__(self, host, port):
@@ -139,16 +162,22 @@ class PRServerConnection():
139 socket.setdefaulttimeout(2) 162 socket.setdefaulttimeout(2)
140 try: 163 try:
141 self.connection.quit() 164 self.connection.quit()
142 except: 165 except Exception as exc:
143 pass 166 sys.stderr.write("%s\n" % str(exc))
144 167
145 def getPR(self, version, checksum): 168 def getPR(self, version, pkgarch, checksum):
146 return self.connection.getPR(version, checksum) 169 return self.connection.getPR(version, pkgarch, checksum)
147 170
148 def ping(self): 171 def ping(self):
149 return self.connection.ping() 172 return self.connection.ping()
150 173
151def start_daemon(options): 174 def export(self,version=None, pkgarch=None, checksum=None, colinfo=True):
175 return self.connection.export(version, pkgarch, checksum, colinfo)
176
177 def importone(self, version, pkgarch, checksum, value):
178 return self.connection.importone(version, pkgarch, checksum, value)
179
180def start_daemon(dbfile, logfile, interface):
152 try: 181 try:
153 pf = file(PRServer.pidfile,'r') 182 pf = file(PRServer.pidfile,'r')
154 pid = int(pf.readline().strip()) 183 pid = int(pf.readline().strip())
@@ -159,40 +188,43 @@ def start_daemon(options):
159 if pid: 188 if pid:
160 sys.stderr.write("pidfile %s already exist. Daemon already running?\n" 189 sys.stderr.write("pidfile %s already exist. Daemon already running?\n"
161 % PRServer.pidfile) 190 % PRServer.pidfile)
162 sys.exit(1) 191 return 1
163 192
164 server = PRServer(options.dbfile, interface=(options.host, options.port), 193 server = PRServer(os.path.abspath(dbfile), os.path.abspath(logfile), interface)
165 logfile=os.path.abspath(options.logfile))
166 server.start() 194 server.start()
195 return 0
167 196
168def stop_daemon(): 197def stop_daemon(host, port):
198 pidfile = PIDPREFIX % (host, port)
169 try: 199 try:
170 pf = file(PRServer.pidfile,'r') 200 pf = file(pidfile,'r')
171 pid = int(pf.readline().strip()) 201 pid = int(pf.readline().strip())
172 host = pf.readline().strip()
173 port = int(pf.readline().strip())
174 pf.close() 202 pf.close()
175 except IOError: 203 except IOError:
176 pid = None 204 pid = None
177 205
178 if not pid: 206 if not pid:
179 sys.stderr.write("pidfile %s does not exist. Daemon not running?\n" 207 sys.stderr.write("pidfile %s does not exist. Daemon not running?\n"
180 % PRServer.pidfile) 208 % pidfile)
181 sys.exit(1) 209 return 1
182 210
183 PRServerConnection(host,port).terminate() 211 PRServerConnection(host, port).terminate()
184 time.sleep(0.5) 212 time.sleep(0.5)
185 213
186 try: 214 try:
187 while 1: 215 while 1:
188 os.kill(pid,signal.SIGTERM) 216 os.kill(pid,signal.SIGTERM)
189 time.sleep(0.1) 217 time.sleep(0.1)
190 except OSError as err: 218 except OSError as e:
191 err = str(err) 219 err = str(e)
192 if err.find("No such process") > 0: 220 if err.find("No such process") > 0:
193 if os.path.exists(PRServer.pidfile): 221 if os.path.exists(PRServer.pidfile):
194 os.remove(PRServer.pidfile) 222 os.remove(PRServer.pidfile)
195 else: 223 else:
196 print err 224 raise Exception("%s [%d]" % (e.strerror, e.errno))
197 sys.exit(1) 225
226 return 0
198 227
228def ping(host, port):
229 print PRServerConnection(host,port).ping()
230 return 0