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