X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=katie.py;h=308806cc547354d88f56ebfc6dc486a8ed558770;hb=3686a00f1001f2d5692fa5e706b898053e39191a;hp=55e49e08f00e446c1a28c58f8e90cff65c61a538;hpb=84c957285454e91ea0544c2c317f7ed6e67542aa;p=dak.git diff --git a/katie.py b/katie.py index 55e49e08..308806cc 100644 --- a/katie.py +++ b/katie.py @@ -1,8 +1,8 @@ #!/usr/bin/env python # Utility functions for katie -# Copyright (C) 2001, 2002, 2003 James Troup -# $Id: katie.py,v 1.40 2003-09-17 23:36:17 troup Exp $ +# Copyright (C) 2001, 2002, 2003, 2004 James Troup +# $Id: katie.py,v 1.45 2004-04-01 17:14:25 troup Exp $ # 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 @@ -20,7 +20,7 @@ ############################################################################### -import cPickle, errno, os, pg, re, stat, string, sys, tempfile, time; +import cPickle, errno, os, pg, re, stat, string, sys, time; import utils, db_access; import apt_inst, apt_pkg; @@ -93,7 +93,6 @@ class Katie: def __init__(self, Cnf): self.Cnf = Cnf; - self.values = {}; # Read in the group-maint override file self.nmu = nmu_p(Cnf); self.accept_count = 0; @@ -118,6 +117,7 @@ class Katie: exec "self.pkg.%s.clear();" % (i); self.pkg.orig_tar_id = None; self.pkg.orig_tar_location = ""; + self.pkg.orig_tar_gz = None; ########################################################################### @@ -178,7 +178,8 @@ class Katie: if changes.has_key(i): d_changes[i] = changes[i]; ## dsc - for i in [ "source", "version", "maintainer", "fingerprint", "uploaders" ]: + for i in [ "source", "version", "maintainer", "fingerprint", "uploaders", + "bts changelog" ]: if dsc.has_key(i): d_dsc[i] = dsc[i]; ## dsc_files @@ -263,7 +264,7 @@ class Katie: if files[file]["type"] == "deb": summary += apt_pkg.ParseSection(apt_inst.debExtractControl(utils.open_file(file)))["Description"] + '\n'; else: - files[file]["pool name"] = utils.poolify (changes["source"], files[file]["component"]) + files[file]["pool name"] = utils.poolify (changes.get("source",""), files[file]["component"]) destination = self.Cnf["Dir::PoolRoot"] + files[file]["pool name"] + file summary += file + "\n to " + destination + "\n" @@ -383,14 +384,17 @@ distribution."""; Cnf = self.Cnf; Subst = self.Subst; files = self.pkg.files; + changes = self.pkg.changes; + changes_file = self.pkg.changes_file; + dsc = self.pkg.dsc; print "Accepting." - self.Logger.log(["Accepting changes",self.pkg.changes_file]); + self.Logger.log(["Accepting changes",changes_file]); self.dump_vars(Cnf["Dir::Queue::Accepted"]); # Move all the files into the accepted directory - utils.move(self.pkg.changes_file, Cnf["Dir::Queue::Accepted"]); + utils.move(changes_file, Cnf["Dir::Queue::Accepted"]); file_keys = files.keys(); for file in file_keys: utils.move(file, Cnf["Dir::Queue::Accepted"]); @@ -406,9 +410,45 @@ distribution."""; utils.send_mail(mail_message) self.announce(short_summary, 1) - # Special support to enable clean auto-building of accepted packages + + ## Helper stuff for DebBugs Version Tracking + if Cnf.Find("Dir::Queue::BTSVersionTrack"): + # ??? once queue/* is cleared on *.d.o and/or reprocessed + # the conditionalization on dsc["bts changelog"] should be + # dropped. + + # Write out the version history from the changelog + if changes["architecture"].has_key("source") and \ + dsc.has_key("bts changelog"): + + temp_filename = utils.temp_filename(Cnf["Dir::Queue::BTSVersionTrack"], + dotprefix=1, perms=0644); + version_history = utils.open_file(temp_filename, 'w'); + version_history.write(dsc["bts changelog"]); + version_history.close(); + filename = "%s/%s" % (Cnf["Dir::Queue::BTSVersionTrack"], + changes_file[:-8]+".versions"); + os.rename(temp_filename, filename); + + # Write out the binary -> source mapping. + temp_filename = utils.temp_filename(Cnf["Dir::Queue::BTSVersionTrack"], + dotprefix=1, perms=0644); + debinfo = utils.open_file(temp_filename, 'w'); + for file in file_keys: + f = files[file]; + if f["type"] == "deb": + line = " ".join([f["package"], f["version"], + f["architecture"], f["source package"], + f["source version"]]); + debinfo.write(line+"\n"); + debinfo.close(); + filename = "%s/%s" % (Cnf["Dir::Queue::BTSVersionTrack"], + changes_file[:-8]+".debinfo"); + os.rename(temp_filename, filename); + + ## Special support to enable clean auto-building of accepted packages self.projectB.query("BEGIN WORK"); - for suite in self.pkg.changes["distribution"].keys(): + for suite in changes["distribution"].keys(): if suite not in Cnf.ValueList("Dinstall::AcceptedAutoBuildSuites"): continue; suite_id = db_access.get_suite_id(suite); @@ -469,7 +509,9 @@ distribution."""; return; summary = ""; - for file in files.keys(): + file_keys = files.keys(); + file_keys.sort(); + for file in file_keys: if not files[file].has_key("new") and files[file]["type"] == "deb": section = files[file]["section"]; override_section = files[file]["override section"]; @@ -537,9 +579,7 @@ distribution."""; # If we weren't given a manual rejection message, spawn an # editor so the user can add one in... if manual and not reject_message: - temp_filename = tempfile.mktemp(); - fd = os.open(temp_filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0700); - os.close(fd); + temp_filename = utils.temp_filename(); editor = os.environ.get("EDITOR","vi") answer = 'E'; while answer == 'E': @@ -570,7 +610,7 @@ distribution."""; pkg = self.pkg; reason_filename = pkg.changes_file[:-8] + ".reason"; - reject_filename = Cnf["Dir::Queue::Reject"] + '/' + reason_filename; + reason_filename = Cnf["Dir::Queue::Reject"] + '/' + reason_filename; # Move all the files into the reject directory reject_files = pkg.files.keys() + [pkg.changes_file]; @@ -578,16 +618,15 @@ distribution."""; # If we fail here someone is probably trying to exploit the race # so let's just raise an exception ... - if os.path.exists(reject_filename): - os.unlink(reject_filename); - fd = os.open(reject_filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0644); + if os.path.exists(reason_filename): + os.unlink(reason_filename); + reason_file = os.open(reason_filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0644); if not manual: Subst["__REJECTOR_ADDRESS__"] = Cnf["Dinstall::MyEmailAddress"]; Subst["__MANUAL_REJECT_MESSAGE__"] = ""; Subst["__CC__"] = "X-Katie-Rejection: automatic (moo)"; - os.write(fd, reject_message); - os.close(fd); + os.write(reason_file, reject_message); reject_mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/katie.rejected"); else: # Build up the rejection email @@ -597,10 +636,10 @@ distribution."""; Subst["__MANUAL_REJECT_MESSAGE__"] = reject_message; Subst["__CC__"] = "Cc: " + Cnf["Dinstall::MyEmailAddress"]; reject_mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/katie.rejected"); - # Write the rejection email out as the .reason file - os.write(fd, reject_mail_message); - os.close(fd); + os.write(reason_file, reject_mail_message); + + os.close(reason_file); # Send the rejection mail if appropriate if not Cnf["Dinstall::Options::No-Mail"]: @@ -631,13 +670,13 @@ distribution."""; maps = self.Cnf.ValueList("SuiteMappings")[:] maps.reverse() maps = [ m.split() for m in maps ] - maps = [ (x[1], x[2]) for x in maps + maps = [ (x[1], x[2]) for x in maps if x[0] == "map" or x[0] == "silent-map" ] s = [suite] for x in maps: if x[1] in s and x[0] not in s: s.append(x[0]) - + que = "SELECT s.version FROM source s JOIN src_associations sa ON (s.id = sa.source) JOIN suite su ON (sa.suite = su.id) WHERE s.source = '%s' AND (%s)" % (package, string.join(["su.suite_name = '%s'" % a for a in s], " OR ")); q = self.projectB.query(que) @@ -645,17 +684,17 @@ distribution."""; ql = map(lambda x: x[0], q.getresult()); # Try (1) - if ql.count(source_version): + if source_version in ql: continue # Try (2) orig_source_version = re_bin_only_nmu_of_mu.sub('', source_version) - if ql.count(orig_source_version): + if orig_source_version in ql: continue # Try (3) orig_source_version = re_bin_only_nmu_of_nmu.sub('', source_version) - if ql.count(orig_source_version): + if orig_source_version in ql: continue # No source found... @@ -797,7 +836,7 @@ SELECT s.version, su.suite_name FROM source s, src_associations sa, suite su files = self.pkg.files; dsc_files = self.pkg.dsc_files; legacy_source_untouchable = self.pkg.legacy_source_untouchable; - orig_tar_gz = None; + self.pkg.orig_tar_gz = None; # Try and find all files mentioned in the .dsc. This has # to work harder to cope with the multiple possible @@ -815,7 +854,6 @@ SELECT s.version, su.suite_name FROM source s, src_associations sa, suite su # Strip out anything that isn't '%s' or '/%s$' for i in ql: if i[2] != dsc_file and i[2][-(len(dsc_file)+1):] != '/'+dsc_file: - self.Logger.log(["check_dsc_against_db",i[2],dsc_file]); ql.remove(i); # "[katie] has not broken them. [katie] has fixed a @@ -848,14 +886,12 @@ SELECT s.version, su.suite_name FROM source s, src_associations sa, suite su # Strip out anything that isn't '%s' or '/%s$' for i in ql: if i[1] != dsc_file and i[1][-(len(dsc_file)+1):] != '/'+dsc_file: - self.Logger.log(["check_dsc_against_db",i[1],dsc_file]); ql.remove(i); if ql: - # Unfortunately, we make get more than one - # match here if, for example, the package was - # in potato but had a -sa upload in woody. So - # we need to choose the right one. + # Unfortunately, we may get more than one match here if, + # for example, the package was in potato but had an -sa + # upload in woody. So we need to choose the right one. x = ql[0]; # default to something sane in case we don't match any or have only one @@ -877,6 +913,7 @@ SELECT s.version, su.suite_name FROM source s, src_associations sa, suite su dsc_files[dsc_file]["files id"] = x[3]; # need this for updating dsc_files in install() # See install() in katie... self.pkg.orig_tar_id = x[3]; + self.pkg.orig_tar_gz = old_file; if suite_type == "legacy" or suite_type == "legacy-mixed": self.pkg.orig_tar_location = "legacy"; else: @@ -895,9 +932,11 @@ SELECT s.version, su.suite_name FROM source s, src_associations sa, suite su actual_md5 = apt_pkg.md5sum(utils.open_file(in_otherdir)); actual_size = os.stat(in_otherdir)[stat.ST_SIZE]; found = in_otherdir; + self.pkg.orig_tar_gz = in_otherdir; if not found: self.reject("%s refers to %s, but I can't find it in the queue or in the pool." % (file, dsc_file)); + self.pkg.orig_tar_gz = -1; continue; else: self.reject("%s refers to %s, but I can't find it in the queue." % (file, dsc_file)); @@ -907,7 +946,7 @@ SELECT s.version, su.suite_name FROM source s, src_associations sa, suite su if actual_size != int(dsc_files[dsc_file]["size"]): self.reject("size for %s doesn't match %s." % (found, file)); - return (self.reject_message, orig_tar_gz); + return (self.reject_message, None); def do_query(self, q): sys.stderr.write("query: \"%s\" ... " % (q));