]> git.decadent.org.uk Git - dak.git/commitdiff
Merge commit 'private/master' into process-upload
authorFrank Lichtenheld <djpig@debian.org>
Fri, 30 Oct 2009 15:16:40 +0000 (15:16 +0000)
committerFrank Lichtenheld <djpig@debian.org>
Fri, 30 Oct 2009 15:16:40 +0000 (15:16 +0000)
18 files changed:
dak/add_user.py
dak/check_archive.py
dak/contents.py
dak/cruft_report.py
dak/dak.py
dak/dakdb/update20.py [new file with mode: 0755]
dak/generate_releases.py
dak/import_known_changes.py [new file with mode: 0755]
dak/make_suite_file_list.py
dak/new_security_install.py
dak/show_deferred.py
dak/update_db.py
daklib/binary.py
daklib/changes.py
daklib/dbconn.py
daklib/extensions.py [deleted file]
daklib/queue.py
daklib/utils.py

index 77de3e3fb617290c769a2752d0e5db66b2e7234d..28d312087fbcd712408027293d80e38dadb823fb 100755 (executable)
@@ -46,28 +46,28 @@ Adds a new user to the dak databases and keyrings
 # Stolen from userdir-ldap
 # Compute a random password using /dev/urandom.
 def GenPass():
-   # Generate a 10 character random string
-   SaltVals = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/."
-   Rand = open("/dev/urandom")
-   Password = ""
-   for i in range(0,15):
-      Password = Password + SaltVals[ord(Rand.read(1)[0]) % len(SaltVals)]
-   return Password
+    # Generate a 10 character random string
+    SaltVals = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/."
+    Rand = open("/dev/urandom")
+    Password = ""
+    for i in range(0,15):
+        Password = Password + SaltVals[ord(Rand.read(1)[0]) % len(SaltVals)]
+    return Password
 
 # Compute the MD5 crypted version of the given password
 def HashPass(Password):
-   import crypt
-   # Hash it telling glibc to use the MD5 algorithm - if you dont have
-   # glibc then just change Salt = "$1$" to Salt = ""
-   SaltVals = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/."
-   Salt  = "$1$"
-   Rand = open("/dev/urandom")
-   for x in range(0,10):
-      Salt = Salt + SaltVals[ord(Rand.read(1)[0]) % len(SaltVals)]
-   Pass = crypt.crypt(Password,Salt)
-   if len(Pass) < 14:
-      raise "Password Error", "MD5 password hashing failed, not changing the password!"
-   return Pass
+    import crypt
+    # Hash it telling glibc to use the MD5 algorithm - if you dont have
+    # glibc then just change Salt = "$1$" to Salt = ""
+    SaltVals = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/."
+    Salt  = "$1$"
+    Rand = open("/dev/urandom")
+    for x in range(0,10):
+        Salt = Salt + SaltVals[ord(Rand.read(1)[0]) % len(SaltVals)]
+    Pass = crypt.crypt(Password,Salt)
+    if len(Pass) < 14:
+        raise "Password Error", "MD5 password hashing failed, not changing the password!"
+    return Pass
 
 ################################################################################
 
@@ -112,8 +112,8 @@ def main():
                  ]
 
     for i in [ "help", "create" ]:
-       if not Cnf.has_key("Add-User::Options::%s" % (i)):
-           Cnf["Add-User::Options::%s" % (i)] = ""
+        if not Cnf.has_key("Add-User::Options::%s" % (i)):
+            Cnf["Add-User::Options::%s" % (i)] = ""
 
     apt_pkg.ParseCommandLine(Cnf, Arguments, sys.argv)
 
@@ -138,10 +138,10 @@ def main():
     (result, output) = commands.getstatusoutput(cmd)
     m = re_gpg_fingerprint.search(output)
     if not m:
-       print output
+        print output
         utils.fubar("0x%s: (1) No fingerprint found in gpg output but it returned 0?\n%s" \
-                                       % (Cnf["Add-User::Options::Key"], utils.prefix_multi_line_string(output, \
-                                                                                                                                                               " [GPG output:] ")))
+                                        % (Cnf["Add-User::Options::Key"], utils.prefix_multi_line_string(output, \
+                                                                                                                                                                " [GPG output:] ")))
     primary_key = m.group(1)
     primary_key = primary_key.replace(" ","")
 
@@ -174,70 +174,69 @@ def main():
     yn = utils.our_raw_input(prompt).lower()
 
     if yn == "y":
