]> git.decadent.org.uk Git - dak.git/blobdiff - dak/process_new.py
Merge branch 'master' into security
[dak.git] / dak / process_new.py
index c0bc51f371bebe007c69441afc134e98678d8789..3dd93ada1a68ba480c2dcf6c6a9d186e09ef7da4 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+# vim:set et ts=4 sw=4:
 
 # Handles NEW and BYHAND packages
 # Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  James Troup <james@nocrew.org>
@@ -151,7 +152,7 @@ def indiv_sg_compare (a, b):
 def sg_compare (a, b):
     a = a[1]
     b = b[1]
-    """Sort by have note, time of oldest upload."""
+    """Sort by have note, source already in database and time of oldest upload."""
     # Sort by have note
     a_note_state = a["note_state"]
     b_note_state = b["note_state"]
@@ -159,6 +160,10 @@ def sg_compare (a, b):
         return -1
     elif a_note_state > b_note_state:
         return 1
+    # Sort by source already in database (descending)
+    source_in_database = cmp(a["source_in_database"], b["source_in_database"])
+    if source_in_database:
+        return -source_in_database
 
     # Sort by time of oldest upload
     return cmp(a["oldest"], b["oldest"])
@@ -193,6 +198,9 @@ def sort_changes(changes_files):
         per_source[source]["list"].append(cache[filename])
     # Determine oldest time and have note status for each source group
     for source in per_source.keys():
+        q = projectB.query("SELECT 1 FROM source WHERE source = '%s'" % source)
+        ql = q.getresult()
+        per_source[source]["source_in_database"] = len(ql)>0
         source_list = per_source[source]["list"]
         first = source_list[0]
         oldest = os.stat(first["filename"])[stat.ST_MTIME]
@@ -806,21 +814,107 @@ def move_to_dir (dest, perms=0660, changesperms=0664):
     for f in file_keys:
         utils.move (f, dest, perms=perms)
 
+def is_source_in_queue_dir(qdir):
+    entries = [ x for x in os.listdir(qdir) if x.startswith(Upload.pkg.changes["source"])
+                and x.endswith(".changes") ]
+    for entry in entries:
+        # read the .dak
+        u = queue.Upload(Cnf)
+        u.pkg.changes_file = os.path.join(qdir, entry)
+        u.update_vars()
+        if not u.pkg.changes["architecture"].has_key("source"):
+            # another binary upload, ignore
+            continue
+        if Upload.pkg.changes["version"] != u.pkg.changes["version"]:
+            # another version, ignore
+            continue
+        # found it!
+        return True
+    return False
+
+def move_to_holding(suite, queue_dir):
+    print "Moving to %s holding area." % (suite.upper(),)
+    if Options["No-Action"]:
+       return
+    Logger.log(["Moving to %s" % (suite,), Upload.pkg.changes_file])
+    Upload.dump_vars(queue_dir)
+    move_to_dir(queue_dir)
+    os.unlink(Upload.pkg.changes_file[:-8]+".dak")
+
+def _accept():
+    if Options["No-Action"]:
+        return
+    (summary, short_summary) = Upload.build_summaries()
+    Upload.accept(summary, short_summary)
+    os.unlink(Upload.pkg.changes_file[:-8]+".dak")
+
+def do_accept_stableupdate(suite, q):
+    queue_dir = Cnf["Dir::Queue::%s" % (q,)]
+    if not Upload.pkg.changes["architecture"].has_key("source"):
+        # It is not a sourceful upload.  So its source may be either in p-u
+        # holding, in new, in accepted or already installed.
+        if is_source_in_queue_dir(queue_dir):
+            # It's in p-u holding, so move it there.
+            print "Binary-only upload, source in %s." % (q,)
+            move_to_holding(suite, queue_dir)
+        elif Upload.source_exists(Upload.pkg.changes["source"],
+                Upload.pkg.changes["version"]):
+            # dak tells us that there is source available.  At time of
+            # writing this means that it is installed, so put it into
+            # accepted.
+            print "Binary-only upload, source installed."
+            _accept()
+        elif is_source_in_queue_dir(Cnf["Dir::Queue::Accepted"]):
+            # The source is in accepted, the binary cleared NEW: accept it.
+            print "Binary-only upload, source in accepted."
+            _accept()
+        elif is_source_in_queue_dir(Cnf["Dir::Queue::New"]):
+            # It's in NEW.  We expect the source to land in p-u holding
+            # pretty soon.
+            print "Binary-only upload, source in new."
+            move_to_holding(suite, queue_dir)
+        else:
+            # No case applicable.  Bail out.  Return will cause the upload
+            # to be skipped.
+            print "ERROR"
+            print "Stable update failed.  Source not found."
+            return
+    else:
+        # We are handling a sourceful upload.  Move to accepted if currently
+        # in p-u holding and to p-u holding otherwise.
+        if is_source_in_queue_dir(queue_dir):
+            print "Sourceful upload in %s, accepting." % (q,)
+            _accept()
+        else:
+            move_to_holding(suite, queue_dir)
+
 def do_accept():
     print "ACCEPT"
     if not Options["No-Action"]:
         get_accept_lock()
         (summary, short_summary) = Upload.build_summaries()
-    if Cnf.FindB("Dinstall::SecurityQueueHandling"):
-        Upload.dump_vars(Cnf["Dir::Queue::Embargoed"])
-        move_to_dir(Cnf["Dir::Queue::Embargoed"])
-        Upload.queue_build("embargoed", Cnf["Dir::Queue::Embargoed"])
-        # Check for override disparities
-        Upload.Subst["__SUMMARY__"] = summary
-    else:
-        Upload.accept(summary, short_summary)
-        os.unlink(Upload.pkg.changes_file[:-8]+".dak")
-    os.unlink(Cnf["Process-New::AcceptedLockFile"])
+    try:
+        if Cnf.FindB("Dinstall::SecurityQueueHandling"):
+            Upload.dump_vars(Cnf["Dir::Queue::Embargoed"])
+            move_to_dir(Cnf["Dir::Queue::Embargoed"])
+            Upload.queue_build("embargoed", Cnf["Dir::Queue::Embargoed"])
+            # Check for override disparities
+            Upload.Subst["__SUMMARY__"] = summary
+        else:
+            # Stable updates need to be copied to proposed-updates holding
+            # area instead of accepted.  Sourceful uploads need to go
+            # to it directly, binaries only if the source has not yet been
+            # accepted into p-u.
+            for suite, q in [("proposed-updates", "ProposedUpdates"),
+                    ("oldstable-proposed-updates", "OldProposedUpdates")]:
+                if not Upload.pkg.changes["distribution"].has_key(suite):
+                    continue
+                return do_accept_stableupdate(suite, q)
+            # Just a normal upload, accept it...
+            _accept()
+    finally:
+        if not Options["No-Action"]:
+            os.unlink(Cnf["Process-New::AcceptedLockFile"])
 
 def check_status(files):
     new = byhand = 0