]> git.donarmstrong.com Git - dak.git/commitdiff
Merge commit 'ftpmaster/master' into suitesql
authorMark Hymers <mhy@debian.org>
Fri, 30 Oct 2009 13:51:45 +0000 (13:51 +0000)
committerMark Hymers <mhy@debian.org>
Fri, 30 Oct 2009 13:51:45 +0000 (13:51 +0000)
dak/add_user.py
dak/check_archive.py
dak/contents.py
dak/cruft_report.py
dak/generate_releases.py
dak/import_known_changes.py
dak/make_suite_file_list.py
dak/show_deferred.py
daklib/changes.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 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))
 
 #######################################################################################
 
index dcd3a3350e29867d2361459647b0b903e0489349..3702411d3cbe9908ad034c8fbae3493177241099 100755 (executable)
@@ -66,6 +66,8 @@ OPTIONS
     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",
@@ -127,10 +129,17 @@ class OneAtATime(object):
     def __init__(self):
         self.next_in_line = None
         self.next_lock = threading.Condition()
+        self.die = False
+
+    def plsDie(self):
+        self.die = True
+        self.next_lock.notify()
 
     def enqueue(self, next):
         self.next_lock.acquire()
         while self.next_in_line:
+            if self.die:
+                return
             self.next_lock.wait()
 
         assert( not self.next_in_line )
@@ -141,15 +150,19 @@ class OneAtATime(object):
     def dequeue(self):
         self.next_lock.acquire()
         while not self.next_in_line:
+            if self.die:
+                return
             self.next_lock.wait()
-        result = self.next_in_line
 
-        if isinstance(result, EndOfChanges):
-            return None
+        result = self.next_in_line
 
         self.next_in_line = None
         self.next_lock.notify()
         self.next_lock.release()
+
+        if isinstance(result, EndOfChanges):
+            return None
+
         return result
 
 class ChangesToImport(object):
@@ -164,10 +177,15 @@ class ChangesToImport(object):
 
 class ChangesGenerator(threading.Thread):
     """enqueues changes files to be imported"""
-    def __init__(self, queue):
+    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()
@@ -181,28 +199,42 @@ class ChangesGenerator(threading.Thread):
                     if not filenames:
                         # Empty directory (or only subdirectories), next
                         continue
-                    for changesfile in filenames:
-                        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)
-                            print("enqueue: %s" % to_import)
-                            self.queue.enqueue(to_import)
+                    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, queue):
+    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
@@ -212,7 +244,6 @@ class ImportThread(threading.Thread):
                 changes = Changes()
                 changes.changes_file = to_import.changesfile
                 changesfile = os.path.join(to_import.dirpath, to_import.changesfile)
-                print( "STU: %s / %s" % (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)
@@ -220,17 +251,47 @@ class ImportThread(threading.Thread):
 
             except InvalidDscError, line:
                 warn("syntax error in .dsc file '%s', line %s." % (f, line))
-#                failure += 1
 
             except ChangesUnicodeError:
                 warn("found invalid changes file, not properly utf-8 encoded")
-#                failure += 1
-
-                print "Directory %s, file %7d, failures %3d. (%s)" % (dirpath[-10:], count, failure, changesfile)
 
 
+            except KeyboardInterrupt:
+                print("Caught C-c; on ImportThread. terminating.")
+                self.parent.plsDie()
+                sys.exit(1)
             except:
                 traceback.print_exc()
+                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()
@@ -266,12 +327,9 @@ def main():
     if Config().has_key( "%s::%s" %(options_prefix,"Concurrency")):
         num_threads = int(Config()[ "%s::%s" %(options_prefix,"Concurrency")])
 
+    ImportKnownChanges(num_threads)
 
-    queue = OneAtATime()
-    ChangesGenerator(queue).start()
 
-    for i in range(num_threads):
-        ImportThread(queue).start()
 
 
 if __name__ == '__main__':
index 3c690a510960b42da5e9d8a36a4d9952bc7c5a84..d3b679ed5aebbe5364a15c8cf85961bd15a71d2e 100755 (executable)
@@ -309,6 +309,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"]:
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 2413bf4c5da4a251ca6ba7e7e85f6c58d71c16be..3eb842d2269e7f0385eccec53da56bc07ade30ae 100755 (executable)
@@ -192,7 +192,7 @@ class Changes(object):
 
     def mark_missing_fields(self):
         """add "missing" in fields which we will require for the known_changes table"""
-        for key in ['urgency', 'maintainer', 'fingerprint', 'changedby' ]:
+        for key in ['urgency', 'maintainer', 'fingerprint', 'changed-by' ]:
             if (not self.changes.has_key(key)) or (not self.changes[key]):
                 self.changes[key]='missing'
 
@@ -215,7 +215,7 @@ class Changes(object):
               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"],