-# Create an account for the user?
-          summary = ""
-          if Cnf.FindB("Add-User::CreateAccount") or Cnf["Add-User::Options::Create"]:
-              password = GenPass()
-              pwcrypt = HashPass(password)
-              if Cnf.has_key("Add-User::GID"):
-                  cmd = "sudo /usr/sbin/useradd -g users -m -p '%s' -c '%s' -G %s %s" \
-                         % (pwcrypt, name, Cnf["Add-User::GID"], uid)
-              else:
-                  cmd = "sudo /usr/sbin/useradd -g users -m -p '%s' -c '%s' %s" \
-                         % (pwcrypt, name, uid)
-              (result, output) = commands.getstatusoutput(cmd)
-              if (result != 0):
-                   utils.fubar("Invocation of '%s' failed:\n%s\n" % (cmd, output), result)
-              try:
-                  summary+=createMail(uid, password, Cnf["Add-User::Options::Key"], Cnf["Dinstall::GPGKeyring"])
-              except:
-                  summary=""
-                  utils.warn("Could not prepare password information for mail, not sending password.")
-
-# Now add user to the database.
-          # Note that we provide a session, so we're responsible for committing
-          uidobj = get_or_set_uid(uid, session=session)
-          uid_id = uidobj.uid_id
-          add_database_user(uid)
-          session.commit()
-# The following two are kicked out in rhona, so we don't set them. kelly adds
-# them as soon as she installs a package with unknown ones, so no problems to expect here.
-# Just leave the comment in, to not think about "Why the hell aren't they added" in
-# a year, if we ever touch uma again.
-#          maint_id = database.get_or_set_maintainer_id(name)
-#          session.execute("INSERT INTO fingerprint (fingerprint, uid) VALUES (:fingerprint, uid)",
-#                          {'fingerprint': primary_key, 'uid': uid_id})
-
-# Lets add user to the email-whitelist file if its configured.
-          if Cnf.has_key("Dinstall::MailWhiteList") and Cnf["Dinstall::MailWhiteList"] != "":
-              file = utils.open_file(Cnf["Dinstall::MailWhiteList"], "a")
-              for mail in emails:
-                  file.write(mail+'\n')
-              file.close()
-
-          print "Added:\nUid:\t %s (ID: %s)\nMaint:\t %s\nFP:\t %s" % (uid, uid_id, \
-                    name, primary_key)
-
-# Should we send mail to the newly added user?
-          if Cnf.FindB("Add-User::SendEmail"):
-              mail = name + "<" + emails[0] +">"
-              Subst = {}
-              Subst["__NEW_MAINTAINER__"] = mail
-              Subst["__UID__"] = uid
-              Subst["__KEYID__"] = Cnf["Add-User::Options::Key"]
-              Subst["__PRIMARY_KEY__"] = primary_key
-              Subst["__FROM_ADDRESS__"] = Cnf["Dinstall::MyEmailAddress"]
-              Subst["__HOSTNAME__"] = Cnf["Dinstall::MyHost"]
-              Subst["__SUMMARY__"] = summary
-              new_add_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/add-user.added")
-              utils.send_mail(new_add_message)
+        # Create an account for the user?
+        summary = ""
+        if Cnf.FindB("Add-User::CreateAccount") or Cnf["Add-User::Options::Create"]:
+            password = GenPass()
+            pwcrypt = HashPass(password)
+            if Cnf.has_key("Add-User::GID"):
+                cmd = "sudo /usr/sbin/useradd -g users -m -p '%s' -c '%s' -G %s %s" \
+                       % (pwcrypt, name, Cnf["Add-User::GID"], uid)
+            else:
+                cmd = "sudo /usr/sbin/useradd -g users -m -p '%s' -c '%s' %s" \
+                       % (pwcrypt, name, uid)
+            (result, output) = commands.getstatusoutput(cmd)
+            if (result != 0):
+                utils.fubar("Invocation of '%s' failed:\n%s\n" % (cmd, output), result)
+            try:
+                summary+=createMail(uid, password, Cnf["Add-User::Options::Key"], Cnf["Dinstall::GPGKeyring"])
+            except:
+                summary=""
+                utils.warn("Could not prepare password information for mail, not sending password.")
+
+        # Now add user to the database.
+        # Note that we provide a session, so we're responsible for committing
+        uidobj = get_or_set_uid(uid, session=session)
+        uid_id = uidobj.uid_id
+        add_database_user(uid)
+        session.commit()
+
+        # The following two are kicked out in rhona, so we don't set them. kelly adds
+        # them as soon as she installs a package with unknown ones, so no problems to expect here.
+        # Just leave the comment in, to not think about "Why the hell aren't they added" in
+        # a year, if we ever touch uma again.
+        #          maint_id = database.get_or_set_maintainer_id(name)
+        #          session.execute("INSERT INTO fingerprint (fingerprint, uid) VALUES (:fingerprint, uid)",
+        #                          {'fingerprint': primary_key, 'uid': uid_id})
+
+        # Lets add user to the email-whitelist file if its configured.
+        if Cnf.has_key("Dinstall::MailWhiteList") and Cnf["Dinstall::MailWhiteList"] != "":
+            f = utils.open_file(Cnf["Dinstall::MailWhiteList"], "a")
+            for mail in emails:
+                f.write(mail+'\n')
+            f.close()
+
+        print "Added:\nUid:\t %s (ID: %s)\nMaint:\t %s\nFP:\t %s" % (uid, uid_id, \
+                     name, primary_key)
+
+        # Should we send mail to the newly added user?
+        if Cnf.FindB("Add-User::SendEmail"):
+            mail = name + "<" + emails[0] +">"
+            Subst = {}
+            Subst["__NEW_MAINTAINER__"] = mail
+            Subst["__UID__"] = uid
+            Subst["__KEYID__"] = Cnf["Add-User::Options::Key"]
+            Subst["__PRIMARY_KEY__"] = primary_key
+            Subst["__FROM_ADDRESS__"] = Cnf["Dinstall::MyEmailAddress"]
+            Subst["__HOSTNAME__"] = Cnf["Dinstall::MyHost"]
+            Subst["__SUMMARY__"] = summary
+            new_add_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/add-user.added")
+            utils.send_mail(new_add_message)
 
     else:
-          uid = None
-
+        uid = None
 
 #######################################################################################
 
 if __name__ == '__main__':
     main()
-
index 2162068e2b9d69b4885d0d5a10f2721092c9a939..b9837d3049d529da66db95423e8ab023b0d610aa 100755 (executable)
@@ -185,8 +185,8 @@ def check_override():
         print suite_name
         print "-" * len(suite_name)
         print
-        suite = get_suite(suite)
-        q = s.execute("""
+        suite = get_suite(suite_name)
+        q = session.execute("""
 SELECT DISTINCT b.package FROM binaries b, bin_associations ba
  WHERE b.id = ba.bin AND ba.suite = :suiteid AND NOT EXISTS
        (SELECT 1 FROM override o WHERE o.suite = :suiteid AND o.package = b.package)"""
@@ -195,7 +195,7 @@ SELECT DISTINCT b.package FROM binaries b, bin_associations ba
         for j in q.fetchall():
             print j[0]
 
-        q = s.execute("""
+        q = session.execute("""
 SELECT DISTINCT s.source FROM source s, src_associations sa
   WHERE s.id = sa.source AND sa.suite = :suiteid AND NOT EXISTS
        (SELECT 1 FROM override o WHERE o.suite = :suiteid and o.package = s.source)"""
@@ -427,8 +427,8 @@ def check_indices_files_exist():
     """
     for suite in [ "stable", "testing", "unstable" ]:
         for component in Cnf.ValueList("Suite::%s::Components" % (suite)):
-            architectures = database.get_suite_architectures(suite)
-            for arch in [ i.lower() for i in architectures ]:
+            architectures = get_suite_architectures(suite)
+            for arch in [ i.arch_string.lower() for i in architectures ]:
                 if arch == "source":
                     validate_sources(suite, component)
                 elif arch == "all":
@@ -475,6 +475,7 @@ def chk_bd_process_dir (unused, dirname, filenames):
 
 def check_build_depends():
     """ Validate build-dependencies of .dsc files in the archive """
+    cnf = Config()
     os.path.walk(cnf["Dir::Root"], chk_bd_process_dir, None)
 
 ################################################################################
index 834cbccf0cc5027f99ec98433403fab8895392ee..58c3aa6b668d364c23177b18b0e1b2bb9dc198ef 100755 (executable)
@@ -39,6 +39,7 @@ import os
 import logging
 import gzip
 import threading
+import traceback
 import Queue
 import apt_pkg
 from daklib import utils
index 0a1534c59dfaf8e0c6bedf9478f0133c81a12e8c..4541bf6eb6477c8c09cc91022b8c41636d031ebc 100755 (executable)
@@ -92,8 +92,9 @@ def do_anais(architecture, binaries_list, source, session):
                                WHERE ba.suite = :suiteid AND ba.bin = b.id
                                  AND b.architecture = a.id AND b.package = :package""",
                              {'suiteid': suite_id, 'package': binary})
+        ql = q.fetchall()
         versions = []
-        for i in q.fetchall():
+        for i in ql:
             arch = i[0]
             version = i[1]
             if architectures.has_key(arch):
index f9839ea0052d9f4d4fab1b0a846555b40734a5db..e424836f750b1a1f683d027ade063de8359ea5f4 100755 (executable)
@@ -134,6 +134,8 @@ def init():
          "Generate statistics"),
         ("bts-categorize",
          "Categorize uncategorized bugs filed against ftp.debian.org"),
