]> git.decadent.org.uk Git - dak.git/commitdiff
Merge branch 'master' into gps
authorJoerg Jaspert <joerg@debian.org>
Tue, 6 Jul 2010 22:17:22 +0000 (00:17 +0200)
committerJoerg Jaspert <joerg@debian.org>
Tue, 6 Jul 2010 22:17:22 +0000 (00:17 +0200)
* master:
  examine-package: lock access to printed_copyrights
  show-new: multithreading support
  show-new: no longer fiddle with sys.stdout
  examine_package: make most functions functional
  examine-package: really support option -H
  examine-package: add missing newlines to output
  examine-package: make foldable_output functional()
  examine-package: make headline() functional
  call check_deb() with correct arguments
  Add config for volatile

config/debian/dak.conf
dak/examine_package.py
dak/process_new.py
dak/show_new.py

index 243df1ccc247321bdbd189927b9b86d63183ba3c..1411f62a2e6f302e2f72b56bb6b93be8bd3c9171 100644 (file)
@@ -268,6 +268,67 @@ Suite
        };
   };
 
+  Lenny-Volatile
+  {
+       Components
+       {
+         main;
+         contrib;
+         non-free;
+       };
+       Announce "debian-changes@lists.debian.org";
+       Origin "Debian";
+       Description "Volatile Packages for Debian 5.0";
+       CodeName "lenny-volatile";
+       OverrideCodeName "lenny";
+       OverrideSuite "stable";
+       ValidTime 604800; // 7 days
+       NotAutomatic "yes";
+       Priority "0";
+       VersionChecks
+       {
+         MustBeNewerThan
+         {
+           Stable;
+         };
+         Enhances
+      {
+           Stable;
+         };
+       };
+
+  };
+
+  Lenny-Volatile-Proposed-Updates
+  {
+       Components
+       {
+         main;
+         contrib;
+         non-free;
+       };
+       Announce "debian-changes@lists.debian.org";
+       Origin "Debian";
+       Description "Proposed Volatile Packages for Debian 5.0";
+       CodeName "lenny-volatile-proposed-updates";
+       OverrideCodeName "lenny";
+       OverrideSuite "stable";
+       ValidTime 604800; // 7 days
+       NotAutomatic "yes";
+       Priority "0";
+       VersionChecks
+       {
+         MustBeNewerThan
+         {
+           Stable;
+         };
+         Enhances
+      {
+           Stable;
+         };
+       };
+  };
+
   Testing
   {
        Components
@@ -332,6 +393,69 @@ Suite
        };
   };
 
