]> git.pld-linux.org Git - projects/pld-builder.new.git/blame - PLD_Builder/request_handler.py
- grab filename from http post headers
[projects/pld-builder.new.git] / PLD_Builder / request_handler.py
CommitLineData
dfff8bd5
MM
1# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
2
57b6e61d
MM
3import email
4import string
5import time
6import os
7import StringIO
cc94eb63 8import sys
91f92271 9import fnmatch
57b6e61d
MM
10
11import gpg
12import request
13import log
14import path
c8782384 15import util
6b44a683 16import wrap
bdc3292c 17import status
57b6e61d
MM
18from acl import acl
19from lock import lock
20from bqueue import B_Queue
b5a39692 21from config import config, init_conf
57b6e61d
MM
22
23def check_double_id(id):
dfff8bd5
MM
24 id_nl = id + "\n"
25
26 ids = open(path.processed_ids_file)
27 for i in ids.xreadlines():
28 if i == id_nl:
29 # FIXME: security email here?
30 log.alert("request %s already processed" % id)
31 return 1
32 ids.close()
33
34 ids = open(path.processed_ids_file, "a")
35 ids.write(id_nl)
36 ids.close()
57b6e61d 37
dfff8bd5 38 return 0
57b6e61d 39
34738db3 40def handle_group(r, user):
dfff8bd5
MM
41 def fail_mail(msg):
42 if len(r.batches) >= 1:
43 spec = r.batches[0].spec
44 else:
45 spec = "None.spec"
46 log.error("%s: %s" % (spec, msg))
47 m = user.message_to()
48 m.set_headers(subject = "building %s failed" % spec)
49 m.write_line(msg)
50 m.send()
57b6e61d 51
dfff8bd5
MM
52 lock("request")
53 if check_double_id(r.id):
54 return
55
91f92271 56
dfff8bd5
MM
57 for batch in r.batches:
58 if not user.can_do("src", config.builder, batch.branch):
59 fail_mail("user %s is not allowed to src:%s:%s" \
60 % (user.get_login(), config.builder, batch.branch))
61 return
d2c1ec3f 62
e936beda
MM
63 if 'test-build' in r.flags and 'upgrade' in r.flags:
64 fail_mail("it's forbidden to upgrade from a test build")
65 return
66
dfff8bd5
MM
67 if "upgrade" in r.flags and not user.can_do("upgrade", config.builder, batch.branch):
68 fail_mail("user %s is not allowed to upgrade:%s:%s" \
69 % (user.get_login(), config.builder, batch.branch))
70 return
d2c1ec3f 71
dfff8bd5
MM
72 batch.expand_builders(config.binary_builders)
73 if not batch.is_command() and config.builder in batch.builders:
74 batch.builders.remove(config.builder)
75 for bld in batch.builders:
76 batch.builders_status[bld] = '?'
77 if bld not in config.binary_builders and bld != config.builder:
78 fail_mail("I (src rpm builder '%s') do not handle binary builder '%s', only '%s'" % \
9e8a7e70 79 (config.builder, bld, string.join(config.binary_builders)))
dfff8bd5
MM
80 return
81 if batch.is_command():
82 if not user.can_do("command", bld):
83 fail_mail("user %s is not allowed to command:%s" \
84 % (user.get_login(), bld))
85 return
86 elif not user.can_do("binary", bld, batch.branch):
87 pkg = batch.spec
88 if pkg.endswith(".spec"):
89 pkg = pkg[:-5]
90 if not user.can_do("binary-" + pkg, bld, batch.branch):
91 fail_mail("user %s is not allowed to binary-%s:%s:%s" \
92 % (user.get_login(), pkg, bld, batch.branch))
93 return
94
95 r.priority = user.check_priority(r.priority,config.builder)
96 r.requester = user.get_login()
97 r.requester_email = user.mail_to()
98 r.time = time.time()
99 log.notice("queued %s from %s" % (r.id, user.get_login()))
100 q = B_Queue(path.queue_file)
101 q.lock(0)
102 q.read()
103 q.add(r)
104 q.write()
105 q.unlock()
57b6e61d 106
59ce7cd6 107def handle_notification(r, user):
dfff8bd5
MM
108 if not user.can_do("notify", r.builder):
109 log.alert("user %s is not allowed to notify:%s" % (user.login, r.builder))
110 q = B_Queue(path.req_queue_file)
111 q.lock(0)
112 q.read()
113 not_fin = filter(lambda (r): not r.is_done(), q.requests)
114 r.apply_to(q)
115 for r in not_fin:
116 if r.is_done():
117 util.clean_tmp(path.srpms_dir + r.id)
118 now = time.time()
119 def leave_it(r):
120 # for ,,done'' set timeout to 4d
121 if r.is_done() and r.time + 4 * 24 * 60 * 60 < now:
122 return False
123 # and for not ,,done'' set it to 20d
124 if r.time + 20 * 24 * 60 * 60 < now:
125 util.clean_tmp(path.srpms_dir + r.id)
126 return False
127 return True
128 q.requests = filter(leave_it, q.requests)
129 q.write()
130 q.dump(open(path.queue_stats_file, "w"))
131 q.dump_html(open(path.queue_html_stats_file, "w"))
132 os.chmod(path.queue_html_stats_file, 0644)
133 os.chmod(path.queue_stats_file, 0644)
89ad1c79 134 q.write_signed(path.req_queue_signed_file)
135 os.chmod(path.req_queue_signed_file, 0644)
dfff8bd5 136 q.unlock()
59ce7cd6 137
c1ad9456 138def handle_request(f, filename = None):
dfff8bd5
MM
139 sio = StringIO.StringIO()
140 util.sendfile(f, sio)
c1ad9456
ER
141
142 sio.seek(0)
143 if sio.read() == '':
144 log.alert('Empty body received. Filename: %s' % filename)
145 return False
146
dfff8bd5
MM
147 sio.seek(0)
148 (em, body) = gpg.verify_sig(sio)
149 user = acl.user_by_email(em)
150 if user == None:
151 # FIXME: security email here
b5e0afc4
ER
152 sio.seek(0); keys = gpg.get_keys(sio)
153 log.alert("Invalid signature, missing/untrusted key, or '%s' not in acl. Keys in gpg batch: '%s'" % (em, keys))
f6eb7039 154 return False
b5e0afc4 155
dfff8bd5
MM
156 acl.set_current_user(user)
157 status.push("email from %s" % user.login)
158 r = request.parse_request(body)
159 if r.kind == 'group':
160 handle_group(r, user)
161 elif r.kind == 'notification':
162 handle_notification(r, user)
163 else:
164 msg = "%s: don't know how to handle requests of this kind '%s'" \
165 % (user.get_login(), r.kind)
166 log.alert(msg)
167 m = user.message_to()
168 m.set_headers(subject = "unknown request")
169 m.write_line(msg)
170 m.send()
171 status.pop()
f6eb7039 172 return True
cc94eb63 173
c1ad9456 174def handle_request_main(stream, filename = None):
dfff8bd5
MM
175 init_conf("src")
176 status.push("handling email request")
c1ad9456 177 ret = handle_request(stream, filename = filename)
dfff8bd5 178 status.pop()
63319e0a
AM
179 return ret
180
181def main():
182 sys.exit(not handle_request_main(sys.stdin))
1f62bccc 183
e8ee9db8 184if __name__ == '__main__':
dfff8bd5 185 wrap.wrap(main)
This page took 0.099271 seconds and 4 git commands to generate.