]> git.pld-linux.org Git - projects/pld-builder.new.git/blame - PLD_Builder/request_handler.py
Switch to https for client/request handler server and between builders communication...
[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 18from acl import acl
d8d56d0f 19from blacklist import blacklist
57b6e61d
MM
20from lock import lock
21from bqueue import B_Queue
b5a39692 22from config import config, init_conf
854eb778 23from mailer import Message
57b6e61d
MM
24
25def check_double_id(id):
dfff8bd5 26 id_nl = id + "\n"
e6376553 27
dfff8bd5
MM
28 ids = open(path.processed_ids_file)
29 for i in ids.xreadlines():
30 if i == id_nl:
31 # FIXME: security email here?
32 log.alert("request %s already processed" % id)
33 return 1
34 ids.close()
e6376553 35
dfff8bd5
MM
36 ids = open(path.processed_ids_file, "a")
37 ids.write(id_nl)
38 ids.close()
57b6e61d 39
dfff8bd5 40 return 0
57b6e61d 41
34738db3 42def handle_group(r, user):
e1389e9c 43 lockf = None
dfff8bd5
MM
44 def fail_mail(msg):
45 if len(r.batches) >= 1:
46 spec = r.batches[0].spec
47 else:
48 spec = "None.spec"
49 log.error("%s: %s" % (spec, msg))
854eb778
KK
50 m = Message()
51 m.set_headers(to = r.requester_email, cc = config.builder_list)
dfff8bd5
MM
52 m.set_headers(subject = "building %s failed" % spec)
53 m.write_line(msg)
54 m.send()
e6376553 55
e1389e9c 56 lockf = lock("request")
dfff8bd5 57 if check_double_id(r.id):
e1389e9c 58 lockf.close()
dfff8bd5 59 return
91f92271 60
854eb778
KK
61 try:
62 if (user.change_requester and r.requester):
cba0beaa 63 user = acl.user_by_login(r.requester)
854eb778
KK
64 except KeyError:
65 r.requester += '/' + user.get_login()
66 else:
67 r.requester = user.get_login()
68 r.requester_email = user.mail_to()
cba0beaa 69
dfff8bd5 70 for batch in r.batches:
897f56ee 71
dfff8bd5
MM
72 if not user.can_do("src", config.builder, batch.branch):
73 fail_mail("user %s is not allowed to src:%s:%s" \
74 % (user.get_login(), config.builder, batch.branch))
e1389e9c 75 lockf.close()
dfff8bd5 76 return
d2c1ec3f 77
e936beda
MM
78 if 'test-build' in r.flags and 'upgrade' in r.flags:
79 fail_mail("it's forbidden to upgrade from a test build")
e1389e9c 80 lockf.close()
e936beda
MM
81 return
82
dfff8bd5
MM
83 if "upgrade" in r.flags and not user.can_do("upgrade", config.builder, batch.branch):
84 fail_mail("user %s is not allowed to upgrade:%s:%s" \
85 % (user.get_login(), config.builder, batch.branch))
e1389e9c 86 lockf.close()
dfff8bd5 87 return
d2c1ec3f 88
07db6665 89 # src builder handles only special commands
a72a1c1c 90 if batch.is_command() and (batch.command in ["git pull"] or batch.command[:5] == "skip:" or config.builder in batch.builders):
07db6665
AM
91 batch.expand_builders(config.binary_builders + [config.src_builder])
92 else:
93 batch.expand_builders(config.binary_builders)
94
dfff8bd5
MM
95 if not batch.is_command() and config.builder in batch.builders:
96 batch.builders.remove(config.builder)
07db6665 97
dfff8bd5
MM
98 for bld in batch.builders:
99 batch.builders_status[bld] = '?'
1432ffd5 100 batch.builders_status_time[bld] = time.time()
dfff8bd5
MM
101 if bld not in config.binary_builders and bld != config.builder:
102 fail_mail("I (src rpm builder '%s') do not handle binary builder '%s', only '%s'" % \
9e8a7e70 103 (config.builder, bld, string.join(config.binary_builders)))
e1389e9c 104 lockf.close()
dfff8bd5
MM
105 return
106 if batch.is_command():
e242bc52
AM
107 if "no-chroot" in batch.command_flags:
108 if not user.can_do("command-no-chroot", bld):
109 fail_mail("user %s is not allowed to command-no-chroot:%s" \
110 % (user.get_login(), bld))
111 lockf.close()
112 return
dfff8bd5
MM
113 if not user.can_do("command", bld):
114 fail_mail("user %s is not allowed to command:%s" \
115 % (user.get_login(), bld))
e1389e9c 116 lockf.close()
dfff8bd5
MM
117 return
118 elif not user.can_do("binary", bld, batch.branch):
119 pkg = batch.spec
120 if pkg.endswith(".spec"):
121 pkg = pkg[:-5]
122 if not user.can_do("binary-" + pkg, bld, batch.branch):
123 fail_mail("user %s is not allowed to binary-%s:%s:%s" \
124 % (user.get_login(), pkg, bld, batch.branch))
e1389e9c 125 lockf.close()
dfff8bd5 126 return
e5e1ca0e
KK
127 if not "test-build" in r.flags and not user.can_do("ready", bld, batch.branch):
128 fail_mail("user %s is not allowed to send ready builds (ready:%s:%s)" \
129 % (user.get_login(), bld, batch.branch))
130 lockf.close()
131 return
e6376553 132
d8d56d0f
JR
133 pkg = batch.spec
134 if pkg.endswith(".spec"):
135 pkg = pkg[:-5]
136 if not "test-build" in r.flags and blacklist.package(pkg):
137 fail_mail("package '%s' is blacklisted, only test-builds allowed" % pkg)
138 lockf.close()
139 return
140
dfff8bd5 141 r.priority = user.check_priority(r.priority,config.builder)
dfff8bd5
MM
142 r.time = time.time()
143 log.notice("queued %s from %s" % (r.id, user.get_login()))
144 q = B_Queue(path.queue_file)
145 q.lock(0)
146 q.read()
147 q.add(r)
148 q.write()
149 q.unlock()
e1389e9c 150 lockf.close()
57b6e61d 151
59ce7cd6 152def handle_notification(r, user):
dfff8bd5
MM
153 if not user.can_do("notify", r.builder):
154 log.alert("user %s is not allowed to notify:%s" % (user.login, r.builder))
155 q = B_Queue(path.req_queue_file)
156 q.lock(0)
157 q.read()
158 not_fin = filter(lambda (r): not r.is_done(), q.requests)
159 r.apply_to(q)
160 for r in not_fin:
161 if r.is_done():
9be34149 162 util.clean_tmp(path.srpms_dir + '/' + r.id)
dfff8bd5
MM
163 now = time.time()
164 def leave_it(r):
165 # for ,,done'' set timeout to 4d
166 if r.is_done() and r.time + 4 * 24 * 60 * 60 < now:
167 return False
168 # and for not ,,done'' set it to 20d
169 if r.time + 20 * 24 * 60 * 60 < now:
9be34149 170 util.clean_tmp(path.srpms_dir + '/' + r.id)
dfff8bd5
MM
171 return False
172 return True
173 q.requests = filter(leave_it, q.requests)
174 q.write()
8d15cbfe
AM
175 q.dump(path.queue_stats_file)
176 q.dump_html(path.queue_html_stats_file)
89ad1c79 177 q.write_signed(path.req_queue_signed_file)
dfff8bd5 178 q.unlock()
59ce7cd6 179
f02c1e4d
AM
180def handle_request(req, filename = None):
181 if req == '':
c1ad9456
ER
182 log.alert('Empty body received. Filename: %s' % filename)
183 return False
184
8736fafd 185 keys = gpg.get_keys(req)
f02c1e4d 186 (em, body) = gpg.verify_sig(req)
8736fafd 187 if not em:
030fb437 188 log.alert("Invalid signature, missing/untrusted key. Keys in gpg batch: '%s'" % keys)
8736fafd 189 return False
dfff8bd5
MM
190 user = acl.user_by_email(em)
191 if user == None:
192 # FIXME: security email here
8736fafd 193 log.alert("'%s' not in acl. Keys in gpg batch: '%s'" % (em, keys))
f6eb7039 194 return False
b5e0afc4 195
dfff8bd5 196 acl.set_current_user(user)
db286098 197 status.push("request from %s" % user.login)
dfff8bd5
MM
198 r = request.parse_request(body)
199 if r.kind == 'group':
200 handle_group(r, user)
201 elif r.kind == 'notification':
202 handle_notification(r, user)
203 else:
204 msg = "%s: don't know how to handle requests of this kind '%s'" \
205 % (user.get_login(), r.kind)
206 log.alert(msg)
207 m = user.message_to()
208 m.set_headers(subject = "unknown request")
209 m.write_line(msg)
210 m.send()
211 status.pop()
f6eb7039 212 return True
cc94eb63 213
f02c1e4d 214def handle_request_main(req, filename = None):
e3e3d74f 215 acl.try_reload()
73c1dbdf 216 blacklist.try_reload()
dfff8bd5
MM
217 init_conf("src")
218 status.push("handling email request")
f02c1e4d 219 ret = handle_request(req, filename = filename)
dfff8bd5 220 status.pop()
63319e0a
AM
221 return ret
222
223def main():
f02c1e4d 224 sys.exit(not handle_request_main(sys.stdin.read()))
1f62bccc 225
e8ee9db8 226if __name__ == '__main__':
dfff8bd5 227 wrap.wrap(main)
This page took 0.691875 seconds and 4 git commands to generate.