]> git.decadent.org.uk Git - dak.git/blobdiff - dak/process_upload.py
dak/process_upload.py: improve error message for ArchiveExceptions and Rejects
[dak.git] / dak / process_upload.py
index 25f32b5842f16ecdb14c91764682b7000c9a2a0a..1dbde576de16b72dddb6cc5780361db3882fb1e6 100755 (executable)
@@ -180,6 +180,7 @@ from daklib.textutils import fix_maintainer
 from daklib.regexes import *
 
 import daklib.archive
+import daklib.checks
 import daklib.upload
 
 ###############################################################################
@@ -206,17 +207,24 @@ def try_or_reject(function):
     """Try to call function or reject the upload if that fails
     """
     def wrapper(directory, upload, *args, **kwargs):
+        reason = 'No exception caught. This should not happen.'
+
         try:
             return function(directory, upload, *args, **kwargs)
+        except (daklib.archive.ArchiveException, daklib.checks.Reject) as e:
+            reason = e
+        except Exception as e:
+            reason = "There was an uncaught exception when processing your upload:\n{0}\nAny original reject reason follows below.".format(traceback.format_exc())
+
+        try:
+            upload.rollback()
+            return real_reject(directory, upload, reason=reason)
         except Exception as e:
-            try:
-                reason = "There was an uncaught exception when processing your upload:\n{0}\nAny original reject reason follows below.".format(traceback.format_exc())
-                upload.rollback()
-                return real_reject(directory, upload, reason=reason)
-            except Exception as e:
-                reason = "In addition there was an exception when rejecting the package:\n{0}\nPrevious reasons:\n{1}".format(traceback.format_exc(), reason)
-                upload.rollback()
-                return real_reject(directory, upload, reason=reason, notify=False)
+            reason = "In addition there was an exception when rejecting the package:\n{0}\nPrevious reasons:\n{1}".format(traceback.format_exc(), reason)
+            upload.rollback()
+            return real_reject(directory, upload, reason=reason, notify=False)
+
+        raise Exception('Rejecting upload failed after multiple tries. Giving up. Last reason:\n{0}'.format(reason))
 
     return wrapper
 
@@ -237,10 +245,15 @@ def subst_for_upload(upload):
                 suite_names.append(suite.suite_name)
         suite_name = ','.join(suite_names)
 
-    maintainer_field = control.get('Changed-By', control.get('Maintainer', cnf['Dinstall::MyEmailAddress']))
-    maintainer = fix_maintainer(maintainer_field)
-    addresses = utils.mail_addresses_for_upload(control.get('Maintainer', cnf['Dinstall::MyEmailAddress']), maintainer_field, changes.primary_fingerprint)
+    maintainer_field = control.get('Maintainer', cnf['Dinstall::MyEmailAddress'])
+    changed_by_field = control.get('Changed-By', maintainer_field)
+    maintainer = fix_maintainer(changed_by_field)
+    if upload.changes.source is not None:
+        addresses = utils.mail_addresses_for_upload(maintainer_field, changed_by_field, changes.primary_fingerprint)
+    else:
+        addresses = utils.mail_addresses_for_upload(maintainer_field, maintainer_field, changes.primary_fingerprint)
 
+    # debian-{devel-,}-changes@lists.debian.org toggles writes access based on this header
     bcc = 'X-DAK: dak process-upload'
     if 'Dinstall::Bcc' in cnf:
         bcc = '{0}\nBcc: {1}'.format(bcc, cnf['Dinstall::Bcc'])
@@ -260,15 +273,12 @@ def subst_for_upload(upload):
         '__DAK_ADDRESS__': cnf['Dinstall::MyEmailAddress'],
         '__MAINTAINER_FROM__': maintainer[1],
         '__MAINTAINER_TO__': ", ".join(addresses),
-        '__MAINTAINER__': maintainer_field,
+        '__MAINTAINER__': changed_by_field,
         '__BCC__': bcc,
 
         '__BUG_SERVER__': cnf.get('Dinstall::BugServer'),
 
-        # TODO: don't use private member
-        '__FILE_CONTENTS__': upload.changes._signed_file.contents,
-
-        # __REJECT_MESSAGE__
+        '__FILE_CONTENTS__': open(upload.changes.path, 'r').read(),
         }
 
     override_maintainer = cnf.get('Dinstall::OverrideMaintainer')
@@ -289,8 +299,10 @@ def accept(directory, upload):
     for suite in upload.final_suites:
         accepted_to_real_suite = accepted_to_real_suite or suite.policy_queue is None
 
+    sourceful_upload = 'source' in upload.changes.architectures
+
     control = upload.changes.changes