+  Squeeze-Volatile
+  {
+       Components
+       {
+         main;
+         contrib;
+         non-free;
+       };
+       Announce "debian-testing-changes@lists.debian.org";
+       Origin "Debian";
+       Description "Volatile Packages for Debian x.y (testing)";
+       CodeName "squeeze-volatile";
+       OverrideCodeName "squeeze";
+       OverrideSuite "testing";
+       ValidTime 604800; // 7 days
+       NotAutomatic "yes";
+       Priority "0";
+       VersionChecks
+       {
+         MustBeNewerThan
+         {
+           Stable;
+           Testing;
+         };
+         Enhances
+      {
+           Testing;
+         };
+       };
+
+  };
+
+  Squeeze-Volatile-Proposed-Updates
+  {
+       Components
+       {
+         main;
+         contrib;
+         non-free;
+       };
+       Announce "debian-testing-changes@lists.debian.org";
+       Origin "Debian";
+       Description "Proposed Volatile Packages for Debian x.y (testing)";
+       CodeName "squeeze-volatile-proposed-updates";
+       OverrideCodeName "squeeze";
+       OverrideSuite "testing";
+       ValidTime 604800; // 7 days
+       NotAutomatic "yes";
+       Priority "0";
+       VersionChecks
+       {
+         MustBeNewerThan
+         {
+           Stable;
+           Testing;
+         };
+         Enhances
+      {
+           Testing;
+         };
+       };
+  };
+
   Unstable
   {
        Components
@@ -409,7 +533,9 @@ SuiteMappings
  "propup-version stable-security testing testing-proposed-updates unstable";
  "propup-version testing-security unstable";
  "map lenny stable";
+ "map lenny-volatile lenny-volatile-proposed-updates";
  "map squeeze testing";
+ "map squeeze-volatile squeeze-volatile-proposed-updates";
  "map sid unstable";
  "map rc-buggy experimental";
 // "map oldstable oldstable-proposed-updates";
@@ -469,6 +595,9 @@ Dir
     Byhand "/srv/ftp-master.debian.org/queue/byhand/";
     ProposedUpdates "/srv/ftp-master.debian.org/queue/p-u-new/";
     OldProposedUpdates "/srv/ftp-master.debian.org/queue/o-p-u-new/";
+    ProposedUpdates "/srv/ftp-master.debian.org/queue/p-u-new/";
+    Lenny-Volatile-Proposed-Updates "/srv/ftp-master.debian.org/queue/volatile/lenny-volatile-p-u-new";
+    Squeeze-Volatile-Proposed-Updates "/srv/ftp-master.debian.org/queue/volatile/squeeze-volatile-p-u-new";
     Done "/srv/ftp-master.debian.org/queue/done/";
     Holding "/srv/ftp-master.debian.org/queue/holding/";
     New "/srv/ftp-master.debian.org/queue/new/";
index 2961111450a275a27f76c6042b62a88ff7abefcc..6a3c8046fdd6293a1dcf5c268ced4818df5116fe 100755 (executable)
@@ -3,6 +3,10 @@
 """
 Script to automate some parts of checking NEW packages
 
+Most functions are written in a functional programming style. They
+return a string avoiding the side effect of directly printing the string
+to stdout. Those functions can be used in multithreaded parts of dak.
+
 @contact: Debian FTP Master <ftpmaster@debian.org>
 @copyright: 2000, 2001, 2002, 2003, 2006  James Troup <james@nocrew.org>
 @copyright: 2009  Joerg Jaspert <joerg@debian.org>
@@ -47,6 +51,7 @@ import apt_pkg
 import apt_inst
 import shutil
 import commands
+import threading
 
 from daklib import utils
 from daklib.dbconn import DBConn, get_binary_from_name_suite
@@ -59,6 +64,7 @@ from daklib.regexes import html_escaping, re_html_escaping, re_version, re_space
 Cnf = None
 Cnf = utils.get_conf()
 
+changes_lock = threading.Lock()
 printed_copyrights = {}
 package_relations = {}           #: Store relations of packages for later output
 
@@ -91,13 +97,13 @@ def escape_if_needed(s):
 def headline(s, level=2, bodyelement=None):
     if use_html:
         if bodyelement:
-            print """<thead>
+            return """<thead>
                 <tr><th colspan="2" class="title" onclick="toggle('%(bodyelement)s', 'table-row-group', 'table-row-group')">%(title)s <span class="toggle-msg">(click to toggle)</span></th></tr>
-              </thead>"""%{"bodyelement":bodyelement,"title":utils.html_escape(s)}
+              </thead>\n"""%{"bodyelement":bodyelement,"title":utils.html_escape(s)}
         else:
-            print "<h%d>%s</h%d>" % (level, utils.html_escape(s), level)
+            return "<h%d>%s</h%d>\n" % (level, utils.html_escape(s), level)
     else:
-        print "---- %s ----" % (s)
+        return "---- %s ----\n" % (s)
 
 # Colour definitions, 'end' isn't really for use
 
@@ -154,18 +160,20 @@ def format_field(k,v):
 
 def foldable_output(title, elementnameprefix, content, norow=False):
     d = {'elementnameprefix':elementnameprefix}
+    result = ''
     if use_html:
-        print """<div id="%(elementnameprefix)s-wrap"><a name="%(elementnameprefix)s" />
-                   <table class="infobox rfc822">"""%d
-    headline(title, bodyelement="%(elementnameprefix)s-body"%d)
+        result += """<div id="%(elementnameprefix)s-wrap"><a name="%(elementnameprefix)s" />
+                   <table class="infobox rfc822">\n"""%d
+    result += headline(title, bodyelement="%(elementnameprefix)s-body"%d)
     if use_html:
-        print """    <tbody id="%(elementnameprefix)s-body" class="infobody">"""%d
+        result += """    <tbody id="%(elementnameprefix)s-body" class="infobody">\n"""%d
     if norow:
-        print content
+        result += content + "\n"
     else:
-        print output_row(content)
+        result += output_row(content) + "\n"
     if use_html:
-        print """</tbody></table></div>"""
+        result += """</tbody></table></div>"""
+    return result
 
 ################################################################################
 
@@ -360,7 +368,7 @@ def output_package_relations ():
             to_print += "%-15s: (%s) %s\n" % (package, relation, package_relations[package][relation])
 
     package_relations.clear()
-    foldable_output("Package relations", "relations", to_print)
+    return foldable_output("Package relations", "relations", to_print)
 
 def output_deb_info(suite, filename, packagename):
     (control, control_keys, section, depends, recommends, arch, maintainer) = read_control(filename)
@@ -409,6 +417,8 @@ def do_lintian (filename):
         return do_command("lintian --show-overrides --color always", filename, 1)
 
 def get_copyright (deb_filename):
+    global changes_lock, printed_copyrights
+
     package = re_package.sub(r'\1', deb_filename)
     o = os.popen("dpkg-deb -c %s | egrep 'usr(/share)?/doc/[^/]*/copyright' | awk '{print $6}' | head -n 1" % (deb_filename))
     cright = o.read()[:-1]
@@ -425,11 +435,13 @@ def get_copyright (deb_filename):
     copyrightmd5 = md5.md5(cright).hexdigest()
 
     res = ""
+    changes_lock.acquire()
     if printed_copyrights.has_key(copyrightmd5) and printed_copyrights[copyrightmd5] != "%s (%s)" % (package, deb_filename):
         res += formatted_text( "NOTE: Copyright is the same as %s.\n\n" % \
                                (printed_copyrights[copyrightmd5]))
     else:
         printed_copyrights[copyrightmd5] = "%s (%s)" % (package, deb_filename)
+    changes_lock.release()
     return res+formatted_text(cright)
 
 def get_readme_source (dsc_filename):
@@ -462,9 +474,13 @@ def get_readme_source (dsc_filename):
 
 def check_dsc (suite, dsc_filename):
     (dsc) = read_changes_or_dsc(suite, dsc_filename)
-    foldable_output(dsc_filename, "dsc", dsc, norow=True)
-    foldable_output("lintian check for %s" % dsc_filename, "source-lintian", do_lintian(dsc_filename))
-    foldable_output("README.source for %s" % dsc_filename, "source-readmesource", get_readme_source(dsc_filename))
+    return foldable_output(dsc_filename, "dsc", dsc, norow=True) + \
+           "\n" + \
+           foldable_output("lintian check for %s" % dsc_filename,
+              "source-lintian", do_lintian(dsc_filename)) + \
+           "\n" + \
+           foldable_output("README.source for %s" % dsc_filename,
+               "source-readmesource", get_readme_source(dsc_filename))
 
 def check_deb (suite, deb_filename):
     filename = os.path.basename(deb_filename)
@@ -475,29 +491,30 @@ def check_deb (suite, deb_filename):
     else:
         is_a_udeb = 0
 
-
-    foldable_output("control file for %s" % (filename), "binary-%s-control"%packagename,
-                    output_deb_info(suite, deb_filename, packagename), norow=True)
+    result = foldable_output("control file for %s" % (filename), "binary-%s-control"%packagename,
+        output_deb_info(suite, deb_filename, packagename), norow=True) + "\n"
 
     if is_a_udeb:
-        foldable_output("skipping lintian check for udeb", "binary-%s-lintian"%packagename,
-                        "")
+        result += foldable_output("skipping lintian check for udeb",
+           "binary-%s-lintian"%packagename, "") + "\n"
     else:
-        foldable_output("lintian check for %s" % (filename), "binary-%s-lintian"%packagename,
-                        do_lintian(deb_filename))
+        result += foldable_output("lintian check for %s" % (filename),
+           "binary-%s-lintian"%packagename, do_lintian(deb_filename)) + "\n"
 
-    foldable_output("contents of %s" % (filename), "binary-%s-contents"%packagename,
-                    do_command("dpkg -c", deb_filename))
+    result += foldable_output("contents of %s" % (filename), "binary-%s-contents"%packagename,
+        do_command("dpkg -c", deb_filename)) + "\n"
 
     if is_a_udeb:
-        foldable_output("skipping copyright for udeb", "binary-%s-copyright"%packagename,
-                        "")
+        result += foldable_output("skipping copyright for udeb",
+           "binary-%s-copyright"%packagename, "") + "\n"
     else:
-        foldable_output("copyright of %s" % (filename), "binary-%s-copyright"%packagename,
-                        get_copyright(deb_filename))
+        result += foldable_output("copyright of %s" % (filename),
+           "binary-%s-copyright"%packagename, get_copyright(deb_filename)) + "\n"
 
-    foldable_output("file listing of %s" % (filename),  "binary-%s-file-listing"%packagename,
-                    do_command("ls -l", deb_filename))
+    result += foldable_output("file listing of %s" % (filename),
+       "binary-%s-file-listing"%packagename, do_command("ls -l", deb_filename))
+
+    return result
 
 # Read a file, strip the signature and return the modified contents as
 # a string.
@@ -528,22 +545,26 @@ def strip_pgp_signature (filename):
     return contents
 
 def display_changes(suite, changes_filename):
+    global changes_lock, printed_copyrights
     changes = read_changes_or_dsc(suite, changes_filename)
-    foldable_output(changes_filename, "changes", changes, norow=True)
+    changes_lock.acquire()
+    printed_copyrights = {}
+    changes_lock.release()
+    return foldable_output(changes_filename, "changes", changes, norow=True)
 
 def check_changes (changes_filename):
     try:
         changes = utils.parse_changes (changes_filename)
     except ChangesUnicodeError:
         utils.warn("Encoding problem with changes file %s" % (changes_filename))
-    display_changes(changes['distribution'], changes_filename)
+    print display_changes(changes['distribution'], changes_filename)
 
     files = utils.build_file_list(changes)
     for f in files.keys():
         if f.endswith(".deb") or f.endswith(".udeb"):
-            check_deb(changes['distribution'], f)
+            print check_deb(changes['distribution'], f)
         if f.endswith(".dsc"):
-            check_dsc(changes['distribution'], f)
+            print check_dsc(changes['distribution'], f)
         # else: => byhand
 
 def main ():
@@ -564,6 +585,10 @@ def main ():
     if Options["Help"]:
         usage()
 
+    if Options["Html-Output"]:
+        global use_html
+        use_html = 1
+
     stdout_fd = sys.stdout
 
     for f in args:
@@ -579,13 +604,13 @@ def main ():
                 elif f.endswith(".deb") or f.endswith(".udeb"):
                     # default to unstable when we don't have a .changes file
                     # perhaps this should be a command line option?
-                    check_deb('unstable', file)
+                    print check_deb('unstable', f)
                 elif f.endswith(".dsc"):
-                    check_dsc('unstable', f)
+                    print check_dsc('unstable', f)
                 else:
                     utils.fubar("Unrecognised file type: '%s'." % (f))
             finally:
-                output_package_relations()
+                print output_package_relations()
                 if not Options["Html-Output"]:
                     # Reset stdout here so future less invocations aren't FUBAR
                     less_fd.close()
index 74bae8fe4cef50f98e52c5bf39837c5664a4d0bb..fc952d2a346d86ba60dc963e35aacb7c0f4c15d0 100755 (executable)
@@ -380,17 +380,17 @@ def check_pkg (upload):
         try:
             sys.stdout = less_fd
             changes = utils.parse_changes (upload.pkg.changes_file)
-            examine_package.display_changes(changes['distribution'], upload.pkg.changes_file)
+            print examine_package.display_changes(changes['distribution'], upload.pkg.changes_file)
             files = upload.pkg.files
             for f in files.keys():
                 if files[f].has_key("new"):
                     ftype = files[f]["type"]
                     if ftype == "deb":
-                        examine_package.check_deb(changes['distribution'], f)
+                        print examine_package.check_deb(changes['distribution'], f)
                     elif ftype == "dsc":
-                        examine_package.check_dsc(changes['distribution'], f)
+                        print examine_package.check_dsc(changes['distribution'], f)
         finally:
-            examine_package.output_package_relations()
+            print examine_package.output_package_relations()
             sys.stdout = stdout_fd
     except IOError, e:
         if e.errno == errno.EPIPE:
index 9e216c5e2033f1b59f4c14b3dc249b2a493527a7..9cb0890199d7210a985f6eee946c9d3d7f3288b7 100755 (executable)
@@ -37,6 +37,7 @@ from daklib.regexes import re_source_ext
 from daklib.config import Config
 from daklib import daklog
 from daklib.changesutils import *
+from daklib.threadpool import ThreadPool
 
 # Globals
 Cnf = None
@@ -51,7 +52,7 @@ sources = set()
 def html_header(name, filestoexamine):
     if name.endswith('.changes'):
         name = ' '.join(name.split('_')[:2])
-    print """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+    result = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
   <head>
     <meta http-equiv="content-type" content="text/xhtml+xml; charset=utf-8"
@@ -105,31 +106,36 @@ def html_header(name, filestoexamine):
         Debian NEW package overview for %(name)s
       </span>
     </div>
+
     """%{"name":name}
 
     # we assume only one source (.dsc) per changes here
-    print """
+    result += """
     <div id="menu">
       <p class="title">Navigation</p>
       <p><a href="#changes" onclick="show('changes-body')">.changes</a></p>
       <p><a href="#dsc" onclick="show('dsc-body')">.dsc</a></p>
       <p><a href="#source-lintian" onclick="show('source-lintian-body')">source lintian</a></p>
-      """
+
+"""
     for fn in filter(lambda x: x.endswith('.deb') or x.endswith('.udeb'),filestoexamine):
         packagename = fn.split('_')[0]
-        print """
+        result += """
         <p class="subtitle">%(pkg)s</p>
         <p><a href="#binary-%(pkg)s-control" onclick="show('binary-%(pkg)s-control-body')">control file</a></p>
         <p><a href="#binary-%(pkg)s-lintian" onclick="show('binary-%(pkg)s-lintian-body')">binary lintian</a></p>
         <p><a href="#binary-%(pkg)s-contents" onclick="show('binary-%(pkg)s-contents-body')">.deb contents</a></p>
         <p><a href="#binary-%(pkg)s-copyright" onclick="show('binary-%(pkg)s-copyright-body')">copyright</a></p>
         <p><a href="#binary-%(pkg)s-file-listing" onclick="show('binary-%(pkg)s-file-listing-body')">file listing</a></p>
-        """%{"pkg":packagename}
-    print "    </div>"
+
+"""%{"pkg":packagename}
+    result += "    </div>"
+    return result
 
 def html_footer():
-    print """    <p class="validate">Timestamp: %s (UTC)</p>"""% (time.strftime("%d.%m.%Y / %H:%M:%S", time.gmtime()))
-    print """    <p><a href="http://validator.w3.org/check?uri=referer">
+    result = """    <p class="validate">Timestamp: %s (UTC)</p>
+"""% (time.strftime("%d.%m.%Y / %H:%M:%S", time.gmtime()))
+    result += """    <p><a href="http://validator.w3.org/check?uri=referer">
       <img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"
       style="border: none; height: 31px; width: 88px" /></a>
     <a href="http://jigsaw.w3.org/css-validator/check/referer">
@@ -139,7 +145,8 @@ def html_footer():
   </body>
 </html>
 """
-#"""
+    return result
+
 ################################################################################
 
 
@@ -167,34 +174,29 @@ def do_pkg(changes_file):
 
     new = determine_new(u.pkg.changes, files, 0)
 
-    stdout_fd = sys.stdout
-
     htmlname = changes["source"] + "_" + changes["version"] + ".html"
     sources.add(htmlname)
     # do not generate html output if that source/version already has one.
     if not os.path.exists(os.path.join(cnf["Show-New::HTMLPath"],htmlname)):
-        sys.stdout = open(os.path.join(cnf["Show-New::HTMLPath"],htmlname),"w")
+        outfile = open(os.path.join(cnf["Show-New::HTMLPath"],htmlname),"w")
 
         filestoexamine = []
         for pkg in new.keys():
             for fn in new[pkg]["files"]:
                 filestoexamine.append(fn)
 
-        html_header(changes["source"], filestoexamine)
+        print >> outfile, html_header(changes["source"], filestoexamine)
 
         check_valid(new)
         distribution = changes["distribution"].keys()[0]
-        examine_package.display_changes(distribution, changes_file)
+        print >> outfile, examine_package.display_changes(distribution, changes_file)
 
         for fn in filter(lambda fn: fn.endswith(".dsc"), filestoexamine):
-            examine_package.check_dsc(distribution, fn)
+            print >> outfile, examine_package.check_dsc(distribution, fn)
         for fn in filter(lambda fn: fn.endswith(".deb") or fn.endswith(".udeb"), filestoexamine):
-            examine_package.check_deb(distribution, fn)
+            print >> outfile, examine_package.check_deb(distribution, fn)
 
-        html_footer()
-        if sys.stdout != stdout_fd:
-            sys.stdout.close()
-            sys.stdout = stdout_fd
+        print >> outfile, html_footer()
     session.close()
 
 ################################################################################
@@ -242,12 +244,14 @@ def main():
 
     examine_package.use_html=1
 
+    threadpool = ThreadPool()
     for changes_file in changes_files:
         changes_file = utils.validate_changes_file_arg(changes_file, 0)
         if not changes_file:
             continue
         print "\n" + changes_file
-        do_pkg (changes_file)
+        threadpool.queueTask(do_pkg, changes_file)
+    threadpool.joinAll()
 
     files = set(os.listdir(cnf["Show-New::HTMLPath"]))
     to_delete = filter(lambda x: x.endswith(".html"), files.difference(sources))