import popen2
import re
+import xreadlines
+import StringIO
-def verify_sig(email):
+def verify_sig(buf):
"""Check signature.
- Given email as list of strings, return (signer-emails, signed-body).
- where both are lists of strings.
+ Given email as file-like object, return (signer-emails, signed-body).
+ where signer-emails is lists of strings, and signed-body is StringIO
+ object.
"""
(gpg_out, gpg_in, gpg_err) = popen2.popen3("LC_ALL=C gpg --decrypt")
- for l in email:
- gpg_in.write(l)
+ gpg_in.write(buf.read())
gpg_in.close()
- body = gpg_out.readlines()
+ body = StringIO.StringIO()
+ for l in gpg_out.xreadlines():
+ body.write(l)
rx = re.compile("^gpg: Good signature from .*<([^>]+)>")
emails = []
- for l in gpg_err.readlines():
+ for l in gpg_err.xreadlines():
m = rx.match(l)
if m:
emails.append(m.group(1))
+ body.seek(0)
+ gpg_out.close()
+ gpg_err.close()
return (emails, body)
+
+def sign(buf):
+ (gpg_out, gpg_in, gpg_err) = popen2.popen3("LC_ALL=C gpg --clearsign --default-key builder")
+ gpg_in.write(buf.read())
+ gpg_in.close()
+ body = StringIO.StringIO()
+ for l in gpg_out.xreadlines():
+ body.write(l)
+ body.seek(0)
+ gpg_out.close()
+ gpg_err.close()
+ return body
from xml.dom.minidom import *
import string
+import time
+__all__ = ['parse_request', 'parse_requests']
+
def text(e):
if len(e.childNodes) == 0:
return ""
raise "xml: text expected: <%s>" % e.nodeName
def attr(e, a):
- return e.attributes[a]
- #.getNamedItem(a)
+ return e.attributes[a].value
def is_blank(e):
return e.nodeType == Element.TEXT_NODE and string.strip(e.nodeValue) == ""
self.is_group = 1
self.id = attr(e, "id")
self.priority = 2
+ self.time = time.time()
for c in e.childNodes:
if is_blank(c): continue
if c.nodeType != Element.ELEMENT_NODE:
self.requester = text(c)
elif c.nodeName == "priority":
self.priority = int(text(c))
+ elif c.nodeName == "time":
+ self.time = int(text(c))
else:
raise "xml: evil group child (%s)" % c.nodeName
def dump(self):
print "group: %s @%d" % (self.id, self.priority)
- print " from: %s" % (self.requester)
+ print " from: %s" % self.requester
+ print " time: %s" % time.asctime(time.localtime(self.time))
for b in self.batches:
b.dump()
else:
raise "xml: evil request <%s>" % e.nodeName
-def parse(str):
- d = parseString(str)
+def parse_request(f):
+ d = parse(f)
return build_request(d.documentElement)
+def parse_requests(f):
+ d = parse(f)
+ res = []
+ for r in d.documentElement.childNodes:
+ res.append(build_request(r))
+ return res
--- /dev/null
+# Queue on src-builder
+
+import re
+import gzip
+import time
+import StringIO
+
+# PLD_Builder:
+import gpg
+import request
+
+class Src_Queue:
+ def __init__(self, filename):
+ self.name = filename
+ self.requests = []
+ self.is_gzip = 0
+
+ def read(self):
+ if re.search(r"\.gz$", self.name):
+ f = gzip.open(self.name)
+ self.is_gzip = 1
+ else:
+ f = open(self.name)
+ self.is_gzip = 0
+ (signers, body) = gpg.verify_sig(f)
+ # maybe check signers here?
+ self.requests = request.parse_requests(body)
+
+ def write(self):
+ sio = StringIO.StringIO()
+ sio.write("<queue>\n")
+ for r in self.requests:
+ r.write_to(sio)
+ sio.write("</queue>\n")
+ sio.seek(0)
+ sio = gpg.sign(sio)
+ if self.is_gzip:
+ f = gzip.open(self.name, "w", 6)
+ else:
+ f = open(self.name, "w")
+ f.write(sio.read())
+ f.close()
+
+ def remove_old(self):
+ now = time.time()
+ def is_old(r): return now - r.time > 30 * 24 * 3600
+ self.requests = filter(is_old, self.requests)
+
+ def add(self, req):
+ self.requests.append(req)
+
+ def value():
+ return self.requests
#!/usr/bin/python
import sys
+from PLD_Builder.squeue import *
from PLD_Builder.request import *
+from PLD_Builder.gpg import *
-xml = """
-<group id="d30eb8ae-3c54-4103-9188-69b1114d6ac7">
- <priority>2</priority>
- <requester>malekith</requester>
- <batch>
- <src-rpm>foo-1.2-3.src.rpm</src-rpm>
- <spec>foo.spec</spec>
+q = Src_Queue("src-queue")
+#q.read()
+(em, b) = gpg.verify_sig(open("req.txt"))
+q.add(parse_request(b))
+q.write()
- <info>foo.spec -r DEVEL blah,blah</info>
-
- <with>foo</with>
- <without>bar</without>
-
- <builder>i386</builder>
- <builder>i586</builder>
- <builder>i686</builder>
- <builder>ppc</builder>
- </batch>
- <batch>
- <src-rpm>bar-1.2-1.src.rpm</src-rpm>
- <spec>bar.spec</spec>
-
- <info>bar.spec -r HEAD blah,blah</info>
-
- <with>foo</with>
- <without>bar</without>
-
- <builder>i386-security</builder>
- <builder>i586-security</builder>
- <builder>i686-security</builder>
- </batch>
-</group>
-"""
-
-parse(xml).dump()
+for r in q.value():
+ r.dump()