]> git.pld-linux.org Git - projects/pld-builder.new.git/blame - PLD_Builder/request_handler.py
- send notifications for src builds, too (requires acl.conf update to allow src user...
[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):
e1389e9c 41 lockf = None
dfff8bd5
MM
42 def fail_mail(msg):
43 if len(r.batches) >= 1:
44 spec = r.batches[0].spec
45 else:
46 spec = "None.spec"
47 log.error("%s: %s" % (spec, msg))
48 m = user.message_to()
49 m.set_headers(subject = "building %s failed" % spec)
50 m.write_line(msg)
51 m.send()
57b6e61d 52
e1389e9c 53 lockf = lock("request")
dfff8bd5 54 if check_double_id(r.id):
e1389e9c 55 lockf.close()
dfff8bd5
MM
56 return
57
91f92271 58
dfff8bd5
MM
59 for batch in r.batches:
60 if not user.can_do("src", config.builder, batch.branch):
61 fail_mail("user %s is not allowed to src:%s:%s" \
62 % (user.get_login(), config.builder, batch.branch))
e1389e9c 63 lockf.close()
dfff8bd5 64 return
d2c1ec3f 65
e936beda
MM
66 if 'test-build' in r.flags and 'upgrade' in r.flags:
67 fail_mail("it's forbidden to upgrade from a test build")
e1389e9c 68 lockf.close()
e936beda
MM
69 return
70
dfff8bd5
MM
71 if "upgrade" in r.flags and not user.can_do("upgrade", config.builder, batch.branch):
72 fail_mail("user %s is not allowed to upgrade:%s:%s" \
73 % (user.get_login(), config.builder, batch.branch))
e1389e9c 74 lockf.close()
dfff8bd5 75 return
d2c1ec3f 76
07db6665 77 # src builder handles only special commands
d078b186 78 if batch.is_command() and (batch.command in ["cvs up"] or config.builder in batch.builders):
07db6665
AM
79 batch.expand_builders(config.binary_builders + [config.src_builder])
80 else:
81 batch.expand_builders(config.binary_builders)
82
dfff8bd5
MM
83 if not batch.is_command() and config.builder in batch.builders:
84 batch.builders.remove(config.builder)
07db6665 85
dfff8bd5
MM
86 for bld in batch.builders:
87 batch.builders_status[bld] = '?'
88 if bld not in config.binary_builders and bld != config.builder:
89 fail_mail("I (src rpm builder '%s') do not handle binary builder '%s', only '%s'" % \
9e8a7e70 90 (config.builder, bld, string.join(config.binary_builders)))
e1389e9c 91 lockf.close()
dfff8bd5
MM
92 return
93 if batch.is_command():
94 if not user.can_do("command", bld):
95 fail_mail("user %s is not allowed to command:%s" \
96 % (user.get_login(), bld))
e1389e9c 97 lockf.close()
dfff8bd5
MM
98 return
99 elif not user.can_do("binary", bld, batch.branch):
100 pkg = batch.spec
101 if pkg.endswith(".spec"):
102 pkg = pkg[:-5]
103 if not user.can_do("binary-" + pkg, bld, batch.branch):
104 fail_mail("user %s is not allowed to binary-%s:%s:%s" \
105 % (user.get_login(), pkg, bld, batch.branch))
e1389e9c 106 lockf.close()
dfff8bd5
MM
107 return
108
109 r.priority = user.check_priority(r.priority,config.builder)
110 r.requester = user.get_login()
111 r.requester_email = user.mail_to()
112 r.time = time.time()
113 log.notice("queued %s from %s" % (r.id, user.get_login()))
114 q = B_Queue(path.queue_file)
115 q.lock(0)
116 q.read()
117 q.add(r)
118 q.write()
119 q.unlock()
e1389e9c 120 lockf.close()
57b6e61d 121
59ce7cd6 122def handle_notification(r, user):
dfff8bd5
MM
123 if not user.can_do("notify", r.builder):
124 log.alert("user %s is not allowed to notify:%s" % (user.login, r.builder))
125 q = B_Queue(path.req_queue_file)
126 q.lock(0)
127 q.read()
128 not_fin = filter(lambda (r): not r.is_done(), q.requests)
129 r.apply_to(q)
130 for r in not_fin:
131 if r.is_done():
9be34149 132 util.clean_tmp(path.srpms_dir + '/' + r.id)
dfff8bd5
MM
133 now = time.time()
134 def leave_it(r):
135 # for ,,done'' set timeout to 4d
136 if r.is_done() and r.time + 4 * 24 * 60 * 60 < now:
137 return False
138 # and for not ,,done'' set it to 20d
139 if r.time + 20 * 24 * 60 * 60 < now:
9be34149 140 util.clean_tmp(path.srpms_dir + '/' + r.id)
dfff8bd5
MM
141 return False
142 return True
143 q.requests = filter(leave_it, q.requests)
144 q.write()
145 q.dump(open(path.queue_stats_file, "w"))
146 q.dump_html(open(path.queue_html_stats_file, "w"))
147 os.chmod(path.queue_html_stats_file, 0644)
148 os.chmod(path.queue_stats_file, 0644)
89ad1c79 149 q.write_signed(path.req_queue_signed_file)
150 os.chmod(path.req_queue_signed_file, 0644)
dfff8bd5 151 q.unlock()
59ce7cd6 152
f02c1e4d
AM
153def handle_request(req, filename = None):
154 if req == '':
c1ad9456
ER
155 log.alert('Empty body received. Filename: %s' % filename)
156 return False
157
f02c1e4d 158 (em, body) = gpg.verify_sig(req)
dfff8bd5
MM
159 user = acl.user_by_email(em)
160 if user == None:
161 # FIXME: security email here
f02c1e4d 162 keys = gpg.get_keys(req)
b5e0afc4 163 log.alert("Invalid signature, missing/untrusted key, or '%s' not in acl. Keys in gpg batch: '%s'" % (em, keys))
f6eb7039 164 return False
b5e0afc4 165
dfff8bd5
MM
166 acl.set_current_user(user)
167 status.push("email from %s" % user.login)
168 r = request.parse_request(body)
169 if r.kind == 'group':
170 handle_group(r, user)
171 elif r.kind == 'notification':
172 handle_notification(r, user)
173 else:
174 msg = "%s: don't know how to handle requests of this kind '%s'" \
175 % (user.get_login(), r.kind)
176 log.alert(msg)
177 m = user.message_to()
178 m.set_headers(subject = "unknown request")
179 m.write_line(msg)
180 m.send()
181 status.pop()
f6eb7039 182 return True
cc94eb63 183
f02c1e4d 184def handle_request_main(req, filename = None):
dfff8bd5
MM
185 init_conf("src")
186 status.push("handling email request")
f02c1e4d 187 ret = handle_request(req, filename = filename)
dfff8bd5 188 status.pop()
63319e0a
AM
189 return ret
190
191def main():
f02c1e4d 192 sys.exit(not handle_request_main(sys.stdin.read()))
1f62bccc 193
e8ee9db8 194if __name__ == '__main__':
dfff8bd5 195 wrap.wrap(main)
This page took 0.079815 seconds and 4 git commands to generate.