-    if 'source' in upload.changes.architectures and not Options['No-Action']:
+    if sourceful_upload and not Options['No-Action']:
         urgency = control.get('Urgency')
         if urgency not in cnf.value_list('Urgency::Valid'):
             urgency = cnf['Urgency::Default']
@@ -302,23 +314,28 @@ def accept(directory, upload):
     utils.send_mail(message)
 
     # send mail to announce lists and tracking server
-    subst = subst_for_upload(upload)
-    announce = set()
-    for suite in upload.final_suites:
-        if suite.policy_queue is None:
-            continue
-        announce.update(suite.announce or [])
-    announce_address = ", ".join(announce)
-    tracking = cnf.get('Dinstall::TrackingServer')
-    if tracking and 'source' in upload.changes.architectures:
-        announce_address = '{0}\nBcc: {1}@{2}'.format(announce_address, control['Source'], tracking)
-    message = utils.TemplateSubst(subst, os.path.join(cnf['Dir::Templates'], 'process-unchecked.announce'))
-    utils.send_mail(message)
+    if accepted_to_real_suite and sourceful_upload:
+        subst = subst_for_upload(upload)
+        announce = set()
+        for suite in upload.final_suites:
+            if suite.policy_queue is not None:
+                continue
+            announce.update(suite.announce or [])
+        announce_address = ", ".join(announce)
+
+        tracking = cnf.get('Dinstall::TrackingServer')
+        if tracking and 'source' in upload.changes.architectures:
+            announce_address = '{0}\nBcc: {1}@{2}'.format(announce_address, control['Source'], tracking)
+
+        subst['__ANNOUNCE_LIST_ADDRESS__'] = announce_address
+
+        message = utils.TemplateSubst(subst, os.path.join(cnf['Dir::Templates'], 'process-unchecked.announce'))
+        utils.send_mail(message)
 
     # Only close bugs for uploads that were not redirected to a policy queue.
     # process-policy will close bugs for those once they are accepted.
     subst = subst_for_upload(upload)
-    if accepted_to_real_suite and cnf.find_b('Dinstall::CloseBugs') and upload.changes.source is not None:
+    if accepted_to_real_suite and cnf.find_b('Dinstall::CloseBugs') and sourceful_upload:
         for bugnum in upload.changes.closed_bugs:
             subst['__BUG_NUMBER__'] = str(bugnum)
 
@@ -349,7 +366,7 @@ def accept_to_new(directory, upload):
     Logger.log(['ACCEPT-TO-NEW', upload.changes.filename])
 
     upload.install_to_new()
-    # TODO: tag bugs pending, send announcement
+    # TODO: tag bugs pending
 
     subst = subst_for_upload(upload)
     message = utils.TemplateSubst(subst, os.path.join(cnf['Dir::Templates'], 'process-unchecked.new'))
@@ -377,6 +394,8 @@ def real_reject(directory, upload, reason=None, notify=True):
     for fn in files:
         src = os.path.join(upload.directory, fn)
         dst = utils.find_next_free(os.path.join(rejectdir, fn))
+        if not os.path.exists(src):
+            continue
         fs.copy(src, dst)
 
     if upload.reject_reasons is not None:
@@ -392,7 +411,6 @@ def real_reject(directory, upload, reason=None, notify=True):
     fh.write(reason)
     fh.close()
 
-    # TODO: fix
     if notify:
         subst = subst_for_upload(upload)
         subst['__REJECTOR_ADDRESS__'] = cnf['Dinstall::MyEmailAddress']
@@ -488,7 +506,6 @@ def action(directory, upload):
     elif answer == 'S':
         processed = False
 
-    #raise Exception("FAIL")
     if not Options['No-Action']:
         upload.commit()
 
@@ -509,19 +526,6 @@ def process_it(directory, changes, keyrings, session):
     print "\n{0}\n".format(changes.filename)
     Logger.log(["Processing changes file", changes.filename])
 
-    cnf = Config()
-
-    # Some defaults in case we can't fully process the .changes file
-    #u.pkg.changes["maintainer2047"] = cnf["Dinstall::MyEmailAddress"]
-    #u.pkg.changes["changedby2047"] = cnf["Dinstall::MyEmailAddress"]
-
-    # debian-{devel-,}-changes@lists.debian.org toggles writes access based on this header
-    bcc = "X-DAK: dak process-upload"
-    #if cnf.has_key("Dinstall::Bcc"):
-    #    u.Subst["__BCC__"] = bcc + "\nBcc: %s" % (cnf["Dinstall::Bcc"])
-    #else:
-    #    u.Subst["__BCC__"] = bcc
-
     with daklib.archive.ArchiveUpload(directory, changes, keyrings) as upload:
         processed = action(directory, upload)
         if processed and not Options['No-Action']: