mirror of
https://git.launchpad.net/~ubuntu-release/britney/+git/britney2-ubuntu
synced 2025-05-18 05:51:32 +00:00
Aggregate all migration decisions and present it in excuses
With this change, Britney can now provide a very brief summary of the migration via one single value (YAML) or line (HTML). This solves two issues: * It provides an aggregated version of the policy decision without having to loop over all policies (and even those would not give a full verdict on their own as not all rejections come from policies) * It enables a simple way to inform readers of the HTML excuses of whether a rejection is permanent or not. This should hopefully make it easier for contributors to understand Britney and react more pro-actively. Signed-off-by: Niels Thykier <niels@thykier.net>
This commit is contained in:
parent
f40a7f41b3
commit
d7a676d074
30
britney.py
30
britney.py
@ -1085,7 +1085,7 @@ class Britney(object):
|
|||||||
self.excuses[excuse.name] = excuse
|
self.excuses[excuse.name] = excuse
|
||||||
return False
|
return False
|
||||||
|
|
||||||
excuse.is_valid = True
|
excuse.policy_verdict = PolicyVerdict.PASS
|
||||||
self.excuses[excuse.name] = excuse
|
self.excuses[excuse.name] = excuse
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -1237,7 +1237,7 @@ class Britney(object):
|
|||||||
|
|
||||||
# if there is nothing wrong and there is something worth doing, this is a valid candidate
|
# if there is nothing wrong and there is something worth doing, this is a valid candidate
|
||||||
if not anywrongver and anyworthdoing:
|
if not anywrongver and anyworthdoing:
|
||||||
excuse.is_valid = True
|
excuse.policy_verdict = PolicyVerdict.PASS
|
||||||
self.excuses[excuse.name] = excuse
|
self.excuses[excuse.name] = excuse
|
||||||
return True
|
return True
|
||||||
# else if there is something worth doing (but something wrong, too) this package won't be considered
|
# else if there is something worth doing (but something wrong, too) this package won't be considered
|
||||||
@ -1293,7 +1293,7 @@ class Britney(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# the starting point is that we will update the candidate
|
# the starting point is that we will update the candidate
|
||||||
excuse.is_valid = True
|
excuse.policy_verdict = PolicyVerdict.PASS
|
||||||
|
|
||||||
# if there is a `remove' hint and the requested version is the same as the
|
# if there is a `remove' hint and the requested version is the same as the
|
||||||
# version in testing, then stop here and return False
|
# version in testing, then stop here and return False
|
||||||
@ -1303,7 +1303,7 @@ class Britney(object):
|
|||||||
excuse.add_hint(hint)
|
excuse.add_hint(hint)
|
||||||
excuse.addhtml("Removal request by %s" % (hint.user))
|
excuse.addhtml("Removal request by %s" % (hint.user))
|
||||||
excuse.addhtml("Trying to remove package, not update it")
|
excuse.addhtml("Trying to remove package, not update it")
|
||||||
excuse.is_valid = False
|
excuse.policy_verdict = PolicyVerdict.REJECTED_PERMANENTLY
|
||||||
break
|
break
|
||||||
|
|
||||||
# check if there is a `block' or `block-udeb' hint for this package, or a `block-all source' hint
|
# check if there is a `block' or `block-udeb' hint for this package, or a `block-all source' hint
|
||||||
@ -1358,7 +1358,7 @@ class Britney(object):
|
|||||||
else:
|
else:
|
||||||
excuse.addhtml("NEEDS APPROVAL BY RM")
|
excuse.addhtml("NEEDS APPROVAL BY RM")
|
||||||
excuse.addreason("block")
|
excuse.addreason("block")
|
||||||
excuse.is_valid = False
|
excuse.policy_verdict = PolicyVerdict.REJECTED_PERMANENTLY
|
||||||
|
|
||||||
# at this point, we check the status of the builds on all the supported architectures
|
# at this point, we check the status of the builds on all the supported architectures
|
||||||
# to catch the out-of-date ones
|
# to catch the out-of-date ones
|
||||||
@ -1404,7 +1404,7 @@ class Britney(object):
|
|||||||
# we would not need to be forgiving at
|
# we would not need to be forgiving at
|
||||||
# all. However, due to how arch:all packages
|
# all. However, due to how arch:all packages
|
||||||
# are handled, we do run into occasionally.
|
# are handled, we do run into occasionally.
|
||||||
excuse.is_valid = False
|
excuse.policy_verdict = PolicyVerdict.REJECTED_PERMANENTLY
|
||||||
|
|
||||||
# if there are out-of-date packages, warn about them in the excuse and set excuse.is_valid
|
# if there are out-of-date packages, warn about them in the excuse and set excuse.is_valid
|
||||||
# to False to block the update; if the architecture where the package is out-of-date is
|
# to False to block the update; if the architecture where the package is out-of-date is
|
||||||
@ -1434,9 +1434,9 @@ class Britney(object):
|
|||||||
if self.options.ignore_cruft:
|
if self.options.ignore_cruft:
|
||||||
text = text + " (but ignoring cruft, so nevermind)"
|
text = text + " (but ignoring cruft, so nevermind)"
|
||||||
else:
|
else:
|
||||||
excuse.is_valid = False
|
excuse.policy_verdict = PolicyVerdict.REJECTED_PERMANENTLY
|
||||||
else:
|
else:
|
||||||
excuse.is_valid = False
|
excuse.policy_verdict = PolicyVerdict.REJECTED_PERMANENTLY
|
||||||
excuse.missing_build_on_arch(arch)
|
excuse.missing_build_on_arch(arch)
|
||||||
|
|
||||||
excuse.addhtml(text)
|
excuse.addhtml(text)
|
||||||
@ -1445,21 +1445,20 @@ class Britney(object):
|
|||||||
if not source_u.binaries:
|
if not source_u.binaries:
|
||||||
excuse.addhtml("%s has no binaries on any arch" % src)
|
excuse.addhtml("%s has no binaries on any arch" % src)
|
||||||
excuse.addreason("no-binaries")
|
excuse.addreason("no-binaries")
|
||||||
excuse.is_valid = False
|
excuse.policy_verdict = PolicyVerdict.REJECTED_PERMANENTLY
|
||||||
|
|
||||||
# if the suite is unstable, then we have to check the urgency and the minimum days of
|
# if the suite is unstable, then we have to check the urgency and the minimum days of
|
||||||
# permanence in unstable before updating testing; if the source package is too young,
|
# permanence in unstable before updating testing; if the source package is too young,
|
||||||
# the check fails and we set is_valid to False to block the update; consider
|
# the check fails and we set is_valid to False to block the update; consider
|
||||||
# the age-days hint, if specified for the package
|
# the age-days hint, if specified for the package
|
||||||
|
policy_verdict = excuse.policy_verdict
|
||||||
policy_info = excuse.policy_info
|
policy_info = excuse.policy_info
|
||||||
policy_verdict = PolicyVerdict.PASS
|
|
||||||
for policy in self.policies:
|
for policy in self.policies:
|
||||||
if suite in policy.applicable_suites:
|
if suite in policy.applicable_suites:
|
||||||
v = policy.apply_policy(policy_info, suite, src, source_t, source_u, excuse)
|
v = policy.apply_policy(policy_info, suite, src, source_t, source_u, excuse)
|
||||||
if v.value > policy_verdict.value:
|
if v.value > policy_verdict.value:
|
||||||
policy_verdict = v
|
policy_verdict = v
|
||||||
if policy_verdict.is_rejected:
|
excuse.policy_verdict = policy_verdict
|
||||||
excuse.is_valid = False
|
|
||||||
|
|
||||||
if suite in ('pu', 'tpu') and source_t:
|
if suite in ('pu', 'tpu') and source_t:
|
||||||
# o-o-d(ish) checks for (t-)p-u
|
# o-o-d(ish) checks for (t-)p-u
|
||||||
@ -1490,7 +1489,7 @@ class Britney(object):
|
|||||||
text = text + " (but %s isn't keeping up, so never mind)" % (arch)
|
text = text + " (but %s isn't keeping up, so never mind)" % (arch)
|
||||||
excuse.missing_build_on_ood_arch(arch)
|
excuse.missing_build_on_ood_arch(arch)
|
||||||
else:
|
else:
|
||||||
excuse.is_valid = False
|
excuse.policy_verdict = PolicyVerdict.REJECTED_PERMANENTLY
|
||||||
excuse.missing_build_on_arch(arch)
|
excuse.missing_build_on_arch(arch)
|
||||||
|
|
||||||
excuse.addhtml(text)
|
excuse.addhtml(text)
|
||||||
@ -1585,7 +1584,10 @@ class Britney(object):
|
|||||||
excuse.addhtml("Removal request by %s" % (hint.user))
|
excuse.addhtml("Removal request by %s" % (hint.user))
|
||||||
excuse.addhtml("Package is broken, will try to remove")
|
excuse.addhtml("Package is broken, will try to remove")
|
||||||
excuse.add_hint(hint)
|
excuse.add_hint(hint)
|
||||||
excuse.is_valid = True
|
# Using "PASS" here as "Created by a hint" != "accepted due to hint". In a future
|
||||||
|
# where there might be policy checks on removals, it would make sense to distinguish
|
||||||
|
# those two states. Not sure that future will ever be.
|
||||||
|
excuse.policy_verdict = PolicyVerdict.PASS
|
||||||
excuses[excuse.name] = excuse
|
excuses[excuse.name] = excuse
|
||||||
|
|
||||||
# extract the not considered packages, which are in the excuses but not in upgrade_me
|
# extract the not considered packages, which are in the excuses but not in upgrade_me
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from britney2.policies.policy import PolicyVerdict
|
||||||
|
|
||||||
class Excuse(object):
|
class Excuse(object):
|
||||||
"""Excuse class
|
"""Excuse class
|
||||||
@ -51,6 +52,7 @@ class Excuse(object):
|
|||||||
self.needs_approval = False
|
self.needs_approval = False
|
||||||
self.hints = []
|
self.hints = []
|
||||||
self.forced = False
|
self.forced = False
|
||||||
|
self._policy_verdict = PolicyVerdict.REJECTED_PERMANENTLY
|
||||||
|
|
||||||
self.invalid_deps = []
|
self.invalid_deps = []
|
||||||
self.deps = {}
|
self.deps = {}
|
||||||
@ -73,13 +75,19 @@ class Excuse(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
return self._is_valid
|
return False if self._policy_verdict.is_rejected else True
|
||||||
|
|
||||||
@is_valid.setter
|
|
||||||
def is_valid(self, value):
|
|
||||||
self._is_valid = value
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def policy_verdict(self):
|
||||||
|
return self._policy_verdict
|
||||||
|
|
||||||
|
@policy_verdict.setter
|
||||||
|
def policy_verdict(self, value):
|
||||||
|
if value.is_rejected and self.forced:
|
||||||
|
# By virtue of being forced, the item was hinted to
|
||||||
|
# undo the rejection
|
||||||
|
value = PolicyVerdict.PASS_HINTED
|
||||||
|
self._policy_verdict = value
|
||||||
|
|
||||||
def set_vers(self, tver, uver):
|
def set_vers(self, tver, uver):
|
||||||
"""Set the testing and unstable versions"""
|
"""Set the testing and unstable versions"""
|
||||||
@ -120,8 +128,8 @@ class Excuse(object):
|
|||||||
def force(self):
|
def force(self):
|
||||||
"""Add force hint"""
|
"""Add force hint"""
|
||||||
self.forced = True
|
self.forced = True
|
||||||
if not self._is_valid:
|
if self._policy_verdict.is_rejected:
|
||||||
self._is_valid = True
|
self._policy_verdict = PolicyVerdict.PASS_HINTED
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -144,10 +152,24 @@ class Excuse(object):
|
|||||||
def add_hint(self, hint):
|
def add_hint(self, hint):
|
||||||
self.hints.append(hint)
|
self.hints.append(hint)
|
||||||
|
|
||||||
|
def _format_verdict_summary(self):
|
||||||
|
verdict = self._policy_verdict
|
||||||
|
if not verdict.is_rejected:
|
||||||
|
msg = 'OK: Will attempt migration'
|
||||||
|
if verdict == PolicyVerdict.PASS_HINTED:
|
||||||
|
msg = 'OK: Will attempt migration due to a hint'
|
||||||
|
msg += " (Any information below is purely informational)"
|
||||||
|
return msg
|
||||||
|
if verdict == PolicyVerdict.REJECTED_PERMANENTLY:
|
||||||
|
msg = "BLOCKED: Will not migrate (Please review if it introduces a regression or needs approval/unblock)"
|
||||||
|
return msg
|
||||||
|
return "TEMP-BLOCKED: Waiting for test results, another package or too young (no action required at this time)"
|
||||||
|
|
||||||
def html(self):
|
def html(self):
|
||||||
"""Render the excuse in HTML"""
|
"""Render the excuse in HTML"""
|
||||||
res = "<a id=\"%s\" name=\"%s\">%s</a> (%s to %s)\n<ul>\n" % \
|
res = "<a id=\"%s\" name=\"%s\">%s</a> (%s to %s)\n<ul>\n" % \
|
||||||
(self.name, self.name, self.name, self.ver[0], self.ver[1])
|
(self.name, self.name, self.name, self.ver[0], self.ver[1])
|
||||||
|
res += "<li>Migration status: %s" % self._format_verdict_summary()
|
||||||
if self.maint:
|
if self.maint:
|
||||||
res = res + "<li>Maintainer: %s\n" % (self.maint)
|
res = res + "<li>Maintainer: %s\n" % (self.maint)
|
||||||
if self.section and self.section.find("/") > -1:
|
if self.section and self.section.find("/") > -1:
|
||||||
@ -210,6 +232,7 @@ class Excuse(object):
|
|||||||
excusedata["excuses"] = self._text()
|
excusedata["excuses"] = self._text()
|
||||||
excusedata["item-name"] = self.name
|
excusedata["item-name"] = self.name
|
||||||
excusedata["source"] = source
|
excusedata["source"] = source
|
||||||
|
excusedata["migration-policy-verdict"] = self._policy_verdict
|
||||||
excusedata["old-version"] = self.ver[0]
|
excusedata["old-version"] = self.ver[0]
|
||||||
excusedata["new-version"] = self.ver[1]
|
excusedata["new-version"] = self.ver[1]
|
||||||
if self.maint:
|
if self.maint:
|
||||||
|
@ -39,6 +39,7 @@ from britney2.consts import (VERSION, PROVIDES, DEPENDS, CONFLICTS,
|
|||||||
SOURCE, MAINTAINER, MULTIARCH,
|
SOURCE, MAINTAINER, MULTIARCH,
|
||||||
ESSENTIAL)
|
ESSENTIAL)
|
||||||
from britney2.migrationitem import MigrationItem, UnversionnedMigrationItem
|
from britney2.migrationitem import MigrationItem, UnversionnedMigrationItem
|
||||||
|
from britney2.policies.policy import PolicyVerdict
|
||||||
|
|
||||||
|
|
||||||
def ifilter_except(container, iterable=None):
|
def ifilter_except(container, iterable=None):
|
||||||
@ -814,7 +815,8 @@ def invalidate_excuses(excuses, valid, invalid):
|
|||||||
invalid.append(valid.pop(p))
|
invalid.append(valid.pop(p))
|
||||||
excuses[x].addhtml("Invalidated by dependency")
|
excuses[x].addhtml("Invalidated by dependency")
|
||||||
excuses[x].addreason("depends")
|
excuses[x].addreason("depends")
|
||||||
excuses[x].is_valid = False
|
if excuses[x].policy_verdict.value < PolicyVerdict.REJECTED_TEMPORARILY.value:
|
||||||
|
excuses[x].policy_verdict = PolicyVerdict.REJECTED_TEMPORARILY
|
||||||
|
|
||||||
|
|
||||||
def compile_nuninst(binaries_t, inst_tester, architectures, nobreakall_arches):
|
def compile_nuninst(binaries_t, inst_tester, architectures, nobreakall_arches):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user