From b7d6ee82d9292fa353e76f3c940a2535759b4237 Mon Sep 17 00:00:00 2001 From: Ivo De Decker Date: Tue, 10 Dec 2013 22:26:26 +0100 Subject: [PATCH 01/25] first attempt at yaml logging --- britney.py | 14 ++++++++++++++ excuse.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/britney.py b/britney.py index ee09123..78ab7af 100755 --- a/britney.py +++ b/britney.py @@ -186,12 +186,14 @@ import string import time import optparse import urllib +import yaml import apt_pkg from functools import reduce, partial from itertools import chain, ifilter, product from operator import attrgetter +from datetime import datetime if __name__ == '__main__': # Check if there is a python-search dir for this version of @@ -1655,6 +1657,18 @@ class Britney(object): f.write("\n") f.close() + if hasattr(self.options, 'excuses_yaml_output'): + self.__log("> Writing YAML Excuses to %s" % self.options.excuses_yaml_output, type="I") + f = open(self.options.excuses_yaml_output, 'w') + excuselist = [] + for e in self.excuses: + excuselist.append(e.excusedata()) + excusesdata = {} + excusesdata["sources"] = excuselist + excusesdata["generated"] = datetime.utcnow() + f.write(yaml.dump(excusesdata, default_flow_style=False, allow_unicode=True)) + f.close() + self.__log("Update Excuses generation completed", type="I") # Upgrade run diff --git a/excuse.py b/excuse.py index 08e333f..8fa1874 100644 --- a/excuse.py +++ b/excuse.py @@ -151,3 +151,57 @@ class Excuse(object): res += "
  • Valid candidate\n" res = res + "\n" return res + + # TODO merge with html() + def text(self): + """Render the excuse in text""" + res = [] + res.append("%s (%s to %s)" % \ + (self.name, self.ver[0], self.ver[1])) + if self.maint: + maint = self.maint + # ugly hack to work around strange encoding in pyyaml + # should go away with pyyaml in python 3 + try: + maint.decode('ascii') + except UnicodeDecodeError: + maint = unicode(self.maint,'utf-8') + res.append("Maintainer: %s" % maint) + if self.section and string.find(self.section, "/") > -1: + res.append("Section: %s" % (self.section)) + if self.daysold != None: + if self.daysold < self.mindays: + res.append(("Too young, only %d of %d days old" % + (self.daysold, self.mindays))) + else: + res.append(("%d days old (needed %d days)" % + (self.daysold, self.mindays))) + for x in self.htmlline: + res.append("" + x + "") + lastdep = "" + for x in sorted(self.deps, lambda x,y: cmp(x.split('/')[0], y.split('/')[0])): + dep = x.split('/')[0] + if dep == lastdep: continue + lastdep = dep + if x in self.invalid_deps: + res.append("Depends: %s %s (not considered)" % (self.name, dep)) + else: + res.append("Depends: %s %s" % (self.name, dep)) + for (n,a) in self.break_deps: + if n not in self.deps: + res.append("Ignoring %s depends: %s" % (a, n)) + if self.is_valid: + res.append("Valid candidate") + return res + + def excusedata(self): + """Render the excuse in as key-value data""" + excusedata = {} + excusedata["excuses"] = self.text() + excusedata["source"] = self.name + excusedata["oldversion"] = self.ver[0] + excusedata["newversion"] = self.ver[1] + excusedata["age"] = self.daysold + excusedata["ageneeded"] = self.mindays + return excusedata + From 511a25707b90ec0832b6c5cc884dd6e1552014ef Mon Sep 17 00:00:00 2001 From: Ivo De Decker Date: Tue, 10 Dec 2013 22:27:32 +0100 Subject: [PATCH 02/25] add bug list to yaml --- britney.py | 2 ++ excuse.py | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/britney.py b/britney.py index 78ab7af..1d4fa9b 100755 --- a/britney.py +++ b/britney.py @@ -1434,6 +1434,8 @@ class Britney(object): new_bugs = sorted(set(bugs_u).difference(bugs_t)) old_bugs = sorted(set(bugs_t).difference(bugs_u)) + excuse.setbugs(old_bugs,new_bugs) + if len(new_bugs) > 0: excuse.addhtml("%s (%s) \n" return res + def setbugs(self, oldbugs, newbugs): + """"Set the list of old and new bugs""" + for bug in newbugs: + self.newbugs[bug] = 1 + for bug in oldbugs: + self.oldbugs[bug] = 1 + # TODO merge with html() def text(self): """Render the excuse in text""" @@ -203,5 +212,7 @@ class Excuse(object): excusedata["newversion"] = self.ver[1] excusedata["age"] = self.daysold excusedata["ageneeded"] = self.mindays + excusedata["newbugs"] = self.newbugs.keys() + excusedata["oldbugs"] = self.oldbugs.keys() return excusedata From 369f01e8d28988c00eb3739c4986b513b14b64f8 Mon Sep 17 00:00:00 2001 From: Ivo De Decker Date: Tue, 10 Dec 2013 22:27:32 +0100 Subject: [PATCH 03/25] first attempt at adding reason --- britney.py | 19 +++++++++++++++++++ excuse.py | 6 ++++++ 2 files changed, 25 insertions(+) diff --git a/britney.py b/britney.py index 1d4fa9b..5ec9a43 100755 --- a/britney.py +++ b/britney.py @@ -1007,6 +1007,7 @@ class Britney(object): # if no package can satisfy the dependency, add this information to the excuse if len(packages) == 0: excuse.addhtml("%s/%s unsatisfiable Depends: %s" % (pkg, arch, block_txt.strip())) + excuse.addreason("depends"); continue # for the solving packages, update the excuse to add the dependencies @@ -1048,6 +1049,7 @@ class Britney(object): excuse.addhtml("Not touching package, as requested by %s (contact debian-release " "if update is needed)" % hint.user) excuse.addhtml("Not considered") + excuse.addreason("block") self.excuses.append(excuse) return False @@ -1087,6 +1089,7 @@ class Britney(object): excuse.addhtml("Removal request by %s" % (hint.user)) excuse.addhtml("Trying to remove package, not update it") excuse.addhtml("Not considered") + excuse.addreason("remove") self.excuses.append(excuse) return False @@ -1235,6 +1238,7 @@ class Britney(object): if source_t and apt_pkg.version_compare(source_u[VERSION], source_t[VERSION]) < 0: excuse.addhtml("ALERT: %s is newer in testing (%s %s)" % (src, source_t[VERSION], source_u[VERSION])) self.excuses.append(excuse) + excuse.addreason("newerintesting"); return False # check if the source package really exists or if it is a fake one @@ -1256,6 +1260,7 @@ class Britney(object): same_source(source_u[VERSION], item.version): excuse.addhtml("Removal request by %s" % (item.user)) excuse.addhtml("Trying to remove package, not update it") + excuse.addreason("remove") update_candidate = False # check if there is a `block' or `block-udeb' hint for this package, or a `block-all source' hint @@ -1294,8 +1299,10 @@ class Britney(object): if suite == 'unstable' or block_cmd == 'block-udeb': excuse.addhtml("Not touching package due to %s request by %s (contact debian-release if update is needed)" % (block_cmd, blocked[block_cmd].user)) + excuse.addreason("block") else: excuse.addhtml("NEEDS APPROVAL BY RM") + excuse.addreason("block") update_candidate = False # if the suite is unstable, then we have to check the urgency and the minimum days of @@ -1325,6 +1332,7 @@ class Britney(object): excuse.addhtml("Too young, but urgency pushed by %s" % (urgent_hints[0].user)) else: update_candidate = False + excuse.addreason("age") if suite in ['pu', 'tpu']: # o-o-d(ish) checks for (t-)p-u @@ -1357,6 +1365,8 @@ class Britney(object): text = text + " (but %s isn't keeping up, so never mind)" % (arch) else: update_candidate = False + excuse.addreason("arch") + excuse.addreason("arch-%s" % arch) excuse.addhtml(text) @@ -1404,6 +1414,8 @@ class Britney(object): text = text + " (but %s isn't keeping up, so nevermind)" % (arch) else: update_candidate = False + excuse.addreason("arch") + excuse.addreason("arch-%s" % arch) if self.date_now != self.dates[src][1]: excuse.addhtml(text) @@ -1411,6 +1423,7 @@ class Britney(object): # if the source package has no binaries, set update_candidate to False to block the update if len(self.sources[suite][src][BINARIES]) == 0: excuse.addhtml("%s has no binaries on any arch" % src) + excuse.addreason("no-binaries") update_candidate = False # if the suite is unstable, then we have to check the release-critical bug lists before @@ -1443,6 +1456,7 @@ class Britney(object): excuse.addhtml("Updating %s introduces new bugs: %s" % (pkg, ", ".join( ["#%s" % (urllib.quote(a), a) for a in new_bugs]))) update_candidate = False + excuse.addreason("buggy") if len(old_bugs) > 0: excuse.addhtml("Updating %s fixes old bugs: %s" % (pkg, ", ".join( @@ -1457,6 +1471,7 @@ class Britney(object): excuse.dontinvalidate = True if not update_candidate and forces: excuse.addhtml("Should ignore, but forced by %s" % (forces[0].user)) + # TODO force update_candidate = True # if the package can be updated, it is a valid candidate @@ -1464,6 +1479,7 @@ class Britney(object): excuse.is_valid = True # else it won't be considered else: + # TODO excuse.addhtml("Not considered") self.excuses.append(excuse) @@ -1522,6 +1538,7 @@ class Britney(object): invalid.append(valid.pop(p)) exclookup[x].addhtml("Invalidated by dependency") exclookup[x].addhtml("Not considered") + exclookup[x].addreason("depends") exclookup[x].is_valid = False i = i + 1 @@ -1600,6 +1617,7 @@ class Britney(object): excuse.set_vers(tsrcv, None) excuse.addhtml("Removal request by %s" % (item.user)) excuse.addhtml("Package is broken, will try to remove") + excuse.addreason("remove") self.excuses.append(excuse) # sort the excuses by daysold and name @@ -1640,6 +1658,7 @@ class Britney(object): ok = True if not ok: e.addhtml("Impossible dependency: %s -> %s" % (e.name, d)) + e.addreason("depends") self.invalidate_excuses(upgrade_me, unconsidered) # sort the list of candidates diff --git a/excuse.py b/excuse.py index b81adbc..627bc4f 100644 --- a/excuse.py +++ b/excuse.py @@ -58,6 +58,7 @@ class Excuse(object): self.bugs = [] self.newbugs = {} self.oldbugs = {} + self.reason = {} self.htmlline = [] @property @@ -161,6 +162,10 @@ class Excuse(object): for bug in oldbugs: self.oldbugs[bug] = 1 + def addreason(self, reason): + """"adding reason""" + self.reason[reason] = 1 + # TODO merge with html() def text(self): """Render the excuse in text""" @@ -214,5 +219,6 @@ class Excuse(object): excusedata["ageneeded"] = self.mindays excusedata["newbugs"] = self.newbugs.keys() excusedata["oldbugs"] = self.oldbugs.keys() + excusedata["reason"] = self.reason.keys() return excusedata From e109b446dfe946f5c576f4541a0d7da2a54e07bb Mon Sep 17 00:00:00 2001 From: Ivo De Decker Date: Wed, 11 Dec 2013 21:21:13 +0100 Subject: [PATCH 04/25] add remove reason when package not in unstable --- britney.py | 1 + 1 file changed, 1 insertion(+) diff --git a/britney.py b/britney.py index 5ec9a43..542be29 100755 --- a/britney.py +++ b/britney.py @@ -1040,6 +1040,7 @@ class Britney(object): # otherwise, add a new excuse for its removal and return True src = self.sources['testing'][pkg] excuse = Excuse("-" + pkg) + excuse.addreason("remove") excuse.set_vers(src[VERSION], None) src[MAINTAINER] and excuse.set_maint(src[MAINTAINER].strip()) src[SECTION] and excuse.set_section(src[SECTION].strip()) From c971474945226e5042a30ed5d17720dbfa3183e3 Mon Sep 17 00:00:00 2001 From: Ivo De Decker Date: Wed, 11 Dec 2013 21:21:15 +0100 Subject: [PATCH 05/25] handle export for excuse with 'force' --- britney.py | 2 +- excuse.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/britney.py b/britney.py index 542be29..dff1680 100755 --- a/britney.py +++ b/britney.py @@ -1472,7 +1472,7 @@ class Britney(object): excuse.dontinvalidate = True if not update_candidate and forces: excuse.addhtml("Should ignore, but forced by %s" % (forces[0].user)) - # TODO force + excuse.force() update_candidate = True # if the package can be updated, it is a valid candidate diff --git a/excuse.py b/excuse.py index 627bc4f..d87d0c1 100644 --- a/excuse.py +++ b/excuse.py @@ -50,6 +50,7 @@ class Excuse(object): self.section = None self._is_valid = False self._dontinvalidate = False + self.forced = False self.invalid_deps = [] self.deps = {} @@ -117,6 +118,10 @@ class Excuse(object): self.daysold = daysold self.mindays = mindays + def force(self): + """Add force hint""" + self.forced = True + def addhtml(self, note): """Add a note in HTML""" self.htmlline.append(note) @@ -219,6 +224,10 @@ class Excuse(object): excusedata["ageneeded"] = self.mindays excusedata["newbugs"] = self.newbugs.keys() excusedata["oldbugs"] = self.oldbugs.keys() - excusedata["reason"] = self.reason.keys() + if self.forced: + excusedata["forcedreason"] = self.reason.keys() + excusedata["reason"] = [] + else: + excusedata["reason"] = self.reason.keys() return excusedata From 0304b1adb48d55cf4bd60fedf17f221b4ef4009a Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Wed, 11 Dec 2013 21:21:15 +0100 Subject: [PATCH 06/25] excuse.py: Use a set for storing bugs Signed-off-by: Niels Thykier --- excuse.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/excuse.py b/excuse.py index d87d0c1..4e15708 100644 --- a/excuse.py +++ b/excuse.py @@ -57,8 +57,8 @@ class Excuse(object): self.sane_deps = [] self.break_deps = [] self.bugs = [] - self.newbugs = {} - self.oldbugs = {} + self.newbugs = set() + self.oldbugs = set() self.reason = {} self.htmlline = [] @@ -162,10 +162,8 @@ class Excuse(object): def setbugs(self, oldbugs, newbugs): """"Set the list of old and new bugs""" - for bug in newbugs: - self.newbugs[bug] = 1 - for bug in oldbugs: - self.oldbugs[bug] = 1 + self.newbugs.update(newbugs) + self.oldbugs.update(oldbugs) def addreason(self, reason): """"adding reason""" @@ -222,8 +220,8 @@ class Excuse(object): excusedata["newversion"] = self.ver[1] excusedata["age"] = self.daysold excusedata["ageneeded"] = self.mindays - excusedata["newbugs"] = self.newbugs.keys() - excusedata["oldbugs"] = self.oldbugs.keys() + excusedata["newbugs"] = sorted(self.newbugs) + excusedata["oldbugs"] = sorted(self.oldbugs) if self.forced: excusedata["forcedreason"] = self.reason.keys() excusedata["reason"] = [] From 1ab07cb054c5d2c3f28b933ed76315bc2c51a722 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Wed, 11 Dec 2013 21:21:15 +0100 Subject: [PATCH 07/25] excuse.py: Rename keys to include "-" between words Signed-off-by: Niels Thykier --- excuse.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/excuse.py b/excuse.py index 4e15708..3868b4d 100644 --- a/excuse.py +++ b/excuse.py @@ -216,14 +216,14 @@ class Excuse(object): excusedata = {} excusedata["excuses"] = self.text() excusedata["source"] = self.name - excusedata["oldversion"] = self.ver[0] - excusedata["newversion"] = self.ver[1] + excusedata["old-version"] = self.ver[0] + excusedata["new-version"] = self.ver[1] excusedata["age"] = self.daysold - excusedata["ageneeded"] = self.mindays - excusedata["newbugs"] = sorted(self.newbugs) - excusedata["oldbugs"] = sorted(self.oldbugs) + excusedata["age-needed"] = self.mindays + excusedata["new-bugs"] = sorted(self.newbugs) + excusedata["old-bugs"] = sorted(self.oldbugs) if self.forced: - excusedata["forcedreason"] = self.reason.keys() + excusedata["forced-reason"] = self.reason.keys() excusedata["reason"] = [] else: excusedata["reason"] = self.reason.keys() From 93af0aac7a8e597c0056a21b93f233904285af2a Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Wed, 11 Dec 2013 21:21:15 +0100 Subject: [PATCH 08/25] excuse.py: Add "is-candidate" to the excuse Signed-off-by: Niels Thykier --- excuse.py | 1 + 1 file changed, 1 insertion(+) diff --git a/excuse.py b/excuse.py index 3868b4d..02b000f 100644 --- a/excuse.py +++ b/excuse.py @@ -227,5 +227,6 @@ class Excuse(object): excusedata["reason"] = [] else: excusedata["reason"] = self.reason.keys() + excusedata["is-candidate"] = self.is_valid return excusedata From 9e25dc26132377a3aa7875f60597ce4127c0fef2 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Wed, 11 Dec 2013 21:21:15 +0100 Subject: [PATCH 09/25] INSTALL: Mention the need for python-yaml Also prune the "2.7" in the package names under the assumption that people are running Jessie. Signed-off-by: Niels Thykier --- INSTALL | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/INSTALL b/INSTALL index 0f836ca..a65b744 100644 --- a/INSTALL +++ b/INSTALL @@ -4,6 +4,6 @@ INSTALL for britney v2.0 Requirements: ------------- - * Python 2.7 aptitude install python2.7 - * Python APT/DPKG bindings aptitude install python2.7-apt - + * Python 2.7 aptitude install python + * Python APT/DPKG bindings aptitude install python-apt + * Python YAML library aptitude install python-yaml From f9d2d787344949342d78a919e01199a7613e2425 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Wed, 11 Dec 2013 21:21:15 +0100 Subject: [PATCH 10/25] util: Add new "write_excuses" function Signed-off-by: Niels Thykier --- britney.py | 29 ++++++----------------------- britney_util.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/britney.py b/britney.py index dff1680..d274089 100755 --- a/britney.py +++ b/britney.py @@ -186,14 +186,12 @@ import string import time import optparse import urllib -import yaml import apt_pkg from functools import reduce, partial from itertools import chain, ifilter, product from operator import attrgetter -from datetime import datetime if __name__ == '__main__': # Check if there is a python-search dir for this version of @@ -217,7 +215,8 @@ from hints import HintCollection from britney_util import (old_libraries_format, same_source, undo_changes, register_reverses, compute_reverse_tree, read_nuninst, write_nuninst, write_heidi, - eval_uninst, newly_uninst, make_migrationitem) + eval_uninst, newly_uninst, make_migrationitem, + write_excuses) from consts import (VERSION, SECTION, BINARIES, MAINTAINER, FAKESRC, SOURCE, SOURCEVER, ARCHITECTURE, DEPENDS, CONFLICTS, PROVIDES, RDEPENDS, RCONFLICTS, MULTIARCH, ESSENTIAL) @@ -1668,28 +1667,12 @@ class Britney(object): # write excuses to the output file if not self.options.dry_run: self.__log("> Writing Excuses to %s" % self.options.excuses_output, type="I") - f = open(self.options.excuses_output, 'w') - f.write("\n") - f.write("excuses...") - f.write("\n") - f.write("

    Generated: " + time.strftime("%Y.%m.%d %H:%M:%S %z", time.gmtime(time.time())) + "

    \n") - f.write("
      \n") - for e in self.excuses: - f.write("
    • %s" % e.html()) - f.write("
    \n") - f.close() - + write_excuses(self.excuses, self.options.excuses_output, + output_format="legacy-html") if hasattr(self.options, 'excuses_yaml_output'): self.__log("> Writing YAML Excuses to %s" % self.options.excuses_yaml_output, type="I") - f = open(self.options.excuses_yaml_output, 'w') - excuselist = [] - for e in self.excuses: - excuselist.append(e.excusedata()) - excusesdata = {} - excusesdata["sources"] = excuselist - excusesdata["generated"] = datetime.utcnow() - f.write(yaml.dump(excusesdata, default_flow_style=False, allow_unicode=True)) - f.close() + write_excuses(self.excuses, self.options.excuses_yaml_output, + output_format="yaml") self.__log("Update Excuses generation completed", type="I") diff --git a/britney_util.py b/britney_util.py index be87e13..826ab53 100644 --- a/britney_util.py +++ b/britney_util.py @@ -23,9 +23,12 @@ import apt_pkg from functools import partial +from datetime import datetime from itertools import chain, ifilter, ifilterfalse, izip, repeat import re import time +import yaml + from migrationitem import MigrationItem, UnversionnedMigrationItem from consts import (VERSION, BINARIES, PROVIDES, DEPENDS, CONFLICTS, @@ -413,3 +416,34 @@ def make_migrationitem(package, sources, VERSION=VERSION): item = UnversionnedMigrationItem(package) return MigrationItem("%s/%s" % (item.uvname, sources[item.suite][item.package][VERSION])) + + +def write_excuses(excuses, dest_file, output_format="yaml"): + """Write the excuses to dest_file + + Writes a list of excuses in a specified output_format to the + path denoted by dest_file. The output_format can either be "yaml" + or "legacy-html". + """ + if output_format == "yaml": + with open(dest_file, 'w') as f: + excuselist = [] + for e in excuses: + excuselist.append(e.excusedata()) + excusesdata = {} + excusesdata["sources"] = excuselist + excusesdata["generated"] = datetime.utcnow() + f.write(yaml.dump(excusesdata, default_flow_style=False, allow_unicode=True)) + elif output_format == "legacy-html": + with open(dest_file, 'w') as f: + f.write("\n") + f.write("excuses...") + f.write("\n") + f.write("

    Generated: " + time.strftime("%Y.%m.%d %H:%M:%S %z", time.gmtime(time.time())) + "

    \n") + f.write("
      \n") + for e in excuses: + f.write("
    • %s" % e.html()) + f.write("
    \n") + else: + raise ValueError('Output format must be either "yaml or "legacy-html"') + From 36b58958a3589ea7ccea86b900ec2000da5eecb0 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Wed, 11 Dec 2013 21:21:15 +0100 Subject: [PATCH 11/25] excuse: Rename "generated" to "generated-date" "generated-date" suggests the value as a date, whereas "generated" suggests a boolean value. Signed-off-by: Niels Thykier --- britney_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/britney_util.py b/britney_util.py index 826ab53..cfd2fa9 100644 --- a/britney_util.py +++ b/britney_util.py @@ -432,7 +432,7 @@ def write_excuses(excuses, dest_file, output_format="yaml"): excuselist.append(e.excusedata()) excusesdata = {} excusesdata["sources"] = excuselist - excusesdata["generated"] = datetime.utcnow() + excusesdata["generated-date"] = datetime.utcnow() f.write(yaml.dump(excusesdata, default_flow_style=False, allow_unicode=True)) elif output_format == "legacy-html": with open(dest_file, 'w') as f: From d9f04b88c98b81766b4361459ca3bc635c311144 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Wed, 11 Dec 2013 21:49:17 +0100 Subject: [PATCH 12/25] britney.conf: Add EXCUSES_YAML_OUTPUT Signed-off-by: Niels Thykier --- britney.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/britney.conf b/britney.conf index 1dc4f89..76ecf5a 100644 --- a/britney.conf +++ b/britney.conf @@ -9,6 +9,7 @@ UNSTABLE = /srv/release.debian.org/britney/var/data-b2/unstable # Output NONINST_STATUS = /srv/release.debian.org/britney/var/data-b2/non-installable-status EXCUSES_OUTPUT = /srv/release.debian.org/britney/var/data-b2/output/excuses.html +EXCUSES_YAML_OUTPUT = /srv/release.debian.org/britney/var/data-b2/output/excuses.yaml UPGRADE_OUTPUT = /srv/release.debian.org/britney/var/data-b2/output/output.txt HEIDI_OUTPUT = /srv/release.debian.org/britney/var/data-b2/output/HeidiResult From 0214b41a4ff6a49c0293b2d8418683d28e5ffb85 Mon Sep 17 00:00:00 2001 From: Ivo De Decker Date: Wed, 11 Dec 2013 21:56:51 +0100 Subject: [PATCH 13/25] Add note when a pkg is being removed because it is not in sid Signed-off-by: Niels Thykier --- britney.py | 1 + 1 file changed, 1 insertion(+) diff --git a/britney.py b/britney.py index d274089..0d5303f 100755 --- a/britney.py +++ b/britney.py @@ -1039,6 +1039,7 @@ class Britney(object): # otherwise, add a new excuse for its removal and return True src = self.sources['testing'][pkg] excuse = Excuse("-" + pkg) + excuse.addhtml("Package not in unstable, will try to remove") excuse.addreason("remove") excuse.set_vers(src[VERSION], None) src[MAINTAINER] and excuse.set_maint(src[MAINTAINER].strip()) From 36da23b5b76a388efd6f0badcae2bb14706ee51d Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Sun, 15 Dec 2013 05:13:12 +0100 Subject: [PATCH 14/25] britney.py: Remove obsolete comment about AIEEE Signed-off-by: Niels Thykier --- britney.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/britney.py b/britney.py index 0d5303f..43c1be8 100755 --- a/britney.py +++ b/britney.py @@ -2711,9 +2711,6 @@ class Britney(object): If nuninst_arch is not None then it also updated in the same way as broken is. - - current_pkg is the package currently being tried, mainly used - to print where an AIEEE is coming from. """ r = self._inst_tester.is_installable(pkg_name, pkg_version, pkg_arch) if not r: From cc644bc57f1fd1e7b5e86dc1aec4f1dae193b476 Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Mon, 16 Dec 2013 23:05:09 +0100 Subject: [PATCH 15/25] Avoid exploding when reading broken hints If hint.check() fails, just ignore the hint instead of killing britney. Signed-off-by: Julien Cristau --- hints.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hints.py b/hints.py index b54584c..7b43cdb 100644 --- a/hints.py +++ b/hints.py @@ -33,7 +33,10 @@ class HintCollection(object): ] def add_hint(self, hint, user): - self._hints.append(Hint(hint, user)) + try: + self._hints.append(Hint(hint, user)) + except AssertionError: + print "Ignoring broken hint %r from %s" % (hint, user) class Hint(object): NO_VERSION = [ 'block', 'block-all', 'block-udeb' ] From 3dc4a6367f45337bf7563e2a8e6df13d98c2bf71 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Sat, 11 Jan 2014 09:03:16 +0100 Subject: [PATCH 16/25] Write "HeidiResultDelta" file containing the changes of the run Based on Colin Watson's code to do the same from the "britney2-ubuntu" repository[1] revision 306, 308 and 309. Notable differences include: * output include version of source package being removed * output prefix removals with a "-" (otherwise it would be identical to a upgrade/new source with the change above). [1] http://bazaar.launchpad.net/~ubuntu-release/britney/britney2-ubuntu/revision/306 Signed-off-by: Niels Thykier --- britney.py | 13 ++++++++++++- britney_util.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/britney.py b/britney.py index 43c1be8..40f808a 100755 --- a/britney.py +++ b/britney.py @@ -216,7 +216,7 @@ from britney_util import (old_libraries_format, same_source, undo_changes, register_reverses, compute_reverse_tree, read_nuninst, write_nuninst, write_heidi, eval_uninst, newly_uninst, make_migrationitem, - write_excuses) + write_excuses, write_heidi_delta) from consts import (VERSION, SECTION, BINARIES, MAINTAINER, FAKESRC, SOURCE, SOURCEVER, ARCHITECTURE, DEPENDS, CONFLICTS, PROVIDES, RDEPENDS, RCONFLICTS, MULTIARCH, ESSENTIAL) @@ -257,6 +257,8 @@ class Britney(object): apt_pkg.init() self.sources = {} self.binaries = {} + self.all_selected = [] + try: self.hints = self.read_hints(self.options.hintsdir) except AttributeError: @@ -385,6 +387,9 @@ class Britney(object): not getattr(self.options, k.lower()): setattr(self.options, k.lower(), v) + if not hasattr(self.options, "heidi_delta_output"): + self.options.heidi_delta_output = self.options.heidi_output + "Delta" + # Sort the architecture list allarches = sorted(self.options.architectures.split()) arches = [x for x in allarches if x in self.options.nobreakall_arches.split()] @@ -2272,6 +2277,7 @@ class Britney(object): newly_uninst(nuninst_start, nuninst_end)) + "\n") self.output_write("SUCCESS (%d/%d)\n" % (len(actions or self.upgrade_me), len(extra))) self.nuninst_orig = nuninst_end + self.all_selected += selected if not actions: if recurse: self.upgrade_me = sorted(extra) @@ -2401,6 +2407,11 @@ class Britney(object): write_heidi(self.options.heidi_output, self.sources["testing"], self.binaries["testing"]) + self.__log("Writing delta to %s" % self.options.heidi_delta_output) + write_heidi_delta(self.options.heidi_delta_output, + self.all_selected) + + self.printuninstchange() self.__log("Test completed!", type="I") diff --git a/britney_util.py b/britney_util.py index cfd2fa9..b23f7cf 100644 --- a/britney_util.py +++ b/britney_util.py @@ -407,6 +407,34 @@ def write_heidi(filename, sources_t, packages_t, srcsec = src[SECTION] or 'unknown' f.write('%s %s source %s\n' % (src_name, srcv, srcsec)) + +def write_heidi_delta(filename, all_selected): + """Write the output delta + + This method writes the packages to be upgraded, in the form: + + or (if the source is to be removed): + - + + The order corresponds to that shown in update_output. + """ + with open(filename, "w") as fd: + + fd.write("#HeidiDelta\n") + + for item in all_selected: + prefix = "" + + if item.is_removal: + prefix = "-" + + if item.architecture == 'source': + fd.write('%s%s %s\n' % (prefix, item.package, item.version)) + else: + fd.write('%s%s %s %s\n' % (prefix, item.package, + item.version, item.architecture)) + + def make_migrationitem(package, sources, VERSION=VERSION): """Convert a textual package specification to a MigrationItem From 07ad1de5deb6181828062956195eaa84803423a7 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Wed, 29 Jan 2014 23:04:28 +0100 Subject: [PATCH 17/25] britney.conf: Add sparc to {BREAK,FUCKED}_ARCHES Signed-off-by: Niels Thykier --- britney.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/britney.conf b/britney.conf index 76ecf5a..1f27a83 100644 --- a/britney.conf +++ b/britney.conf @@ -20,10 +20,10 @@ ARCHITECTURES = i386 amd64 armel ia64 mips mipsel powerpc sparc kfreebsd-i38 NOBREAKALL_ARCHES = i386 # if you're in this list, your packages may not stay in sync with the source -FUCKED_ARCHES = ia64 +FUCKED_ARCHES = ia64 sparc # if you're in this list, your uninstallability count may increase -BREAK_ARCHES = ia64 +BREAK_ARCHES = ia64 sparc # if you're in this list, you are a new architecture NEW_ARCHES = From 5dfa64624fe30741c51f278c605bf7a3b9e18fa0 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Fri, 31 Jan 2014 21:38:44 +0100 Subject: [PATCH 18/25] britney.conf: Remove ia64 from testing Signed-off-by: Niels Thykier --- britney.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/britney.conf b/britney.conf index 1f27a83..6b20ee0 100644 --- a/britney.conf +++ b/britney.conf @@ -14,16 +14,16 @@ UPGRADE_OUTPUT = /srv/release.debian.org/britney/var/data-b2/output/output.tx HEIDI_OUTPUT = /srv/release.debian.org/britney/var/data-b2/output/HeidiResult # List of release architectures -ARCHITECTURES = i386 amd64 armel ia64 mips mipsel powerpc sparc kfreebsd-i386 kfreebsd-amd64 armhf s390x +ARCHITECTURES = i386 amd64 armel mips mipsel powerpc sparc kfreebsd-i386 kfreebsd-amd64 armhf s390x # if you're not in this list, arch: all packages are allowed to break on you NOBREAKALL_ARCHES = i386 # if you're in this list, your packages may not stay in sync with the source -FUCKED_ARCHES = ia64 sparc +FUCKED_ARCHES = sparc # if you're in this list, your uninstallability count may increase -BREAK_ARCHES = ia64 sparc +BREAK_ARCHES = sparc # if you're in this list, you are a new architecture NEW_ARCHES = From 131a51ea25686f6b1be8e51134d001135723038f Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Fri, 31 Jan 2014 21:48:17 +0100 Subject: [PATCH 19/25] Sync britney_nobreakall.conf with recent changes Signed-off-by: Niels Thykier --- britney_nobreakall.conf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/britney_nobreakall.conf b/britney_nobreakall.conf index 71f67b1..9aa98c8 100644 --- a/britney_nobreakall.conf +++ b/britney_nobreakall.conf @@ -12,16 +12,16 @@ UPGRADE_OUTPUT = /srv/release.debian.org/britney/var/data-b2/output/output.tx HEIDI_OUTPUT = /srv/release.debian.org/britney/var/data-b2/output/HeidiResult # List of release architectures -ARCHITECTURES = i386 amd64 armel ia64 mips mipsel powerpc sparc kfreebsd-i386 kfreebsd-amd64 armhf s390x +ARCHITECTURES = i386 amd64 armel mips mipsel powerpc sparc kfreebsd-i386 kfreebsd-amd64 armhf s390x # if you're not in this list, arch: all packages are allowed to break on you -NOBREAKALL_ARCHES = i386 amd64 armel ia64 mips mipsel powerpc sparc kfreebsd-i386 kfreebsd-amd64 armhf s390x +NOBREAKALL_ARCHES = i386 amd64 armel mips mipsel powerpc sparc kfreebsd-i386 kfreebsd-amd64 armhf s390x # if you're in this list, your packages may not stay in sync with the source -FUCKED_ARCHES = ia64 +FUCKED_ARCHES = sparc # if you're in this list, your uninstallability count may increase -BREAK_ARCHES = ia64 +BREAK_ARCHES = sparc # if you're in this list, you are a new architecture NEW_ARCHES = From 92fe1724db1a609cfb84b4247defeb5e97753aba Mon Sep 17 00:00:00 2001 From: "Adam D. Barratt" Date: Thu, 27 Feb 2014 18:12:54 +0000 Subject: [PATCH 20/25] Fix a crash during installability testing Signed-off-by: Adam D. Barratt --- installability/tester.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/installability/tester.py b/installability/tester.py index a00308f..2b98b1b 100644 --- a/installability/tester.py +++ b/installability/tester.py @@ -280,10 +280,6 @@ class InstallabilityTester(object): # is smaller than testing (so presumably faster) remain = choice - never - cbroken - if not remain: - # all alternatives would violate the conflicts => package is not installable - return None - if len(remain) > 1 and not remain.isdisjoint(safe_set): first = None for r in ifilter(safe_set.__contains__, remain): @@ -305,6 +301,12 @@ class InstallabilityTester(object): check.update(remain) musts.update(remain) continue + + if not remain: + # all alternatives would violate the conflicts or are uninstallable + # => package is not installable + return None + # The choice is still deferred rebuild.add(frozenset(remain)) From 329f1901b4e3ebb22d0815fa6ff3ddc2f486a160 Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Mon, 10 Mar 2014 18:48:04 +0100 Subject: [PATCH 21/25] Factor write_sources into its own function Signed-off-by: Niels Thykier --- britney.py | 12 +++--------- britney_util.py | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/britney.py b/britney.py index 40f808a..9a6d509 100755 --- a/britney.py +++ b/britney.py @@ -216,7 +216,7 @@ from britney_util import (old_libraries_format, same_source, undo_changes, register_reverses, compute_reverse_tree, read_nuninst, write_nuninst, write_heidi, eval_uninst, newly_uninst, make_migrationitem, - write_excuses, write_heidi_delta) + write_excuses, write_heidi_delta, write_sources) from consts import (VERSION, SECTION, BINARIES, MAINTAINER, FAKESRC, SOURCE, SOURCEVER, ARCHITECTURE, DEPENDS, CONFLICTS, PROVIDES, RDEPENDS, RCONFLICTS, MULTIARCH, ESSENTIAL) @@ -911,14 +911,8 @@ class Britney(object): f.close() filename = os.path.join(basedir, 'Sources') - f = open(filename, 'w') - for src in sources: - output = "Package: %s\n" % src - for key, k in ((VERSION, 'Version'), (SECTION, 'Section'), (MAINTAINER, 'Maintainer')): - if not sources[src][key]: continue - output += (k + ": " + sources[src][key] + "\n") - f.write(output + "\n") - f.close() + write_sources(sources, filename) + # Utility methods for package analysis # ------------------------------------ diff --git a/britney_util.py b/britney_util.py index b23f7cf..b8327b1 100644 --- a/britney_util.py +++ b/britney_util.py @@ -33,7 +33,7 @@ from migrationitem import MigrationItem, UnversionnedMigrationItem from consts import (VERSION, BINARIES, PROVIDES, DEPENDS, CONFLICTS, RDEPENDS, RCONFLICTS, ARCHITECTURE, SECTION, - SOURCE, SOURCEVER) + SOURCE, SOURCEVER, MAINTAINER) binnmu_re = re.compile(r'^(.*)\+b\d+$') @@ -475,3 +475,21 @@ def write_excuses(excuses, dest_file, output_format="yaml"): else: raise ValueError('Output format must be either "yaml or "legacy-html"') + +def write_sources(sources_s, filename): + """Write a sources file from Britney's state for a given suite + + Britney discards fields she does not care about, so the resulting + file omitts a lot of regular fields. + """ + + key_pairs = ((VERSION, 'Version'), (SECTION, 'Section'), + (MAINTAINER, 'Maintainer')) + + with open(filename, 'w') as f: + for src in sources_s: + src_data = sources_s[src] + output = "Package: %s\n" % src + output += "\n".join(k + ": "+ src_data[key] + for key, k in key_pairs if src_data[key]) + f.write(output + "\n\n") From 3f86ef329923472cfbaab422a59bf9c33bac065b Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Mon, 10 Mar 2014 18:48:04 +0100 Subject: [PATCH 22/25] Move write_controlfiles to britney_util Signed-off-by: Niels Thykier --- britney.py | 53 +++++--------------------------------------- britney_util.py | 59 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 49 deletions(-) diff --git a/britney.py b/britney.py index 9a6d509..94bfc97 100755 --- a/britney.py +++ b/britney.py @@ -216,7 +216,7 @@ from britney_util import (old_libraries_format, same_source, undo_changes, register_reverses, compute_reverse_tree, read_nuninst, write_nuninst, write_heidi, eval_uninst, newly_uninst, make_migrationitem, - write_excuses, write_heidi_delta, write_sources) + write_excuses, write_heidi_delta, write_controlfiles) from consts import (VERSION, SECTION, BINARIES, MAINTAINER, FAKESRC, SOURCE, SOURCEVER, ARCHITECTURE, DEPENDS, CONFLICTS, PROVIDES, RDEPENDS, RCONFLICTS, MULTIARCH, ESSENTIAL) @@ -868,52 +868,6 @@ class Britney(object): return hints - def write_controlfiles(self, basedir, suite): - """Write the control files - - This method writes the control files for the binary packages of all - the architectures and for the source packages. - """ - sources = self.sources[suite] - - self.__log("Writing new %s control files to %s" % (suite, basedir)) - for arch in self.options.architectures: - filename = os.path.join(basedir, 'Packages_%s' % arch) - f = open(filename, 'w') - binaries = self.binaries[suite][arch][0] - for pkg in binaries: - output = "Package: %s\n" % pkg - for key, k in ((SECTION, 'Section'), (ARCHITECTURE, 'Architecture'), (MULTIARCH, 'Multi-Arch'), (SOURCE, 'Source'), (VERSION, 'Version'), - (DEPENDS, 'Depends'), (PROVIDES, 'Provides'), (CONFLICTS, 'Conflicts'), (ESSENTIAL, 'Essential')): - if not binaries[pkg][key]: continue - if key == SOURCE: - if binaries[pkg][SOURCE] == pkg: - if binaries[pkg][SOURCEVER] != binaries[pkg][VERSION]: - source = binaries[pkg][SOURCE] + " (" + binaries[pkg][SOURCEVER] + ")" - else: continue - else: - if binaries[pkg][SOURCEVER] != binaries[pkg][VERSION]: - source = binaries[pkg][SOURCE] + " (" + binaries[pkg][SOURCEVER] + ")" - else: - source = binaries[pkg][SOURCE] - output += (k + ": " + source + "\n") - if sources[binaries[pkg][SOURCE]][MAINTAINER]: - output += ("Maintainer: " + sources[binaries[pkg][SOURCE]][MAINTAINER] + "\n") - elif key == PROVIDES: - if len(binaries[pkg][key]) > 0: - output += (k + ": " + ", ".join(binaries[pkg][key]) + "\n") - elif key == ESSENTIAL: - if binaries[pkg][key]: - output += (k + ": " + " yes\n") - else: - output += (k + ": " + binaries[pkg][key] + "\n") - f.write(output + "\n") - f.close() - - filename = os.path.join(basedir, 'Sources') - write_sources(sources, filename) - - # Utility methods for package analysis # ------------------------------------ @@ -2388,7 +2342,10 @@ class Britney(object): if not self.options.dry_run: # re-write control files if self.options.control_files: - self.write_controlfiles(self.options.testing, 'testing') + self.__log("Writing new testing control files to %s" % + self.options.testing) + write_controlfiles(self.sources, self.binaries, + 'testing', self.options.testing) # write dates try: diff --git a/britney_util.py b/britney_util.py index b8327b1..93bf614 100644 --- a/britney_util.py +++ b/britney_util.py @@ -25,6 +25,7 @@ import apt_pkg from functools import partial from datetime import datetime from itertools import chain, ifilter, ifilterfalse, izip, repeat +import os import re import time import yaml @@ -33,7 +34,8 @@ from migrationitem import MigrationItem, UnversionnedMigrationItem from consts import (VERSION, BINARIES, PROVIDES, DEPENDS, CONFLICTS, RDEPENDS, RCONFLICTS, ARCHITECTURE, SECTION, - SOURCE, SOURCEVER, MAINTAINER) + SOURCE, SOURCEVER, MAINTAINER, MULTIARCH, + ESSENTIAL) binnmu_re = re.compile(r'^(.*)\+b\d+$') @@ -493,3 +495,58 @@ def write_sources(sources_s, filename): output += "\n".join(k + ": "+ src_data[key] for key, k in key_pairs if src_data[key]) f.write(output + "\n\n") + + +def write_controlfiles(sources, packages, suite, basedir): + """Write the control files + + This method writes the control files for the binary packages of all + the architectures and for the source packages. Note that Britney + discards a lot of fields that she does not care about. Therefore, + these files may omit a lot of regular fields. + """ + + sources_s = sources[suite] + packages_s = packages[suite] + + key_pairs = ((SECTION, 'Section'), (ARCHITECTURE, 'Architecture'), + (MULTIARCH, 'Multi-Arch'), (SOURCE, 'Source'), + (VERSION, 'Version'), (DEPENDS, 'Depends'), + (PROVIDES, 'Provides'), (CONFLICTS, 'Conflicts'), + (ESSENTIAL, 'Essential')) + + for arch in packages_s: + filename = os.path.join(basedir, 'Packages_%s' % arch) + binaries = packages_s[arch][0] + with open(filename, 'w') as f: + for pkg in binaries: + output = "Package: %s\n" % pkg + bin_data = binaries[pkg] + for key, k in key_pairs: + if not bin_data[key]: continue + if key == SOURCE: + src = bin_data[SOURCE] + if sources_s[src][MAINTAINER]: + output += ("Maintainer: " + sources_s[src][MAINTAINER] + "\n") + + if bin_data[SOURCE] == pkg: + if bin_data[SOURCEVER] != bin_data[VERSION]: + source = src + " (" + bin_data[SOURCEVER] + ")" + else: continue + else: + if bin_data[SOURCEVER] != bin_data[VERSION]: + source = src + " (" + bin_data[SOURCEVER] + ")" + else: + source = src + output += (k + ": " + source + "\n") + elif key == PROVIDES: + if bin_data[key]: + output += (k + ": " + ", ".join(bin_data[key]) + "\n") + elif key == ESSENTIAL: + if bin_data[key]: + output += (k + ": " + " yes\n") + else: + output += (k + ": " + bin_data[key] + "\n") + f.write(output + "\n") + + write_sources(sources_s, os.path.join(basedir, 'Sources')) From d644d7554ad4a7df40d6f41db313414134bd4a7d Mon Sep 17 00:00:00 2001 From: Niels Thykier Date: Mon, 10 Mar 2014 18:48:04 +0100 Subject: [PATCH 23/25] Move "old_libraries" to britney_util Signed-off-by: Niels Thykier --- britney.py | 32 ++++++-------------------------- britney_util.py | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/britney.py b/britney.py index 94bfc97..336f623 100755 --- a/britney.py +++ b/britney.py @@ -216,7 +216,8 @@ from britney_util import (old_libraries_format, same_source, undo_changes, register_reverses, compute_reverse_tree, read_nuninst, write_nuninst, write_heidi, eval_uninst, newly_uninst, make_migrationitem, - write_excuses, write_heidi_delta, write_controlfiles) + write_excuses, write_heidi_delta, write_controlfiles, + old_libraries) from consts import (VERSION, SECTION, BINARIES, MAINTAINER, FAKESRC, SOURCE, SOURCEVER, ARCHITECTURE, DEPENDS, CONFLICTS, PROVIDES, RDEPENDS, RCONFLICTS, MULTIARCH, ESSENTIAL) @@ -2324,14 +2325,14 @@ class Britney(object): self.do_all(actions=removals) # smooth updates - if len(self.options.smooth_updates) > 0: + if self.options.smooth_updates: self.__log("> Removing old packages left in testing from smooth updates", type="I") - removals = self.old_libraries() - if len(removals) > 0: + removals = old_libraries(self.sources, self.binaries) + if removals: self.output_write("Removing packages left in testing for smooth updates (%d):\n%s" % \ (len(removals), old_libraries_format(removals))) self.do_all(actions=removals) - removals = self.old_libraries() + removals = old_libraries(self.sources, self.binaries) else: removals = () @@ -2592,27 +2593,6 @@ class Britney(object): if i not in to_skip: self.do_hint("easy", "autohinter", [ MigrationItem("%s/%s" % (x[0], x[1])) for x in l[i] ]) - def old_libraries(self, same_source=same_source): - """Detect old libraries left in testing for smooth transitions - - This method detects old libraries which are in testing but no longer - built from the source package: they are still there because other - packages still depend on them, but they should be removed as soon - as possible. - - same_source is an opt to avoid "load global". - """ - sources = self.sources['testing'] - testing = self.binaries['testing'] - unstable = self.binaries['unstable'] - removals = [] - for arch in self.options.architectures: - for pkg_name in testing[arch][0]: - pkg = testing[arch][0][pkg_name] - if pkg_name not in unstable[arch][0] and \ - not same_source(sources[pkg[SOURCE]][VERSION], pkg[SOURCEVER]): - removals.append(MigrationItem("-" + pkg_name + "/" + arch + "/" + pkg[SOURCEVER])) - return removals def nuninst_arch_report(self, nuninst, arch): """Print a report of uninstallable packages for one architecture.""" diff --git a/britney_util.py b/britney_util.py index 93bf614..a931dfd 100644 --- a/britney_util.py +++ b/britney_util.py @@ -550,3 +550,27 @@ def write_controlfiles(sources, packages, suite, basedir): f.write(output + "\n") write_sources(sources_s, os.path.join(basedir, 'Sources')) + + +def old_libraries(sources, packages, same_source=same_source): + """Detect old libraries left in testing for smooth transitions + + This method detects old libraries which are in testing but no + longer built from the source package: they are still there because + other packages still depend on them, but they should be removed as + soon as possible. + + same_source is an optimisation to avoid "load global". + """ + sources_t = sources['testing'] + testing = packages['testing'] + unstable = packages['unstable'] + removals = [] + for arch in testing: + for pkg_name in testing[arch][0]: + pkg = testing[arch][0][pkg_name] + if pkg_name not in unstable[arch][0] and \ + not same_source(sources_t[pkg[SOURCE]][VERSION], pkg[SOURCEVER]): + migration = "-" + "/".join((pkg_name, arch, pkg[SOURCEVER])) + removals.append(MigrationItem(migration)) + return removals From a75002f472ca707045226fe37e2772fc842c4cad Mon Sep 17 00:00:00 2001 From: Philipp Kern Date: Sat, 26 Apr 2014 14:59:48 +0000 Subject: [PATCH 24/25] britney{,_nobreakall.conf}: Drop sparc from testing. Signed-off-by: Philipp Kern --- britney.conf | 6 +++--- britney_nobreakall.conf | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/britney.conf b/britney.conf index 6b20ee0..6779206 100644 --- a/britney.conf +++ b/britney.conf @@ -14,16 +14,16 @@ UPGRADE_OUTPUT = /srv/release.debian.org/britney/var/data-b2/output/output.tx HEIDI_OUTPUT = /srv/release.debian.org/britney/var/data-b2/output/HeidiResult # List of release architectures -ARCHITECTURES = i386 amd64 armel mips mipsel powerpc sparc kfreebsd-i386 kfreebsd-amd64 armhf s390x +ARCHITECTURES = i386 amd64 armel mips mipsel powerpc kfreebsd-i386 kfreebsd-amd64 armhf s390x # if you're not in this list, arch: all packages are allowed to break on you NOBREAKALL_ARCHES = i386 # if you're in this list, your packages may not stay in sync with the source -FUCKED_ARCHES = sparc +FUCKED_ARCHES = # if you're in this list, your uninstallability count may increase -BREAK_ARCHES = sparc +BREAK_ARCHES = # if you're in this list, you are a new architecture NEW_ARCHES = diff --git a/britney_nobreakall.conf b/britney_nobreakall.conf index 9aa98c8..801446a 100644 --- a/britney_nobreakall.conf +++ b/britney_nobreakall.conf @@ -12,16 +12,16 @@ UPGRADE_OUTPUT = /srv/release.debian.org/britney/var/data-b2/output/output.tx HEIDI_OUTPUT = /srv/release.debian.org/britney/var/data-b2/output/HeidiResult # List of release architectures -ARCHITECTURES = i386 amd64 armel mips mipsel powerpc sparc kfreebsd-i386 kfreebsd-amd64 armhf s390x +ARCHITECTURES = i386 amd64 armel mips mipsel powerpc kfreebsd-i386 kfreebsd-amd64 armhf s390x # if you're not in this list, arch: all packages are allowed to break on you -NOBREAKALL_ARCHES = i386 amd64 armel mips mipsel powerpc sparc kfreebsd-i386 kfreebsd-amd64 armhf s390x +NOBREAKALL_ARCHES = i386 amd64 armel mips mipsel powerpc kfreebsd-i386 kfreebsd-amd64 armhf s390x # if you're in this list, your packages may not stay in sync with the source -FUCKED_ARCHES = sparc +FUCKED_ARCHES = # if you're in this list, your uninstallability count may increase -BREAK_ARCHES = sparc +BREAK_ARCHES = # if you're in this list, you are a new architecture NEW_ARCHES = From 614ab74eb5051bbccb9023acf28c4ab73aec9b35 Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Sat, 24 May 2014 16:59:17 +0200 Subject: [PATCH 25/25] Add pochu Signed-off-by: Julien Cristau --- britney.conf | 1 + britney_nobreakall.conf | 1 + 2 files changed, 2 insertions(+) diff --git a/britney.conf b/britney.conf index 6779206..0433ed0 100644 --- a/britney.conf +++ b/britney.conf @@ -47,6 +47,7 @@ HINTS_NTHYKIER = STANDARD HINTS_KIBI = STANDARD HINTS_JMW = STANDARD HINTS_IVODD = STANDARD +HINTS_POCHU = STANDARD HINTS_FREEZE = block block-all block-udeb HINTS_FREEZE-EXCEPTION = unblock unblock-udeb HINTS_SATBRITNEY = easy diff --git a/britney_nobreakall.conf b/britney_nobreakall.conf index 801446a..e334a38 100644 --- a/britney_nobreakall.conf +++ b/britney_nobreakall.conf @@ -48,6 +48,7 @@ HINTS_FAW = HELPERS HINTS_NTHYKIER = STANDARD HINTS_KIBI = STANDARD HINTS_JMW = STANDARD +HINTS_POCHU = STANDARD HINTS_FREEZE = block block-all block-udeb HINTS_FREEZE-EXCEPTION = unblock unblock-udeb HINTS_SATBRITNEY = easy