From 3ddac110c61cc5bf354ad8b0f0db3347b8588b4b Mon Sep 17 00:00:00 2001 From: Iain Lane Date: Tue, 23 Feb 2021 11:53:50 +0000 Subject: [PATCH] suiteloader: Handle arch-all packages properly when merging binaries In 'partial source' mode, which we use in Ubuntu, we merge the target (release pocket) with the source (proposed), so that proposed-migration has a view of the complete state of the archive when it is migrating. This merging must not be done when a package has been built in the source suite. If it is done incorrectly, proposed-migration will see the previous binary packages as existing when they should not. We have code to handle this already, but it's wrong in the case of arch:all binaries. This comes up in two ways - If a source package builds *only* arch:all binaries, it is not expected that builds will be created on arches other than the one which builds arch:all packages (amd64 currently). If that is built then the package is complete, we shouldn't merge any old binaries such as dropped arch:all ones from the target. - Relatedly, if other non-arch-all packages exist, an arch:all package isn't an indication that a build has taken place on other arches than the all buildd arch. Fixing both of these stops old binaries being merged into a new source when it's been built and arch:all packages are involved. --- britney2/inputs/suiteloader.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/britney2/inputs/suiteloader.py b/britney2/inputs/suiteloader.py index 0208ecc..4a2d635 100644 --- a/britney2/inputs/suiteloader.py +++ b/britney2/inputs/suiteloader.py @@ -244,6 +244,10 @@ class DebMirrorLikeSuiteContentLoader(SuiteContentLoader): source_binaries = source.binaries source_provides = source.provides_table oodsrcs = defaultdict(set) + try: + all_buildarch = self._base_config.all_buildarch + except AttributeError: + all_buildarch = None def _merge_binaries_arch(arch): for pkg, value in target_binaries[arch].items(): @@ -260,13 +264,30 @@ class DebMirrorLikeSuiteContentLoader(SuiteContentLoader): self.logger.info("merge_binaries: pkg %s has no source, NBS?" % pkg) continue if target_version != source_version: + arches_built = set([source_binaries[b.architecture][b.package_name].architecture + for b in source_sources[value.source].binaries + if b.architecture in (arch, all_buildarch)]) + only_builds_arch_all = arches_built == set(['all']) + # If we only build arch:all packages in the source suite, + # it will look like the package is unbuilt on the arches + # other than the all buildarch. But we don't expect a build + # there, so don't merge binaries from the target. If we + # were to, it would look like any dropped non-arch-all + # binaries had gone missing. + if only_builds_arch_all and arch != all_buildarch: + continue + current_arch = value.architecture built = False for b in source_sources[value.source].binaries: if b.architecture == arch: source_value = source_binaries[arch][b.package_name] + # arch:all packages show up in all Packages + # files, but they are only indicative of a + # build on the all_buildarch. if current_arch in ( - source_value.architecture, 'all'): + source_value.architecture, 'all') or \ + (source_value.architecture == 'all' and arch == all_buildarch): built = True break if built: