+++ /dev/null
-# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
-
-import email
-import string
-import time
-import os
-import StringIO
-import sys
-import fnmatch
-
-import gpg
-import request
-import log
-import path
-import util
-import wrap
-import status
-from acl import acl
-from lock import lock
-from bqueue import B_Queue
-from config import config, init_conf
-
-def check_double_id(id):
- id_nl = id + "\n"
-
- ids = open(path.processed_ids_file)
- for i in ids.xreadlines():
- if i == id_nl:
- # FIXME: security email here?
- log.alert("request %s already processed" % id)
- return 1
- ids.close()
-
- ids = open(path.processed_ids_file, "a")
- ids.write(id_nl)
- ids.close()
-
- return 0
-
-def handle_group(r, user):
- lockf = None
- def fail_mail(msg):
- if len(r.batches) >= 1:
- spec = r.batches[0].spec
- else:
- spec = "None.spec"
- log.error("%s: %s" % (spec, msg))
- m = user.message_to()
- m.set_headers(subject = "building %s failed" % spec)
- m.write_line(msg)
- m.send()
-
- lockf = lock("request")
- if check_double_id(r.id):
- lockf.close()
- return
-
- for batch in r.batches:
-
- if not user.can_do("src", config.builder, batch.branch):
- fail_mail("user %s is not allowed to src:%s:%s" \
- % (user.get_login(), config.builder, batch.branch))
- lockf.close()
- return
-
- if 'test-build' in r.flags and 'upgrade' in r.flags:
- fail_mail("it's forbidden to upgrade from a test build")
- lockf.close()
- return
-
- if "upgrade" in r.flags and not user.can_do("upgrade", config.builder, batch.branch):
- fail_mail("user %s is not allowed to upgrade:%s:%s" \
- % (user.get_login(), config.builder, batch.branch))
- lockf.close()
- return
-
- # src builder handles only special commands
- if batch.is_command() and (batch.command in ["git pull"] or batch.command[:5] == "skip:" or config.builder in batch.builders):
- batch.expand_builders(config.binary_builders + [config.src_builder])
- else:
- batch.expand_builders(config.binary_builders)
-
- if not batch.is_command() and config.builder in batch.builders:
- batch.builders.remove(config.builder)
-
- for bld in batch.builders:
- batch.builders_status[bld] = '?'
- batch.builders_status_time[bld] = time.time()
- if bld not in config.binary_builders and bld != config.builder:
- fail_mail("I (src rpm builder '%s') do not handle binary builder '%s', only '%s'" % \
- (config.builder, bld, string.join(config.binary_builders)))
- lockf.close()
- return
- if batch.is_command():
- if "no-chroot" in batch.command_flags:
- if not user.can_do("command-no-chroot", bld):
- fail_mail("user %s is not allowed to command-no-chroot:%s" \
- % (user.get_login(), bld))
- lockf.close()
- return
- if not user.can_do("command", bld):
- fail_mail("user %s is not allowed to command:%s" \
- % (user.get_login(), bld))
- lockf.close()
- return
- elif not user.can_do("binary", bld, batch.branch):
- pkg = batch.spec
- if pkg.endswith(".spec"):
- pkg = pkg[:-5]
- if not user.can_do("binary-" + pkg, bld, batch.branch):
- fail_mail("user %s is not allowed to binary-%s:%s:%s" \
- % (user.get_login(), pkg, bld, batch.branch))
- lockf.close()
- return
-
- r.priority = user.check_priority(r.priority,config.builder)
- r.requester = user.get_login()
- r.requester_email = user.mail_to()
- r.time = time.time()
- log.notice("queued %s from %s" % (r.id, user.get_login()))
- q = B_Queue(path.queue_file)
- q.lock(0)
- q.read()
- q.add(r)
- q.write()
- q.unlock()
- lockf.close()
-
-def handle_notification(r, user):
- if not user.can_do("notify", r.builder):
- log.alert("user %s is not allowed to notify:%s" % (user.login, r.builder))
- q = B_Queue(path.req_queue_file)
- q.lock(0)
- q.read()
- not_fin = filter(lambda (r): not r.is_done(), q.requests)
- r.apply_to(q)
- for r in not_fin:
- if r.is_done():
- util.clean_tmp(path.srpms_dir + '/' + r.id)
- now = time.time()
- def leave_it(r):
- # for ,,done'' set timeout to 4d
- if r.is_done() and r.time + 4 * 24 * 60 * 60 < now:
- return False
- # and for not ,,done'' set it to 20d
- if r.time + 20 * 24 * 60 * 60 < now:
- util.clean_tmp(path.srpms_dir + '/' + r.id)
- return False
- return True
- q.requests = filter(leave_it, q.requests)
- q.write()
- q.dump(path.queue_stats_file)
- q.dump_html(path.queue_html_stats_file)
- q.write_signed(path.req_queue_signed_file)
- q.unlock()
-
-def handle_request(req, filename = None):
- if req == '':
- log.alert('Empty body received. Filename: %s' % filename)
- return False
-
- keys = gpg.get_keys(req)
- (em, body) = gpg.verify_sig(req)
- if not em:
- log.alert("Invalid signature, missing/untrusted key. Keys in gpg batch: '%s'" % keys)
- return False
- user = acl.user_by_email(em)
- if user == None:
- # FIXME: security email here
- log.alert("'%s' not in acl. Keys in gpg batch: '%s'" % (em, keys))
- return False
-
- acl.set_current_user(user)
- status.push("request from %s" % user.login)
- r = request.parse_request(body)
- if r.kind == 'group':
- handle_group(r, user)
- elif r.kind == 'notification':
- handle_notification(r, user)
- else:
- msg = "%s: don't know how to handle requests of this kind '%s'" \
- % (user.get_login(), r.kind)
- log.alert(msg)
- m = user.message_to()
- m.set_headers(subject = "unknown request")
- m.write_line(msg)
- m.send()
- status.pop()
- return True
-
-def handle_request_main(req, filename = None):
- acl.try_reload()
- init_conf("src")
- status.push("handling email request")
- ret = handle_request(req, filename = filename)
- status.pop()
- return ret
-
-def main():
- sys.exit(not handle_request_main(sys.stdin.read()))
-
-if __name__ == '__main__':
- wrap.wrap(main)