+        ("import-known-changes",
+         "import old changes files into known_changes table"),
         ("add-user",
          "Add a user to the archive"),
         ]
diff --git a/dak/dakdb/update20.py b/dak/dakdb/update20.py
new file mode 100755 (executable)
index 0000000..f4e34cb
--- /dev/null
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+# coding=utf8
+
+"""
+Add policy queue handling support
+
+@contact: Debian FTP Master <ftpmaster@debian.org>
+@copyright: 2009  Mark Hymers <mhy@debian.org>
+@license: GNU General Public License version 2 or later
+"""
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+################################################################################
+
+
+################################################################################
+
+import psycopg2
+import time
+import os
+import datetime
+import traceback
+
+from daklib.dak_exceptions import DBUpdateError
+from daklib.config import Config
+
+################################################################################
+
+def do_update(self):
+    print "Updating use of queue table"
+
+    try:
+        c = self.db.cursor()
+
+        cnf = Config()
+
+        print "Adding path to queue table"
+        c.execute("ALTER TABLE queue ADD COLUMN path TEXT")
+        c.execute("SELECT * FROM queue")
+        rows = c.fetchall()
+        seenqueues = {}
+        for row in rows:
+            dir = cnf["Dir::Queue::%s" % row[1]].rstrip('/')
+            seenqueues[row[1].lower()] = 1
+            print "Setting %s queue to use path %s" % (row[1], dir)
+            c.execute("UPDATE queue SET path = %s WHERE id = %s", (dir, row[0]))
+
+        print "Adding missing queues to the queue table"
+        for q in cnf.SubTree("Dir::Queue").keys():
+            qname = q.lower()
+            if qname in seenqueues.keys():
+                continue
+            if qname in ["done", "holding", "reject", "newstage", "btsversiontrack"]:
+                print "Skipping queue %s" % qname
+                continue
+            pth = cnf["Dir::Queue::%s" % qname].rstrip('/')
+            if not os.path.exists(pth):
+                print "Skipping %s as %s does not exist" % (qname, pth)
+                continue
+
+            print "Adding %s queue with path %s" % (qname, pth)
+            c.execute("INSERT INTO queue (queue_name, path) VALUES (%s, %s)", (qname, pth))
+            seenqueues[qname] = 1
+
+        print "Adding queue and approved_for columns to known_changes"
+        c.execute("ALTER TABLE known_changes ADD COLUMN in_queue INT4 REFERENCES queue(id) DEFAULT NULL")
+        c.execute("ALTER TABLE known_changes ADD COLUMN approved_for INT4 REFERENCES queue(id) DEFAULT NULL")
+
+        print "Adding policy queue column to suite table"
+        c.execute("ALTER TABLE suite DROP COLUMN policy_engine")
+        c.execute("ALTER TABLE suite ADD COLUMN policy_queue_id INT4 REFERENCES queue(id) DEFAULT NULL")
+        # Handle some of our common cases automatically
+        if seenqueues.has_key('proposedupdates'):
+            c.execute("""UPDATE suite SET policy_queue_id = (SELECT id FROM queue WHERE queue_name = 'proposedupdates')
+                                      WHERE suite_name = 'proposed-updates'""")
+
+        if seenqueues.has_key('oldproposedupdates'):
+            c.execute("""UPDATE suite SET policy_queue_id = (SELECT id FROM queue WHERE queue_name = 'oldproposedupdates')
+                                      WHERE suite_name = 'oldstable-proposed-updates'""")
+
+        print "Committing"
+        c.execute("UPDATE config SET value = '20' WHERE name = 'db_revision'")
+        self.db.commit()
+
+    except psycopg2.InternalError, msg:
+        self.db.rollback()
+        raise DBUpdateError, "Unable to apply debversion update 20, rollback issued. Error message : %s" % (str(msg))
index 9de4614da4d97530678125ae0580a16c86529572..31cae490775dafcf10bcbd9e8967a6f0ab94089f 100755 (executable)
@@ -1,9 +1,12 @@
 #!/usr/bin/env python
 
-""" Create all the Release files """
-
-# Copyright (C) 2001, 2002, 2006  Anthony Towns <ajt@debian.org>
+""" Create all the Release files
 
+@contact: Debian FTPMaster <ftpmaster@debian.org>
+@Copyright: 2001, 2002, 2006  Anthony Towns <ajt@debian.org>
+@copyright: 2009  Joerg Jaspert <joerg@debian.org>
+@license: GNU General Public License version 2 or later
+"""
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 2 of the License, or
 
 ################################################################################
 
-import sys, os, stat, time
-import gzip, bz2
+import sys
+import os
+import stat
+import time
+import gzip
+import bz2
 import apt_pkg
 
 from daklib import utils
@@ -372,13 +379,21 @@ def main ():
             dest = Cnf["Dir::Root"] + tree + "/Release.gpg"
             if os.path.exists(dest):
                 os.unlink(dest)
+            inlinedest = Cnf["Dir::Root"] + tree + "/InRelease"
+            if os.path.exists(inlinedest):
+                os.unlink(inlinedest)
 
             for keyid in signkeyids:
-                if keyid != "": defkeyid = "--default-key %s" % keyid
-                else: defkeyid = ""
+                if keyid != "":
+                    defkeyid = "--default-key %s" % keyid
+                else:
+                    defkeyid = ""
                 os.system("gpg %s %s %s --detach-sign <%s >>%s" %
                         (keyring, defkeyid, arguments,
                         Cnf["Dir::Root"] + tree + "/Release", dest))
+                os.system("gpg %s %s %s --clearsign <%s >>%s" %
+                        (keyring, defkeyid, arguments,
+                        Cnf["Dir::Root"] + tree + "/Release", inlinedest))
 
 #######################################################################################
 
