]> git.decadent.org.uk Git - dak.git/blobdiff - daklib/queue.py
various
[dak.git] / daklib / queue.py
index 2c3602a2b4741ba4690af16b3315e181df762ae7..09831f4d75a1f1280f6e58b99c232a37af0ff6d5 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+# vim:set et sw=4:
 
 # Queue utility functions for dak
 # Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  James Troup <james@nocrew.org>
@@ -219,7 +220,21 @@ class Upload:
         try:
             os.chmod(dump_filename, 0664)
         except OSError, e:
-            raise
+            # chmod may fail when the dumpfile is not owned by the user
+            # invoking dak (like e.g. when NEW is processed by a member
+            # of ftpteam)
+            if errno.errorcode[e.errno] == 'EPERM':
+                perms = stat.S_IMODE(os.stat(dump_filename)[stat.ST_MODE])
+                # security precaution, should never happen unless a weird
+                # umask is set anywhere
+                if perms & stat.S_IWOTH:
+                    utils.fubar("%s is world writable and chmod failed." % \
+                        (dump_filename,))
+                # ignore the failed chmod otherwise as the file should
+                # already have the right privileges and is just, at worst,
+                # unreadable for world
+            else:
+                raise
 
         p = cPickle.Pickler(dump_file, 1)
         d_changes = {}
@@ -484,19 +499,18 @@ distribution."""
             if changes["architecture"].has_key("source") and \
                dsc.has_key("bts changelog"):
 
-                temp_filename = utils.temp_filename(Cnf["Dir::Queue::BTSVersionTrack"],
-                                                    dotprefix=1, perms=0644)
-                version_history = utils.open_file(temp_filename, 'w')
+                (fd, temp_filename) = utils.temp_filename(Cnf["Dir::Queue::BTSVersionTrack"], prefix=".")
+                version_history = os.fdopen(temp_filename, 'w')
                 version_history.write(dsc["bts changelog"])
                 version_history.close()
                 filename = "%s/%s" % (Cnf["Dir::Queue::BTSVersionTrack"],
                                       changes_file[:-8]+".versions")
                 os.rename(temp_filename, filename)
+                os.chmod(filename, "0644")
 
             # Write out the binary -> source mapping.
-            temp_filename = utils.temp_filename(Cnf["Dir::Queue::BTSVersionTrack"],
-                                                dotprefix=1, perms=0644)
-            debinfo = utils.open_file(temp_filename, 'w')
+            (fd, temp_filename) = utils.temp_filename(Cnf["Dir::Queue::BTSVersionTrack"], prefix=".")
+            debinfo = os.fdopen(temp_filename, 'w')
             for file_entry in file_keys:
                 f = files[file_entry]
                 if f["type"] == "deb":
@@ -508,6 +522,7 @@ distribution."""
             filename = "%s/%s" % (Cnf["Dir::Queue::BTSVersionTrack"],
                                   changes_file[:-8]+".debinfo")
             os.rename(temp_filename, filename)
+            os.chmod(filename, "0644")
 
         self.queue_build("accepted", Cnf["Dir::Queue::Accepted"])
 
@@ -655,7 +670,7 @@ distribution."""
         # If we weren't given a manual rejection message, spawn an
         # editor so the user can add one in...
         if manual and not reject_message:
-            temp_filename = utils.temp_filename()
+            (fd, temp_filename) = utils.temp_filename()
             editor = os.environ.get("EDITOR","vi")
             answer = 'E'
             while answer == 'E':
@@ -834,22 +849,23 @@ distribution."""
 
     ################################################################################
 
-    def cross_suite_version_check(self, query_result, file, new_version):
+    def cross_suite_version_check(self, query_result, file, new_version,
+            sourceful=False):
         """Ensure versions are newer than existing packages in target
         suites and that cross-suite version checking rules as
         set out in the conf file are satisfied."""
 
         # Check versions for each target suite
         for target_suite in self.pkg.changes["distribution"].keys():
-            must_be_newer_than = [ i.lower for i in self.Cnf.ValueList("Suite::%s::VersionChecks::MustBeNewerThan" % (target_suite)) ]
-            must_be_older_than = [ i.lower for i in self.Cnf.ValueList("Suite::%s::VersionChecks::MustBeOlderThan" % (target_suite)) ]
+            must_be_newer_than = [ i.lower() for i in self.Cnf.ValueList("Suite::%s::VersionChecks::MustBeNewerThan" % (target_suite)) ]
+            must_be_older_than = [ i.lower() for i in self.Cnf.ValueList("Suite::%s::VersionChecks::MustBeOlderThan" % (target_suite)) ]
             # Enforce "must be newer than target suite" even if conffile omits it
             if target_suite not in must_be_newer_than:
                 must_be_newer_than.append(target_suite)
             for entry in query_result:
                 existent_version = entry[0]
                 suite = entry[1]
-                if suite in must_be_newer_than and \
+                if suite in must_be_newer_than and sourceful and \
                    apt_pkg.VersionCompare(new_version, existent_version) < 1:
                     self.reject("%s: old version (%s) in %s >= new version (%s) targeted at %s." % (file, existent_version, suite, new_version, target_suite))
                 if suite in must_be_older_than and \
@@ -911,7 +927,8 @@ SELECT b.version, su.suite_name FROM binaries b, bin_associations ba, suite su,
    AND ba.bin = b.id AND ba.suite = su.id AND b.architecture = a.id"""
                                 % (files[file]["package"],
                                    files[file]["architecture"]))
-        self.cross_suite_version_check(q.getresult(), file, files[file]["version"])
+        self.cross_suite_version_check(q.getresult(), file,
+            files[file]["version"], sourceful=False)
 
         # Check for any existing copies of the file
         q = self.projectB.query("""
@@ -936,7 +953,8 @@ SELECT b.id FROM binaries b, architecture a
         q = self.projectB.query("""
 SELECT s.version, su.suite_name FROM source s, src_associations sa, suite su
  WHERE s.source = '%s' AND sa.source = s.id AND sa.suite = su.id""" % (dsc.get("source")))
-        self.cross_suite_version_check(q.getresult(), file, dsc.get("version"))
+        self.cross_suite_version_check(q.getresult(), file, dsc.get("version"),
+            sourceful=True)
 
         return self.reject_message