Avoid some cases of O(n^2) behaviour in sort_actions and reduce the
size of n for the remaining O(n^2)-ish behaviour by filtering out
removals early on.
Signed-off-by: Niels Thykier <niels@thykier.net>
It's more natural to say "check this package if the current arch is in
this list" than "do not check this package if the current arch is not
in this list"
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
This updates the doop_source and _compute_groups functions so
that binary packages that are built from a different source
aren't included as part of an update to the original source.
In the event that it's a binary-only update, also don't remove
the hijacked packages from testing.
This change also removes an obsolete comment regardarding pre-conditions
for the _compute_groups function.
The live-data tests rely on an inconsistency, since they were before
Britney started to record the Essential field.
Signed-off-by: Niels Thykier <niels@thykier.net>
britney assumes that a package build is uniquely described by its
name, version and architecture. Particularly when constructing
Packages files by hand for testing purposes this assumption can be
violated, leading to confusing behaviour. This change makes britney
look for such mismatches, and report if any are found.
Notably:
* Avoid repeated calls frozenset(X), where we can trivially do
without.
* Skip the inner loop, when "i" is in "to_skip".
* Use a set rather than a list for "to_skip" as we do more
membership tests.
Signed-off-by: Niels Thykier <niels@thykier.net>
The get_dependency_solvers method returns a (boolean, list)-tuple, but
the boolean can always be implied from the list (in boolean context).
Signed-off-by: Niels Thykier <niels@thykier.net>
cmp is gone in python3. Also add a sorting method to Excuse that is
compatible with its __eq__/__hash__ methods.
Signed-off-by: Julien Cristau <jcristau@debian.org>
It doesn't exist in python3, but 1000 days should be safe enough as a
fallback for a package without urgency.
Signed-off-by: Julien Cristau <jcristau@debian.org>
- split the one-liner into a for and an if
- use open() as a context manager
- don't use string.strip which is gone in python3
Signed-off-by: Julien Cristau <jcristau@debian.org>
The "remark" hint is only intended for showing up in the output of "d"
(or via hint grep). It has no effect on Britney's behaviour.
Admittedly, the original code would have ignored it as well. But this
change makes it explicit and not simply a "ignored due to insufficient
permissions".
Signed-off-by: Niels Thykier <niels@thykier.net>
For out-of-date binaries, generate different excuses when the build is
missing, or when old (cruft) binaries for previous version are still around.
Signed-off-by: Ivo De Decker <ivodd@debian.org>
As part of a migration, we remove all the existing binaries built by
the source (possibly on a particular architecture) from testing; this
includes architecture-independent binary packages. However, when a
binNMU is in *pu, only the arch-dependent binary pakcages are present.
As a result, after the migration the architecture-independent packages
are no longer present in testing. This usually isn't a practical
problem, as dak will re-add them when it generates the packages files.
It is, however, wrong and will break if a source migration is tempted
during the same run as (and after) the *pu binary migration happened.
The simple fix is to not remove the architecture-independent packages
when performing such migrations.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
In the rare case that a hint removed an uninstallable binary, the
binary could still be included in the nuninst counter.
Regression introduced in a46dd88.
Signed-off-by: Niels Thykier <niels@thykier.net>
sort_actions() can be quite expensive and it is wasteful to resort
actions after each successful "easy"-hint.
Signed-off-by: Niels Thykier <niels@thykier.net>
There are no uses of "lundo" left for a non-hint recurse run (i.e.
the "main run"), so there is no point in building it.
The "lundo"-list is still used in the recurse run of a "hint"-hint.
Signed-off-by: Niels Thykier <niels@thykier.net>
The "do_all"-method now checks the architectures of all changes
applied. If they entirely consist of items from "break archs", then
"do_all" will disregard the current "break archs" setting when
comparing nuninst counters.
This change avoids unintended installability regressions on break
arches when a hint (manual or automatic) apply only to packages on
break arches.
Signed-off-by: Niels Thykier <niels@thykier.net>
Rename local variables and avoid repeated chained lookups. In
particular, avoid confusing cases like:
[...]
version = binaries[parch][0][binary][VERSION]
[...]
binaries[parch][0][binary] = self.binaries[item.suite][parch][0][binary]
version = binaries[parch][0][binary][VERSION]
Where "version" here will refer to two different versions. The former
the version from testing of a hijacked binary and the latter the
version from the source suite (despite the look up using the "testing"
table, due to the testing copy being updated).
Notable renamings:
* binaries => packages_t (a.k.a. self.binaries['testing'])
* binaries[parch][0] => binaries_t_a
* binaries[parch][1] => provides_t_a
* Similar naming used for "item.suite" instead of "testing"
The naming is based on the following logic:
* self.binaries from "packages" files
(by this logic, it ought to be "self.packages", but that is
for later)
* The "_X_a" is short for "[<suite>][<parch>]" look ups.
* binaries_X_a and provides_X_a are the specialised parts of
packages_X_a that deal with (real) binary packages and
provides (i.e. virtual packages) respectively.
Signed-off-by: Niels Thykier <niels@thykier.net>
Extract a specialised iter_packages_hint from iter_packages that only
deals with applying hints. This simplifies iter_packages AND avoids
having to re-compute the uninstallability counters after each single
item in the hint.
This means that a hint can now avoid triggering expontential runtime
provided only that the "post-hint" stage does not trigger expontential
runtime. Previously the hint had to be ordered such that none of the
items in the hint caused such behaviour (if at all possible).
Signed-off-by: Niels Thykier <niels@thykier.net>
Avoid creating two dependency clauses for dependencies emulating a
"version range" a la:
Depends: pkg-a (>= 2), pkg-a (<< 3~)
Previously this would create two clauses a la:
- (pkg-a, 2, arch), (pkg-a, 3, arch)
- (pkg-a, 1, arch), (pkg-a, 2, arch)
However, it is plain to see that only (pkg-a, 2, arch) is a valid
solution and the other options are just noise. This patch makes
Britney merge these two claues into a single clause containing exactly
(pkg-a, 2, arch).
Signed-off-by: Niels Thykier <niels@thykier.net>
The "new" auto hinter relies on partial ordering to determine, when
what can migrate (and what needs to migrate at the same time). At the
same time, it leverages on "_compute_groups" to allow it to include
"removals" in its hints.
Signed-off-by: Niels Thykier <niels@thykier.net>
Avoid smooth-updating libraries in hints, when all of their reverse
dependencies will certainly disappear in the same hint.
Note that in "hint"-hint, reverse dependencies removed in the
following "full run" will not cause the smooth-updated library to be
removed. Instead these will still be removed in the end as usual, but
in some cases that is too late.
Signed-off-by: Niels Thykier <niels@thykier.net>
Rename find_upgraded_binaries into _compute_groups. The new method
will also compute what binaries will be updated in or added to testing
after migration.
Signed-off-by: Niels Thykier <niels@thykier.net>
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 <niels@thykier.net>
This introduces a new variable HINTSDIR, which overrides the location of the
Hints dir (normally it is read from the UNSTABLE dir).
Please note that this is the location of the dir that contains the Hints dir.
Signed-off-by: Niels Thykier <niels@thykier.net>
This introduces a new variable OUTPUTDIR, which overrides the location where
the new dates file is written. This allow to run britney against a read-only
copy of the data.
Signed-off-by: Niels Thykier <niels@thykier.net>
Set the default to maxint until we've read something.
Reported-by: Ivo De Decker <ivo.dedecker@ugent.be>
Signed-off-by: Julien Cristau <jcristau@debian.org>
The new Installability Tester (IT) module replaces the remaining
C-parts. Unlike C-implementation, it does not give up and emit an
"AIEEE" half-way through.
In order to determine installability, it uses two sets "musts" and
"never". As the names suggest, the sets represents the packages that
must be (co-)installable with the package being tested and those that
can never be co-installable. For a package to be installable, "musts"
and "never" have remain disjoint.
These sets are also used to reduce the number of alternatives that are
available to satisfy a given dependency. When these sets are unable
to remove the choice completely, the new IT defers the choice to later.
This occasionally reduces backtracking as a later package may conflict
or unconditionally depend on one of the remaining alternatives.
Signed-off-by: Niels Thykier <niels@thykier.net>
We stopped populating the element with real data some time ago, it's
time to drop it entirely.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
Multiarch adds a Depends: foo:any syntax, permitted only if the
target of the dependency is "Multi-Arch: allowed". This has
been supported by dpkg and apt for some time and is now safe to
use in unstable.
[Adam D. Barratt: adjusted to use consts.py]
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
As HintItem is now redundant, also replace it with a new class -
UnversionnedMigrationItem - and migrate users of the classes to use
the new versions.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
Where possible, avoid creating a list only to discard immediately
afterwards. Example:
"""
for x in sorted([x for x in ...]):
...
"""
Creates a list, passes it to sorted, which generates a new list and
sorts that copy. Since sorted accepts an iterable, we can avoid the
"inner" list and just pass it a generator expression instead.
Signed-off-by: Niels Thykier <niels@thykier.net>
By moving the package loop inside register_reverses, it will be
invoked a lot less (reducing the overhead of invoking functions).
Signed-off-by: Niels Thykier <niels@thykier.net>
Beside some "minor differences" they were computing the same "tree"
(read: "graph"), so merge them into one (get_reverse_tree) and
properly document return value and special cases.
Signed-off-by: Niels Thykier <niels@thykier.net>
Rewrite the arguments of find_upgraded_binaries to not use an instance
of MigrationItem. We want to call it at a time where we have not
created MigrationItems yet.
Signed-off-by: Niels Thykier <niels@thykier.net>
A removal hint will generate both source and per-arch excuses if the
version of the source package differs between testing and unstable. If
the source versions are the same then only the per-arch excuses will
be generated.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
In rare cases with hints with overlapping virtual packages provided by
different sources, this can make a difference.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
If there are multiple versions of an arch:all package in unstable (due
to outdated or no longer built arch:any packages) then only one of them
should be recorded in the list of binary packages built from the source
package. Otherwise we may try and remove the binary package from various
lists multiple times, leading to crashes.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
Given a source which provides two packages and has different versions
in testing and unstable, binNMUs in unstable corresponding to the
older source version should not be considered as migration candidates.
For example:
testing
-------
source 1
bin 1 arch1
bin 1 arch2
unstable
--------
source 2
bin 2 arch1
bin 1+b1 arch2
The binary migration on arch2 should not be considered a candidate.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
Although this should never happen, rather than crashing if one of the
versions is none, simply indicate that they are unequal.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
Although this isn't an issue during normal runs, the excuses might be
built multiple times during a hint-tester run and should not accumulate
during the run.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
For those hints which don't cause an immediate run (i.e. other than
easy, hint and force-hint), re-build the excuses after adding the
hint so that the actions are accounted for in later hints.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
A binNMU does not rebuild architecture:all packages. For migrations via
unstable this is not a problem as the packages corresponding to the
source upload are still present. However, for *pu migrations, the set of
packages considered only includes architecture-specific packages. In
order to avoid installability issues with packages in testing which
depend on the arch:all packages, we leave the existing arch:all packages
in testing and only consider the arch-specific packages for migration.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
The test only needs to consider whether any binaries exist on a given
arch, not how many of them there are (or indeed which binaries they are)
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
When checking whether a tpu source has built on a particular arch, we
should only consider binaries produced by the latest version of the
source package in tpu.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
Originally when binNMUs for packages in testing were scheduled, the
binaries would be installed into tpu with no accompanying source. This
allowed the "removed binary" portions of should_upgrade_srcarch() to be
skipped (as britney had generated a faux source record).
dak now adds the source package to tpu in such cases which lead to the
"removed binary" checks being applied to binNMUs in tpu with potentially
destructive consequences. For example, if a package with amd64 and i386
binaries in testing were binNMUed on just amd64, britney would notice
that there were no i386 binaries in tpu and subsequently remove the i386
binaries from testing as well.
In order to resolve this, we skip the check for removed binaries when
building excuses for a binary-only migration via *pu.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
The primary difference between the parsing / output of excuses for *pu
and unstable unblocks is the messages displayed. We can therefore remove
some duplication by having the same code handle both, outputting the
appropriate message.
Where a *pu package is also the subject of a "block" (most likely during
a freeze) we only supply the "needs approval" or "approved" message;
previously both "needs approval" and "not touching due to block" were
output, which is redundant. We ensure that there is always a dummy
"block" hint for *pu packages to provide the "needs approval" behaviour.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
An "approve" hint is effectively an unblock for tpu packages and britney
is already quiite happy to parse "unblock $pkg/$tpuversion".
We allow the old name to be used for compatibility and replace it with
"unblock" internally.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
A dependency on an arch-specific package which is not a valid candidate
should lead to the depending package not being a candidate.
For now we ensure that the generated excuses output remains the same,
so that we don't have to wait for consumers to adapt to a new format.
Changing the output format should be revisited at a later point.
See Debian bug #693068.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
The code using the variables was refactored in 694d614b. As a result
they were still set in iter_packages() but never subsequently used.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
Previously a package which became obsolete during a run would not be
automatically removed until the next run. This was due to the fact that
sources[][BINARIES] is not updated during the run. Instead, we build a
list of source packages which produce at least one binary and then
remove any packages not in that list.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
"not force and not earlyabort" simplifies to "not earlyabort" rather
than "not force", as an easy hint would set "earlyabort" but not
"force".
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
All callers of get_reverse_tree compute the same modification of its
return value, so move that computation into get_reverse_tree.
Signed-off-by: Niels Thykier <niels@thykier.net>
When processing a hint of the form "easy pkgX libX" where libX would be
a candidate for smooth updates because pkgX/testing depends on it but
pkgX/unstable does not, and there are no other reverse dependencies,
the old binary from libX can simply be dropped straight away.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
The only test currently implemented is to ensure that any prospective
hint contains at least one item beyond the hint name. This prevents
lines in a hint file consisting simply of e.g. "easy" being added to
the hint list and causing later processing to abort with an error.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
This causes Multi-arch dependencies like "pkg:i386" to show up as
unsatisfiable in excuses.
Previously, the dependency would be checked on the wrong architecture
(if available) and cause the package to become a valid candidate. The
package would still be prevent from migrating as the installability
checker does not know of the "pkg:i386" package.
Signed-off-by: Niels Thykier <niels@thykier.net>
In the unsat_deps case, it was used to update a field in the excuse,
but the field was never read anywhere.
Signed-off-by: Niels Thykier <niels@thykier.net>
Use the is_valid in "html"-method to determine whether to write "Valid
candidate" or not. This avoids the occasional:
* Valid candidate
* Invalidated by dependency
* Not considered
Signed-off-by: Niels Thykier <niels@thykier.net>
generate_package_list had the unintended side-effect of regenerating
self.excuses (up top of the original excuses).
Signed-off-by: Niels Thykier <niels@thykier.net>
Presumably there once was a reason for having a notion of "depth",
but these days only 3 "values" were given as "maxdepth":
* "easy" (for easy hint)
* 0 (for "main run" or in a "hint"-hint)
* -1 (for force-hint)
Signed-off-by: Niels Thykier <niels@thykier.net>
This allows britney to load a python2.7 variant of the C module when
run under python2.7.
Note for python3, we add "python3" rather than "python3.Y". This is
to reflect the include path in the python3 package in the archive.
Signed-off-by: Niels Thykier <niels@thykier.net>
"affected" is not allowed to contain duplicates. Since the current
method of removing any such duplicates is
affected = list(set(affected))
then the order of affected is not important.
As a side effect, make get_reverse_tree return a set instead of a
list as its return value is always inserted into affected.
Signed-off-by: Niels Thykier <niels@thykier.net>
Features like the auto-hinter, smooth-upgrades and removal of obsolete
source packages are now unconditionally enabled.
Signed-off-by: Niels Thykier <niels@thykier.net>
An "obsolete source" is one which produces no binaries. This situation
generally arises when all of the binaries which used to be produced by
the source package are now built by other sources.
Sooner or later such sources will probably be auto-crufted from unstable,
but there's no real reason to keep them in testing in the meantime.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
The initial packages of a hint are HintItems, whereas other packages
considered whilst processing the hint will be MigrationItems. In
either case, the version information is irrelevant during the output
of hint processing and only displaying it for some items is confusing
and distracting. Therefore, whilst processing a hint we always use
unversioned names.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
Remove unused "excluded" argument from get_dependency_solvers and
excuse_unsat_deps. The argument was either always default or an empty
list.
Signed-off-by: Niels Thykier <niels@thykier.net>
Simply updating the include in britney-py.c, rebuilding and changing
the shebang of britney.py appears to be enough to make the switch in my
tests, so we just do that for now at least.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
If a hint item references unstable but its version is not correct for
that suite, we compare the version to the (t)pu version (if any) and
if a match is found update the item as if it had been explicitly
specified as applying to that suite originally.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
The feature is used to remove binaries left by smooth-updates and is not
exposed as an available hint type.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
Commit 94071b1649 excluded intra-source
dependencies from the determination as to whether a binary package was
eligible for smooth updates. Whilst this works in many cases, there
are situations where it breaks migration. For instance:
foo depends on libdropped1
libdropped1 depends on libdropped2
libdropped1 and libdropped2 are built from the same source; foo from
another source
libdropped2 is otherwise leaf in testing
In order to resolve this, we build a list of all packages which might
be eligible and filter out those which have reverse-dependencies outside
of their source package. For each remaining package, we consider it
eligible if its intra-source reverse-dependencies are within the list
of packages already determined to be eligible.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
The minimal set is comprised of only the first level of (reverse)
dependencies, before any further iterations of packages are added to
the set. In some cases, the result of the full iteration will contain
packages which cause problems when migrated but the minimal set,
although possibly a less optimal solution, may be able to migrate
successfully.
It is assumed that migrating the larger set of packages will be
preferred if possible, so minimal sets are tried later.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
The minimal set is comprised of only the first level of (reverse)
dependencies, before any further iterations of packages are added to
the set. In some cases, the result of the full iteration will contain
packages which cause problems when migrated but the minimal set,
although possibly a less optimal solution, may be able to migrate
successfully.
It is assumed that migrating the larger set of packages will be
preferred if possible, so minimal sets are tried later.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
In order to make a number of the changes required for the migration simpler,
we also complete the previous migration to using {Hint,Migration}Item rather
than passing around strings representing packages and converting between
the two forms in several places.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
The use of MigrationItem allows us to centralise the parsing and splitting of
package names and architectures, avoiding duplication and simplifying a
number of conditions.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
Rather than only considering pairs of packages, we start from a "leaf"
package (i.e. one with an excuse which declares no dependencies on
other packages' excuses) and recursively build a list of packages
which are the dependency or reverse dependency of a package already
in the list.
Any list which is a subset of another list is ignored and the remaining
items are then processed as "easy" hints.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
Previously we could not reliably detect whether an excuse's dependency
from a source package to a binNMU was valid, as the excuse did not
contain sufficient information to determine the set of architecture(s)
on which the dependency existed.
By modifying the representation of the dependency list in the excuse to
include an architecture list we can walk the relationships in reverse
in order to sanity-check the source -> binNMU dependency.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
When considering an excuse for pkg1/arch, a dependency on either of
pkg2/source or pkg2/arch should be considered acceptable so long
as there is a corresponding excuse.
Dependencies from pkg1/source to pkg2/arch will still be considered
"impossible", as pkg1's excuse does not contain any information
regarding the architecture(s) on which its dependency to pkg2 exists.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
This allows the consideration of packages from proposed-updates to be
{dis,en}abled depending on whether the configuration file specifies
the path to the packages / sources files.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
This is most likely to be useful near the beginning of a release cycle,
when the versions of a package in stable and testing are the same and
the new version of the package is unable to migrate from unstable for
some reason.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
The permissions issues which led to the writing being disabled no longer
exist and not persisting the date list makes b2 unsuitable for use as a
primary implementation.
If a binary package being processed as part of a hint has moved source
packages, the installability checks for the new version of the binary
need to include the reverse-dependency information from the previous
version. In order to allow this, modify doop_source() to take an
optional list of undo information and iter_packages() to pass such
a list when processing hints.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
This reduces the number of ways in which we refer to uninstallable packages
to two. Those should probably be unified further to be consistent across
all parts of the code, but in the meantime this ensures that methods are
internally consistent in their terminology.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
The bug data has contained lists of bugs rather than simple counts for some
time now. Update the log messages to reflect this reality.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>
When undoing the removal of a binary package by an "easy" hint, ensure
that the apt system is updated with the correct version of the package.
Signed-off-by: Adam D. Barratt <adam@adam-barratt.org.uk>