diff --git a/dak/import_known_changes.py b/dak/import_known_changes.py
new file mode 100755 (executable)
index 0000000..cdb1d3a
--- /dev/null
@@ -0,0 +1,346 @@
+#!/usr/bin/env python
+# coding=utf8
+
+"""
+Import known_changes files
+
+@contact: Debian FTP Master <ftpmaster@debian.org>
+@copyright: 2009  Mike O'Connor <stew@debian.org>
+@license: GNU General Public License version 2 or later
+"""
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+################################################################################
+
+
+################################################################################
+
+import sys
+import os
+import logging
+import threading
+from daklib.dbconn import DBConn,get_knownchange
+from daklib.config import Config
+import apt_pkg
+from daklib.dak_exceptions import DBUpdateError, InvalidDscError, ChangesUnicodeError
+from daklib.changes import Changes
+from daklib.utils import parse_changes, warn, gpgv_get_status_output, process_gpgv_output
+import traceback
+
+# where in dak.conf all of our configuration will be stowed
+options_prefix = "KnownChanges"
+options_prefix = "%s::Options" % options_prefix
+
+log = logging.getLogger()
+
+################################################################################
+
+
+def usage (exit_code=0):
+    print """Usage: dak import-known-changes [options]
+
+OPTIONS
+     -j n
+        run with n threads concurrently
+
+     -v, --verbose
+        show verbose information messages
+
+     -q, --quiet
+        supress all output but errors
+
+"""
+    sys.exit(exit_code)
+
+def check_signature (sig_filename, data_filename=""):
+    fingerprint = None
+
+    keyrings = [
+        "/home/joerg/keyring/keyrings/debian-keyring.gpg",
+        "/home/joerg/keyring/keyrings/debian-keyring.pgp",
+        "/home/joerg/keyring/keyrings/debian-maintainers.gpg",
+        "/home/joerg/keyring/keyrings/debian-role-keys.gpg",
+        "/home/joerg/keyring/keyrings/emeritus-keyring.pgp",
+        "/home/joerg/keyring/keyrings/emeritus-keyring.gpg",
+        "/home/joerg/keyring/keyrings/removed-keys.gpg",
+        "/home/joerg/keyring/keyrings/removed-keys.pgp"
+        ]
+
+    keyringargs = " ".join(["--keyring %s" % x for x in keyrings ])
+
+    # Build the command line
+    status_read, status_write = os.pipe()
+    cmd = "gpgv --status-fd %s %s %s" % (status_write, keyringargs, sig_filename)
+
+    # Invoke gpgv on the file
+    (output, status, exit_status) = gpgv_get_status_output(cmd, status_read, status_write)
+
+    # Process the status-fd output
+    (keywords, internal_error) = process_gpgv_output(status)
+
+    # If we failed to parse the status-fd output, let's just whine and bail now
+    if internal_error:
+        warn("Couldn't parse signature")
+        return None
+
+    # usually one would check for bad things here. We, however, do not care.
+
+    # Next check gpgv exited with a zero return code
+    if exit_status:
+        warn("Couldn't parse signature")
+        return None
+
+    # Sanity check the good stuff we expect
+    if not keywords.has_key("VALIDSIG"):
+        warn("Couldn't parse signature")
+    else:
+        args = keywords["VALIDSIG"]
+        if len(args) < 1:
+            warn("Couldn't parse signature")
+        else:
+            fingerprint = args[0]
+
+    return fingerprint
+
+
+class EndOfChanges(object):
+    """something enqueued to signify the last change"""
+    pass
+
+
+class OneAtATime(object):
+    """
+    a one space queue which sits between multiple possible producers
+    and multiple possible consumers
+    """
+    def __init__(self):
+        self.next_in_line = None
+        self.read_lock = threading.Condition()
+        self.write_lock = threading.Condition()
+        self.die = False
+
+    def plsDie(self):
+        self.die = True
+        self.write_lock.acquire()
+        self.write_lock.notifyAll()
+        self.write_lock.release()
+
+        self.read_lock.acquire()
+        self.read_lock.notifyAll()
+        self.read_lock.release()
+
+    def enqueue(self, next):
+        self.write_lock.acquire()
+        while self.next_in_line:
+            if self.die:
+                return
+            self.write_lock.wait()
+
+        assert( not self.next_in_line )
+        self.next_in_line = next
+        self.write_lock.release()
+        self.read_lock.acquire()
+        self.read_lock.notify()
+        self.read_lock.release()
+
+    def dequeue(self):
+        self.read_lock.acquire()
+        while not self.next_in_line:
+            if self.die:
+                return
+            self.read_lock.wait()
+
+        result = self.next_in_line
+
+        self.next_in_line = None
+        self.read_lock.release()
+        self.write_lock.acquire()
+        self.write_lock.notify()
+        self.write_lock.release()
+
+        if isinstance(result, EndOfChanges):
+            return None
+
+        return result
+
+class ChangesToImport(object):
+    """A changes file to be enqueued to be processed"""
+    def __init__(self, checkdir, changesfile, count):
+        self.dirpath = checkdir
+        self.changesfile = changesfile
+        self.count = count
+
+    def __str__(self):
+        return "#%d: %s in %s" % (self.count, self.changesfile, self.dirpath)
+
+class ChangesGenerator(threading.Thread):
+    """enqueues changes files to be imported"""
+    def __init__(self, parent, queue):
+        threading.Thread.__init__(self)
+        self.queue = queue
+        self.session = DBConn().session()
+        self.parent = parent
+        self.die = False
+
+    def plsDie(self):
+        self.die = True
+
+    def run(self):
+        cnf = Config()
+        count = 1
+        for directory in [ "Accepted", "Byhand", "Done", "New", "ProposedUpdates", "OldProposedUpdates" ]:
+            checkdir = cnf["Dir::Queue::%s" % (directory) ]
+            if os.path.exists(checkdir):
+                print "Looking into %s" % (checkdir)
+
+                for dirpath, dirnames, filenames in os.walk(checkdir, topdown=True):
+                    if not filenames:
+                        # Empty directory (or only subdirectories), next
+                        continue
+
+                    for changesfile in filenames:
+                        try:
+                            if not changesfile.endswith(".changes"):
+                                # Only interested in changes files.
+                                continue
+                            count += 1
+
+                            if not get_knownchange(changesfile, self.session):
+                                to_import = ChangesToImport(dirpath, changesfile, count)
+                                if self.die:
+                                    return
+                                self.queue.enqueue(to_import)
+                        except KeyboardInterrupt:
+                            print("got Ctrl-c in enqueue thread.  terminating")
+                            self.parent.plsDie()
+                            sys.exit(1)
+
+        self.queue.enqueue(EndOfChanges())
+
+class ImportThread(threading.Thread):
+    def __init__(self, parent, queue):
+        threading.Thread.__init__(self)
+        self.queue = queue
+        self.session = DBConn().session()
+        self.parent = parent
+        self.die = False
+
+    def plsDie(self):
+        self.die = True
+
+    def run(self):
+        while True:
+            try:
+                if self.die:
+                    return
+                to_import = self.queue.dequeue()
+                if not to_import:
+                    return
+
+                print( "Directory %s, file %7d, (%s)" % (to_import.dirpath[-10:], to_import.count, to_import.changesfile) )
+
+                changes = Changes()
+                changes.changes_file = to_import.changesfile
+                changesfile = os.path.join(to_import.dirpath, to_import.changesfile)
+                changes.changes = parse_changes(changesfile, signing_rules=-1)
+                changes.changes["fingerprint"] = check_signature(changesfile)
+                changes.add_known_changes(to_import.dirpath, self.session)
+                self.session.commit()
+
+            except InvalidDscError, line:
+                warn("syntax error in .dsc file '%s', line %s." % (f, line))
+
+            except ChangesUnicodeError:
+                warn("found invalid changes file, not properly utf-8 encoded")
+
+            except KeyboardInterrupt:
+                print("Caught C-c; on ImportThread. terminating.")
+                self.parent.plsDie()
+                sys.exit(1)
+
+            except:
+                self.parent.plsDie()
+                sys.exit(1)
+
+class ImportKnownChanges(object):
+    def __init__(self,num_threads):
+        self.queue = OneAtATime()
+        self.threads = [ ChangesGenerator(self,self.queue) ]
+
+        for i in range(num_threads):
+            self.threads.append( ImportThread(self,self.queue) )
+
+        try:
+            for thread in self.threads:
+                thread.start()
+
+        except KeyboardInterrupt:
+            print("Caught C-c; terminating.")
+            utils.warn("Caught C-c; terminating.")
+            self.plsDie()
+
+    def plsDie(self):
+        traceback.print_stack90
+        for thread in self.threads:
+            print( "STU: before ask %s to die" % thread )
+            thread.plsDie()
+            print( "STU: after ask %s to die" % thread )
+
+        self.threads=[]
+        sys.exit(1)
+
+
+def main():
+    cnf = Config()
+
+    arguments = [('h',"help", "%s::%s" % (options_prefix,"Help")),
+                 ('j',"concurrency", "%s::%s" % (options_prefix,"Concurrency"),"HasArg"),
+                 ('q',"quiet", "%s::%s" % (options_prefix,"Quiet")),
+                 ('v',"verbose", "%s::%s" % (options_prefix,"Verbose")),
+                ]
+
+    args = apt_pkg.ParseCommandLine(cnf.Cnf, arguments,sys.argv)
+
+    num_threads = 1
+
+    if len(args) > 0:
+        usage()
+
+    if cnf.has_key("%s::%s" % (options_prefix,"Help")):
+        usage()
+
+    level=logging.INFO
+    if cnf.has_key("%s::%s" % (options_prefix,"Quiet")):
+        level=logging.ERROR
+
+    elif cnf.has_key("%s::%s" % (options_prefix,"Verbose")):
+        level=logging.DEBUG
+
+
+    logging.basicConfig( level=level,
+                         format='%(asctime)s %(levelname)s %(message)s',
+                         stream = sys.stderr )
+
+    if Config().has_key( "%s::%s" %(options_prefix,"Concurrency")):
+        num_threads = int(Config()[ "%s::%s" %(options_prefix,"Concurrency")])
+
+    ImportKnownChanges(num_threads)
+
+
+
+
+if __name__ == '__main__':
+    main()
index 3c690a510960b42da5e9d8a36a4d9952bc7c5a84..349a4ae09115f4530e31ae3af0338be8f47696ef 100755 (executable)
@@ -54,10 +54,6 @@ Options = None  #: Parsed CommandLine arguments
 
 ################################################################################
 
