X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=dak%2Frm.py;h=66dab6113ccebdd2f6d748caa4fc405aecf5fc23;hb=cac810b4aeb8fa34c8ccaa7dc35b081efddc606b;hp=d7697fa426a0bd510aeb47d1921aa90fa33bb10c;hpb=30b9b0dcdc57dd0cfb9df267c86f04e548e25242;p=dak.git diff --git a/dak/rm.py b/dak/rm.py index d7697fa4..66dab611 100755 --- a/dak/rm.py +++ b/dak/rm.py @@ -2,6 +2,7 @@ """ General purpose package removal tool for ftpmaster """ # Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006 James Troup +# Copyright (C) 2010 Alexander Reichle-Schmehl # 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 @@ -44,12 +45,14 @@ import os import sys import apt_pkg import apt_inst +from re import sub from daklib.config import Config from daklib.dbconn import * from daklib import utils from daklib.dak_exceptions import * from daklib.regexes import re_strip_source_version, re_build_dep_arch +import debianbts as bts ################################################################################ @@ -66,6 +69,7 @@ Remove PACKAGE(s) from suite(s). -c, --component=COMPONENT act on this component -C, --carbon-copy=EMAIL send a CC of removal message to EMAIL -d, --done=BUG# send removal message as closure to bug# + -D, --do-close also close all bugs associated to that package -h, --help show this help and exit -m, --reason=MSG reason for removal -n, --no-action don't do anything @@ -118,6 +122,12 @@ def reverse_depends_check(removals, suites, arches=None): (result, output) = commands.getstatusoutput("gunzip -c %s > %s" % (filename, temp_filename)) if (result != 0): utils.fubar("Gunzip invocation failed!\n%s\n" % (output), result) + # Also check for udebs + filename = "%s/dists/%s/%s/debian-installer/binary-%s/Packages.gz" % (cnf["Dir::Root"], suites[0], component, architecture) + if os.path.exists(filename): + (result, output) = commands.getstatusoutput("gunzip -c %s >> %s" % (filename, temp_filename)) + if (result != 0): + utils.fubar("Gunzip invocation failed!\n%s\n" % (output), result) packages = utils.open_file(temp_filename) Packages = apt_pkg.ParseTagFile(packages) while Packages.Step(): @@ -262,6 +272,7 @@ def main (): ('c',"component", "Rm::Options::Component", "HasArg"), ('C',"carbon-copy", "Rm::Options::Carbon-Copy", "HasArg"), # Bugs to Cc ('d',"done","Rm::Options::Done", "HasArg"), # Bugs fixed + ('D',"do-close","Rm::Options::Do-Close"), ('R',"rdep-check", "Rm::Options::Rdep-Check"), ('m',"reason", "Rm::Options::Reason", "HasArg"), # Hysterical raisins; -m is old-dinstall option for rejection reason ('n',"no-action","Rm::Options::No-Action"), @@ -272,7 +283,7 @@ def main (): for i in [ "architecture", "binary-only", "carbon-copy", "component", "done", "help", "no-action", "partial", "rdep-check", "reason", - "source-only" ]: + "source-only", "Do-Close" ]: if not cnf.has_key("Rm::Options::%s" % (i)): cnf["Rm::Options::%s" % (i)] = "" if not cnf.has_key("Rm::Options::Suite"): @@ -298,6 +309,14 @@ def main (): if Options["Architecture"] and not Options["Partial"]: utils.warn("-a/--architecture implies -p/--partial.") Options["Partial"] = "true" + if Options["Do-Close"] and not Options["Done"]: + utils.fubar("No.") + if Options["Do-Close"] and Options["Binary-Only"]: + utils.fubar("No.") + if Options["Do-Close"] and Options["Source-Only"]: + utils.fubar("No.") + if Options["Do-Close"] and Options["Suite"] != 'unstable': + utils.fubar("No.") # Force the admin to tell someone if we're not doing a 'dak # cruft-report' inspired removal (or closing a bug, which counts @@ -460,6 +479,7 @@ def main (): summary = "" removals = d.keys() removals.sort() + versions = [] for package in removals: versions = d[package].keys() versions.sort(apt_pkg.VersionCompare) @@ -503,7 +523,38 @@ def main (): logfile.write("Closed bugs: %s\n" % (Options["Done"])) logfile.write("\n------------------- Reason -------------------\n%s\n" % (Options["Reason"])) logfile.write("----------------------------------------------\n") - logfile.flush() + logfile.write("=========================================================================\n") + logfile.close() + + # Do the same in rfc822 format + logfile822 = utils.open_file(cnf["Rm::LogFile822"], 'a') + logfile822.write("Date: %s\n" % date) + logfile822.write("Ftpmaster: %s\n" % whoami) + logfile822.write("Suite: %s\n" % suites_list) + sources = [] + binaries = [] + for package in summary.split("\n"): + for row in package.split("\n"): + element = row.split("|") + if len(element) == 3: + if element[2].find("source") > 0: + sources.append("%s_%s" % tuple(elem.strip(" ") for elem in element[:2])) + element[2] = sub("source\s?,?", "", element[2]).strip(" ") + if element[2]: + binaries.append("%s_%s [%s]" % tuple(elem.strip(" ") for elem in element)) + if sources: + logfile822.write("Sources:\n") + for source in sources: + logfile822.write(" %s\n" % source) + if binaries: + logfile822.write("Binaries:\n") + for binary in binaries: + logfile822.write(" %s\n" % binary) + logfile822.write("Reason: %s\n" % Options["Reason"].replace('\n', '\n ')) + if Options["Done"]: + logfile822.write("Bug: %s\n" % Options["Done"]) + logfile822.write("\n") + logfile822.close() dsc_type_id = get_override_type('dsc', session).overridetype_id deb_type_id = get_override_type('deb', session).overridetype_id @@ -536,31 +587,32 @@ def main (): session.commit() print "done." + Subst = {} + Subst["__RM_ADDRESS__"] = cnf["Rm::MyEmailAddress"] + Subst["__BUG_SERVER__"] = cnf["Dinstall::BugServer"] + bcc = [] + if cnf.Find("Dinstall::Bcc") != "": + bcc.append(cnf["Dinstall::Bcc"]) + if cnf.Find("Rm::Bcc") != "": + bcc.append(cnf["Rm::Bcc"]) + if bcc: + Subst["__BCC__"] = "Bcc: " + ", ".join(bcc) + else: + Subst["__BCC__"] = "X-Filler: 42" + Subst["__CC__"] = "X-DAK: dak rm" + if carbon_copy: + Subst["__CC__"] += "\nCc: " + ", ".join(carbon_copy) + Subst["__SUITE_LIST__"] = suites_list + Subst["__SUBJECT__"] = "Removed package(s) from %s" % (suites_list) + Subst["__ADMIN_ADDRESS__"] = cnf["Dinstall::MyAdminAddress"] + Subst["__DISTRO__"] = cnf["Dinstall::MyDistribution"] + Subst["__WHOAMI__"] = whoami + # Send the bug closing messages if Options["Done"]: - Subst = {} - Subst["__RM_ADDRESS__"] = cnf["Rm::MyEmailAddress"] - Subst["__BUG_SERVER__"] = cnf["Dinstall::BugServer"] - bcc = [] - if cnf.Find("Dinstall::Bcc") != "": - bcc.append(cnf["Dinstall::Bcc"]) - if cnf.Find("Rm::Bcc") != "": - bcc.append(cnf["Rm::Bcc"]) - if bcc: - Subst["__BCC__"] = "Bcc: " + ", ".join(bcc) - else: - Subst["__BCC__"] = "X-Filler: 42" - Subst["__CC__"] = "X-DAK: dak rm" - if carbon_copy: - Subst["__CC__"] += "\nCc: " + ", ".join(carbon_copy) - Subst["__SUITE_LIST__"] = suites_list summarymail = "%s\n------------------- Reason -------------------\n%s\n" % (summary, Options["Reason"]) summarymail += "----------------------------------------------\n" Subst["__SUMMARY__"] = summarymail - Subst["__SUBJECT__"] = "Removed package(s) from %s" % (suites_list) - Subst["__ADMIN_ADDRESS__"] = cnf["Dinstall::MyAdminAddress"] - Subst["__DISTRO__"] = cnf["Dinstall::MyDistribution"] - Subst["__WHOAMI__"] = whoami whereami = utils.where_am_i() Archive = cnf.SubTree("Archive::%s" % (whereami)) Subst["__MASTER_ARCHIVE__"] = Archive["OriginServer"] @@ -570,8 +622,28 @@ def main (): mail_message = utils.TemplateSubst(Subst,cnf["Dir::Templates"]+"/rm.bug-close") utils.send_mail(mail_message) - logfile.write("=========================================================================\n") - logfile.close() + # close associated bug reports + # FIXME: We should also close possible WNPP bugs for that package, but + # currently there's no sane way to determine them + if Options["Do-Close"]: + if len(versions) == 1: + Subst["__VERSION__"] = versions[0] + else: + utils.fubar("Closing bugs with multiple package versions is not supported. Do it yourself.") + whereami = utils.where_am_i() + Archive = cnf.SubTree("Archive::%s" % (whereami)) + # at this point, I just assume, that the first closed bug gives + # some usefull information on why the package got removed + Subst["__BUG_NUMBER__"] = utils.split_args(Options["Done"])[0] + if len(sources) > 1: + utils.fubar("Closing bugs for multiple source pakcages is not supported. Do it yourself.") + Subst["__BUG_NUMBER_ALSO__"] = "" + Subst["__SOURCE__"] = source.split("_", 1)[0] + for bug in bts.get_bugs('src', source.split("_", 1)[0], 'status', 'open'): + Subst["__BUG_NUMBER_ALSO__"] += str(bug) + "-done@" + cnf["Dinstall::BugServer"] + "," + mail_message = utils.TemplateSubst(Subst,cnf["Dir::Templates"]+"/rm.bug-close-related") + if Subst["__BUG_NUMBER_ALSO__"]: + utils.send_mail(mail_message) #######################################################################################