-def Dict(**dict): return dict
-
-################################################################################
-
 def usage (exit_code=0):
     print """Usage: dak make-suite-file-list [OPTION]
 Write out file lists suitable for use with apt-ftparchive.
@@ -309,6 +305,8 @@ def write_filelists(packages, dislocated_files, session):
 ################################################################################
 
 def do_da_do_da():
+    cnf = Config()
+
     # If we're only doing a subset of suites, ensure we do enough to
     # be able to do arch: all mapping.
     if Options["Suite"]:
@@ -357,7 +355,7 @@ SELECT s.id, s.source, 'source', s.version, l.path, f.filename, c.name, f.id,
 
         # 'id' comes from either 'binaries' or 'source', so it's not unique
         unique_id += 1
-        packages[unique_id] = Dict(sourceid=sourceid, pkg=pkg, arch=arch, version=version,
+        packages[unique_id] = dict(sourceid=sourceid, pkg=pkg, arch=arch, version=version,
                                    path=path, filename=filename,
                                    component=component, file_id=file_id,
                                    suite=suite, filetype = filetype)
index 3eb19643b0b195db827b7da31f23daaa542719bb..55a487499bce737630740778a2bf0afcc2de1380 100755 (executable)
@@ -152,9 +152,9 @@ def advisory_info():
     svs = srcverarches.keys()
     svs.sort()
     for sv in svs:
-        as = srcverarches[sv].keys()
-        as.sort()
-        print " %s (%s)" % (sv, ", ".join(as))
+        as_ = srcverarches[sv].keys()
+        as_.sort()
+        print " %s (%s)" % (sv, ", ".join(as_))
 
 def prompt(opts, default):
     p = ""
index e8e1621d2f957cb51c861329e12377e6e780dff1..2bb643d151508bac7b20577d1f0310c51eaeba36 100755 (executable)
@@ -101,7 +101,6 @@ def table_header():
           <th align="center">Closes</th>
         </tr>
         """
-    return res
 
 def table_footer():
     return '</table><br/><p>non-NEW uploads are <a href="/deferred/">available</a>, see the <a href="ftp://ftp-master.debian.org/pub/UploadQueue/README">UploadQueue-README</a> for more information.</p></center><br/>\n'
index e9dfa9a7a12c0401ab9331f772497c6502090227..a5273217e23ec258fcf8078079d8ffc78007b0f3 100755 (executable)
@@ -44,7 +44,7 @@ from daklib.dak_exceptions import DBUpdateError
 ################################################################################
 
 Cnf = None
-required_database_schema = 19
+required_database_schema = 20
 
 ################################################################################
 
index 97e3ec0d26bb4d8c7d930555b25c7e2e159707aa..c6ee96f86d5f1eed8b210720697e1620e2448ead 100755 (executable)
@@ -248,12 +248,16 @@ class Binary(object):
                     except:
                         print >> sys.stderr, "E: %s has non-unicode filename: %s" % (package,tarinfo.name)
 
+                result = True
+
             except:
                 traceback.print_exc()
                 result = False
 
             os.chdir(cwd)
 
+        return result
+
 __all__.append('Binary')
 
 def copy_temporary_contents(package, version, archname, deb, reject, session=None):
index c5ac64a917d99c7f1b871ce6d198e1ec53185d84..fd09cb7f2086b4c96ebaeffd21da5a047ef6a31a 100755 (executable)
@@ -29,7 +29,6 @@ Changes class for dak
 
 import os
 import stat
-import time
 
 import datetime
 from cPickle import Unpickler, Pickler
@@ -189,24 +188,33 @@ class Changes(object):
             session.commit()
             session.close()
 
-    def add_known_changes(self, queue, session=None):
-        cnf = Config()
 
+    def mark_missing_fields(self):
+        """add "missing" in fields which we will require for the known_changes table"""
+        for key in ['urgency', 'maintainer', 'fingerprint', 'changed-by' ]:
+            if (not self.changes.has_key(key)) or (not self.changes[key]):
+                self.changes[key]='missing'
+
+    def add_known_changes(self, dirpath, session=None):
+        """add "missing" in fields which we will require for the known_changes table"""
+        cnf = Config()
+        privatetrans = False
         if session is None:
             session = DBConn().session()
             privatetrans = True
 
-        dirpath = cnf["Dir::Queue::%s" % (queue) ]
         changesfile = os.path.join(dirpath, self.changes_file)
         filetime = datetime.datetime.fromtimestamp(os.path.getctime(changesfile))
 
+        self.mark_missing_fields()
+
         session.execute(
             """INSERT INTO known_changes
               (changesname, seen, source, binaries, architecture, version,
               distribution, urgency, maintainer, fingerprint, changedby, date)
               VALUES (:changesfile,:filetime,:source,:binary, :architecture,
               :version,:distribution,:urgency,:maintainer,:fingerprint,:changedby,:date)""",
-              { 'changesfile':changesfile,
+              { 'changesfile':self.changes_file,
                 'filetime':filetime,
                 'source':self.changes["source"],
                 'binary':self.changes["binary"],
index 45e000d395fbf104a8331004e7a95451114ba1f6..5f24aa73895dc52664e2200cddf06f6a229d5fce 100755 (executable)
@@ -66,10 +66,10 @@ class DebVersion(sqltypes.Text):
 
 sa_major_version = sqlalchemy.__version__[0:3]
 if sa_major_version == "0.5":
-        from sqlalchemy.databases import postgres
-        postgres.ischema_names['debversion'] = DebVersion
+    from sqlalchemy.databases import postgres
+    postgres.ischema_names['debversion'] = DebVersion
 else:
-        raise Exception("dak isn't ported to SQLA versions != 0.5 yet.  See daklib/dbconn.py")
+    raise Exception("dak isn't ported to SQLA versions != 0.5 yet.  See daklib/dbconn.py")
 
 ################################################################################
 
@@ -286,12 +286,12 @@ def get_suites_binary_in(package, session=None):
 __all__.append('get_suites_binary_in')
 
 @session_wrapper
-def get_binary_from_id(id, session=None):
+def get_binary_from_id(binary_id, session=None):
     """
     Returns DBBinary object for given C{id}
 
-    @type id: int
-    @param id: Id of the required binary
+    @type binary_id: int
+    @param binary_id: Id of the required binary
 
     @type session: Session
     @param session: Optional SQLA session object (a temporary one will be
@@ -301,7 +301,7 @@ def get_binary_from_id(id, session=None):
     @return: DBBinary object for the given binary (None if not present)
     """
 
-    q = session.query(DBBinary).filter_by(binary_id=id)
+    q = session.query(DBBinary).filter_by(binary_id=binary_id)
 
     try:
         return q.one()
@@ -769,7 +769,7 @@ def check_poolfile(filename, filesize, md5sum, location_id, session=None):
         ret = (False, None)
     else:
         obj = q.one()
-        if obj.md5sum != md5sum or obj.filesize != filesize:
+        if obj.md5sum != md5sum or obj.filesize != int(filesize):
             ret = (False, obj)
 
     if ret is None:
@@ -944,8 +944,8 @@ class Keyring(object):
     def __repr__(self):
         return '<Keyring %s>' % self.keyring_name
 
-    def de_escape_gpg_str(self, str):
-        esclist = re.split(r'(\\x..)', str)
+    def de_escape_gpg_str(self, txt):
+        esclist = re.split(r'(\\x..)', txt)
         for x in range(1,len(esclist),2):
             esclist[x] = "%c" % (int(esclist[x][2:],16))
         return "".join(esclist)
@@ -1444,13 +1444,13 @@ def insert_pending_content_paths(package, fullpaths, session=None):
         # Insert paths
         pathcache = {}
         for fullpath in fullpaths:
-            (path, file) = os.path.split(fullpath)
+            (path, filename) = os.path.split(fullpath)
 
             if path.startswith( "./" ):
                 path = path[2:]
 
             filepath_id = get_or_set_contents_path_id(path, session)
-            filename_id = get_or_set_contents_file_id(file, session)
+            filename_id = get_or_set_contents_file_id(filename, session)
 
             pathcache[fullpath] = (filepath_id, filename_id)
 
@@ -2552,7 +2552,8 @@ class DBConn(Singleton):
                                                        primaryjoin=(self.tbl_src_uploaders.c.maintainer==self.tbl_maintainer.c.id))))
 
         mapper(Suite, self.tbl_suite,
-               properties = dict(suite_id = self.tbl_suite.c.id))
+               properties = dict(suite_id = self.tbl_suite.c.id,
+                                 policy_queue = relation(Queue)))
 
         mapper(SuiteArchitecture, self.tbl_suite_architectures,
                properties = dict(suite_id = self.tbl_suite_architectures.c.suite,
diff --git a/daklib/extensions.py b/daklib/extensions.py
deleted file mode 100755 (executable)
index 88de870..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Utility functions for extensions
-
-@contact: Debian FTP Master <ftpmaster@debian.org>
-@copyright: 2008 Anthony Towns <ajt@dbeian.org>
-@license: GNU General Public License version 2 or later
-"""
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-dak_functions_to_replace = {}
-dak_replaced_functions = {}
-
-def replace_dak_function(module, name):
-    """
-    Decorator to make a function replace a standard dak function
-    in a given module.
-
-    @type module: string
-    @param module: name of module where replaced function is in
-
-    @type name: string
-    @param name: name of the function to replace
-    """
-
-    def x(f):
-        def myfunc(*a,**kw):
-            global replaced_funcs
-            f(dak_replaced_functions[name], *a, **kw)
-        myfunc.__name__ = f.__name__
-        myfunc.__doc__ = f.__doc__
-        myfunc.__dict__.update(f.__dict__)
-
-        fnname = "%s:%s" % (module, name)
-        if fnname in dak_functions_to_replace:
-            raise Exception, \
-                "%s in %s already marked to be replaced" % (name, module)
-        dak_functions_to_replace["%s:%s" % (module,name)] = myfunc
-        return f
-    return x
-
-################################################################################
-
-def init(name, module, userext):
-    global dak_replaced_functions
-
-    # This bit should be done automatically too
-    dak_replaced_functions = {}
-    for f,newfunc in dak_functions_to_replace.iteritems():
-        m,f = f.split(":",1)
-        if len(f) > 0 and m == name:
-            dak_replaced_functions[f] = module.__dict__[f]
-            module.__dict__[f] = newfunc
index cc1e855ad307a74a1e13b62733fd25f059bfe67b..3e19ac18722c8115f4ed16621b5d379ae66bd9e3 100755 (executable)
@@ -28,7 +28,6 @@ Queue utility functions for dak
 
 import errno
 import os
-import pg
 import stat
 import sys
 import time
@@ -38,7 +37,6 @@ import utils
 import commands
 import shutil
 import textwrap
-import tempfile
 from types import *
 
 import yaml
@@ -298,7 +296,7 @@ class Upload(object):
 
         # If 'dak process-unchecked' crashed out in the right place, architecture may still be a string.
         if not self.pkg.changes.has_key("architecture") or not \
-           isinstance(self.pkg.changes["architecture"], DictType):
+           isinstance(self.pkg.changes["architecture"], dict):
             self.pkg.changes["architecture"] = { "Unknown" : "" }
 
         # and maintainer2047 may not exist.
@@ -408,7 +406,7 @@ class Upload(object):
                    fix_maintainer (self.pkg.changes["maintainer"])
         except ParseMaintError, msg:
             self.rejects.append("%s: Maintainer field ('%s') failed to parse: %s" \
-                   % (filename, changes["maintainer"], msg))
+                   % (filename, self.pkg.changes["maintainer"], msg))
 
         # ...likewise for the Changed-By: field if it exists.
         try:
@@ -755,7 +753,7 @@ class Upload(object):
 
         # Validate the component
         if not get_component(entry["component"], session):
-            self.rejects.append("file '%s' has unknown component '%s'." % (f, component))
+            self.rejects.append("file '%s' has unknown component '%s'." % (f, entry["component"]))
             return
 
         # See if the package is NEW
@@ -770,7 +768,7 @@ class Upload(object):
         location = cnf["Dir::Pool"]
         l = get_location(location, entry["component"], archive, session)
         if l is None:
-            self.rejects.append("[INTERNAL ERROR] couldn't determine location (Component: %s, Archive: %s)" % (component, archive))
+            self.rejects.append("[INTERNAL ERROR] couldn't determine location (Component: %s, Archive: %s)" % (entry["component"], archive))
             entry["location id"] = -1
         else:
             entry["location id"] = l.location_id
@@ -1565,10 +1563,10 @@ class Upload(object):
         rej = False
         for f in self.pkg.files.keys():
             if self.pkg.files[f].has_key("byhand"):
-                self.rejects.append("%s may not upload BYHAND file %s" % (uid, f))
+                self.rejects.append("%s may not upload BYHAND file %s" % (fpr.uid.uid, f))
                 rej = True
             if self.pkg.files[f].has_key("new"):
-                self.rejects.append("%s may not upload NEW file %s" % (uid, f))
+                self.rejects.append("%s may not upload NEW file %s" % (fpr.uid.uid, f))
                 rej = True
 
         if rej:
@@ -1978,14 +1976,14 @@ distribution."""
 
     ###########################################################################
 
-    def remove(self, dir=None):
+    def remove(self, from_dir=None):
         """
         Used (for instance) in p-u to remove the package from unchecked
         """
-        if dir is None:
+        if from_dir is None:
             os.chdir(self.pkg.directory)
         else:
-            os.chdir(dir)
+            os.chdir(from_dir)
 
         for f in self.pkg.files.keys():
             os.unlink(f)
@@ -2150,7 +2148,7 @@ distribution."""
         return 0
 
     ################################################################################
-    def in_override_p(self, package, component, suite, binary_type, file, session):
+    def in_override_p(self, package, component, suite, binary_type, filename, session):
         """
         Check if a package already has override entries in the DB
 
@@ -2166,8 +2164,8 @@ distribution."""
         @type binary_type: string
         @param binary_type: type of the package
 
-        @type file: string
-        @param file: filename we check
+        @type filename: string
+        @param filename: filename we check
 
         @return: the database result. But noone cares anyway.
 
@@ -2193,8 +2191,8 @@ distribution."""
         # Remember the section and priority so we can check them later if appropriate
         if len(result) > 0:
             result = result[0]
-            self.pkg.files[file]["override section"] = result.section.section
-            self.pkg.files[file]["override priority"] = result.priority.priority
+            self.pkg.files[filename]["override section"] = result.section.section
+            self.pkg.files[filename]["override priority"] = result.priority.priority
             return result
 
         return None
@@ -2222,13 +2220,13 @@ distribution."""
 
     ################################################################################
 
-    def cross_suite_version_check(self, sv_list, file, new_version, sourceful=False):
+    def cross_suite_version_check(self, sv_list, filename, new_version, sourceful=False):
         """
         @type sv_list: list
         @param sv_list: list of (suite, version) tuples to check
 
-        @type file: string
-        @param file: XXX
+        @type filename: string
+        @param filename: XXX
 
         @type new_version: string
         @param new_version: XXX
@@ -2253,7 +2251,7 @@ distribution."""
                 vercmp = apt_pkg.VersionCompare(new_version, existent_version)
 
                 if suite in must_be_newer_than and sourceful and vercmp < 1:
-                    self.rejects.append("%s: old version (%s) in %s >= new version (%s) targeted at %s." % (file, existent_version, suite, new_version, target_suite))
+                    self.rejects.append("%s: old version (%s) in %s >= new version (%s) targeted at %s." % (filename, existent_version, suite, new_version, target_suite))
 
                 if suite in must_be_older_than and vercmp > -1:
                     cansave = 0
@@ -2286,7 +2284,7 @@ distribution."""
                             self.rejects.append("Won't propogate NEW packages.")
                         elif apt_pkg.VersionCompare(new_version, add_version) < 0:
                             # propogation would be redundant. no need to reject though.
-                            self.warnings.append("ignoring versionconflict: %s: old version (%s) in %s <= new version (%s) targeted at %s." % (file, existent_version, suite, new_version, target_suite))
+                            self.warnings.append("ignoring versionconflict: %s: old version (%s) in %s <= new version (%s) targeted at %s." % (filename, existent_version, suite, new_version, target_suite))
                             cansave = 1
                         elif apt_pkg.VersionCompare(new_version, add_version) > 0 and \
                              apt_pkg.VersionCompare(add_version, target_version) >= 0:
@@ -2297,29 +2295,29 @@ distribution."""
                             cansave = 1
 
                     if not cansave:
-                        self.reject.append("%s: old version (%s) in %s <= new version (%s) targeted at %s." % (file, existent_version, suite, new_version, target_suite))
+                        self.reject.append("%s: old version (%s) in %s <= new version (%s) targeted at %s." % (filename, existent_version, suite, new_version, target_suite))
 
     ################################################################################
-    def check_binary_against_db(self, file, session):
+    def check_binary_against_db(self, filename, session):
         # Ensure version is sane
         q = session.query(BinAssociation)
-        q = q.join(DBBinary).filter(DBBinary.package==self.pkg.files[file]["package"])
-        q = q.join(Architecture).filter(Architecture.arch_string.in_([self.pkg.files[file]["architecture"], 'all']))
+        q = q.join(DBBinary).filter(DBBinary.package==self.pkg.files[filename]["package"])
+        q = q.join(Architecture).filter(Architecture.arch_string.in_([self.pkg.files[filename]["architecture"], 'all']))
 
         self.cross_suite_version_check([ (x.suite.suite_name, x.binary.version) for x in q.all() ],
-                                       file, self.pkg.files[file]["version"], sourceful=False)
+                                       filename, self.pkg.files[filename]["version"], sourceful=False)
 
         # Check for any existing copies of the file
-        q = session.query(DBBinary).filter_by(package=self.pkg.files[file]["package"])
-        q = q.filter_by(version=self.pkg.files[file]["version"])
-        q = q.join(Architecture).filter_by(arch_string=self.pkg.files[file]["architecture"])
+        q = session.query(DBBinary).filter_by(package=self.pkg.files[filename]["package"])
+        q = q.filter_by(version=self.pkg.files[filename]["version"])
+        q = q.join(Architecture).filter_by(arch_string=self.pkg.files[filename]["architecture"])
 
         if q.count() > 0:
-            self.rejects.append("%s: can not overwrite existing copy already in the archive." % (file))
+            self.rejects.append("%s: can not overwrite existing copy already in the archive." % filename)
 
     ################################################################################
 
-    def check_source_against_db(self, file, session):
+    def check_source_against_db(self, filename, session):
         """
         """
         source = self.pkg.dsc.get("source")
@@ -2330,10 +2328,10 @@ distribution."""
         q = q.join(DBSource).filter(DBSource.source==source)
 
         self.cross_suite_version_check([ (x.suite.suite_name, x.source.version) for x in q.all() ],
-                                       file, version, sourceful=True)
+                                       filename, version, sourceful=True)
 
     ################################################################################
-    def check_dsc_against_db(self, file, session):
+    def check_dsc_against_db(self, filename, session):
         """
 
         @warning: NB: this function can remove entries from the 'files' index [if
@@ -2459,15 +2457,15 @@ distribution."""
                             orig_files[dsc_name]["path"] = in_otherdir
 
                     if not found:
-                        self.rejects.append("%s refers to %s, but I can't find it in the queue or in the pool." % (file, dsc_name))
+                        self.rejects.append("%s refers to %s, but I can't find it in the queue or in the pool." % (filename, dsc_name))
                         continue
             else:
-                self.rejects.append("%s refers to %s, but I can't find it in the queue." % (file, dsc_name))
+                self.rejects.append("%s refers to %s, but I can't find it in the queue." % (filename, dsc_name))
                 continue
             if actual_md5 != dsc_entry["md5sum"]:
-                self.rejects.append("md5sum for %s doesn't match %s." % (found, file))
+                self.rejects.append("md5sum for %s doesn't match %s." % (found, filename))
             if actual_size != int(dsc_entry["size"]):
-                self.rejects.append("size for %s doesn't match %s." % (found, file))
+                self.rejects.append("size for %s doesn't match %s." % (found, filename))
 
     ################################################################################
     # This is used by process-new and process-holding to recheck a changes file
index 0b9fa8416ac33099f71ed828ebdd1f9913fa0208..6ec92f89ad7e03d60a2e793829333b3907128346 100755 (executable)
@@ -36,7 +36,6 @@ import stat
 import apt_pkg
 import time
 import re
-import string
 import email as modemail
 import subprocess
 
@@ -45,8 +44,7 @@ from dak_exceptions import *
 from textutils import fix_maintainer
 from regexes import re_html_escaping, html_escaping, re_single_line_field, \
                     re_multi_line_field, re_srchasver, re_taint_free, \
-                    re_gpg_uid, re_re_mark, re_whitespace_comment, re_issource, \
-                    re_is_orig_source
+                    re_gpg_uid, re_re_mark, re_whitespace_comment, re_issource
 
 from formats import parse_format, validate_changes_format
 from srcformats import get_format_from_string
@@ -64,9 +62,9 @@ key_uid_email_cache = {}  #: Cache for email addresses from gpg key uids
 known_hashes = [("sha1", apt_pkg.sha1sum, (1, 8)),
                 ("sha256", apt_pkg.sha256sum, (1, 8))] #: hashes we accept for entries in .changes/.dsc
 
-# Monkeypatch commands.getstatusoutput as it returns a "0" exit code in
-# all situations under lenny's Python.
-import commands
+# Monkeypatch commands.getstatusoutput as it may not return the correct exit
+# code in lenny's Python. This also affects commands.getoutput and
+# commands.getstatus.
 def dak_getstatusoutput(cmd):
     pipe = subprocess.Popen(cmd, shell=True, universal_newlines=True,
         stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
@@ -558,7 +556,7 @@ def build_file_list(changes, is_a_dsc=0, field="files", hashname="md5sum"):
 
         (section, component) = extract_component_from_section(section)
 
-        files[name] = Dict(size=size, section=section,
+        files[name] = dict(size=size, section=section,
                            priority=priority, component=component)
         files[name][hashname] = md5
 
@@ -616,7 +614,7 @@ def send_mail (message, filename=""):
                 if len(match) == 0:
                     del message_raw[field]
                 else:
-                    message_raw.replace_header(field, string.join(match, ", "))
+                    message_raw.replace_header(field, ', '.join(match))
 
         # Change message fields in order if we don't have a To header
         if not message_raw.has_key("To"):
@@ -757,12 +755,12 @@ def which_alias_file():
 
 ################################################################################
 
-def TemplateSubst(map, filename):
+def TemplateSubst(subst_map, filename):
     """ Perform a substition of template """
     templatefile = open_file(filename)
     template = templatefile.read()
-    for x in map.keys():
-        template = template.replace(x, str(map[x]))
+    for k, v in subst_map.iteritems():
+        template = template.replace(k, str(v))
     templatefile.close()
     return template
 
@@ -1095,10 +1093,6 @@ def split_args (s, dwim=1):
 
 ################################################################################
 
-def Dict(**dict): return dict
-
-########################################
-
 def gpgv_get_status_output(cmd, status_read, status_write):
     """
     Our very own version of commands.getouputstatus(), hacked to support
@@ -1366,7 +1360,7 @@ def check_signature (sig_filename, data_filename="", keyrings=None, autofetch=No
         rejects.append("signature on %s does not appear to be valid [No SIG_ID]." % (sig_filename))
 
     # Finally ensure there's not something we don't recognise
-    known_keywords = Dict(VALIDSIG="",SIG_ID="",GOODSIG="",BADSIG="",ERRSIG="",
+    known_keywords = dict(VALIDSIG="",SIG_ID="",GOODSIG="",BADSIG="",ERRSIG="",
                           SIGEXPIRED="",KEYREVOKED="",NO_PUBKEY="",BADARMOR="",
                           NODATA="",NOTATION_DATA="",NOTATION_NAME="",KEYEXPIRED="")
 
@@ -1488,7 +1482,7 @@ def is_email_alias(email):
 
 ################################################################################
 
-def get_changes_files(dir):
+def get_changes_files(from_dir):
     """
     Takes a directory and lists all .changes files in it (as well as chdir'ing
     to the directory; this is due to broken behaviour on the part of p-u/p-a
@@ -1498,10 +1492,10 @@ def get_changes_files(dir):
     """
     try:
         # Much of the rest of p-u/p-a depends on being in the right place
-        os.chdir(dir)
-        changes_files = [x for x in os.listdir(dir) if x.endswith('.changes')]
+        os.chdir(from_dir)
+        changes_files = [x for x in os.listdir(from_dir) if x.endswith('.changes')]
     except OSError, e:
-        fubar("Failed to read list from directory %s (%s)" % (dir, e))
+        fubar("Failed to read list from directory %s (%s)" % (from_dir, e))
 
     return changes_files