From 119a8d0ed19a4e946591b9aef7d662e14ca7ece5 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 8 Jul 2022 13:34:22 +0200 Subject: Upgrade all binaries in a source package Schedule all other binaries in the source package for upgrade if the candidate version belongs to the same source version as the package we are upgrading. This will significantly reduce the risk of partial upgrades and should make life a lot easier. --- apt-pkg/depcache.cc | 27 +++++++++++++++++++++++++++ test/integration/test-ubuntu-bug-614993 | 16 +++++++++------- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 82b2fda99..f1ad7729e 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1494,6 +1494,31 @@ static bool MarkInstall_UpgradeOrRemoveConflicts(pkgDepCache &Cache, bool const return not failedToRemoveSomething; } /*}}}*/ +static bool MarkInstall_UpgradeOtherBinaries(pkgDepCache &Cache, bool const DebugAutoInstall, unsigned long Depth, bool const ForceImportantDeps, pkgCache::PkgIterator Pkg, pkgCache::VerIterator Ver) /*{{{*/ +{ + auto SrcGrp = Cache.FindGrp(Ver.SourcePkgName()); + for (auto OtherBinary = SrcGrp.VersionsInSource(); not OtherBinary.end(); OtherBinary = OtherBinary.NextInSource()) + { + auto OtherPkg = OtherBinary.ParentPkg(); + auto OtherState = Cache[OtherPkg]; + if (OtherPkg == Pkg) + continue; + // Package is not installed or at right version, don't need to upgrade + if (OtherPkg->CurrentVer == 0 || OtherPkg.CurrentVer() == OtherBinary) + continue; + // Package is to be installed at right version, don't need to upgrade + if (OtherState.Install() && OtherState.InstallVer == OtherBinary) + continue; + // Package has a different source version than us, so it's not relevant + if (strcmp(OtherBinary.SourceVerStr(), Ver.SourceVerStr()) != 0 || OtherState.CandidateVer != OtherBinary) + continue; + if (DebugAutoInstall) + std::clog << OutputInDepth(Depth) << "Upgrading " << APT::PrettyPkg(&Cache, OtherPkg) << " due to " << Pkg.FullName() << '\n'; + Cache.MarkInstall(OtherPkg, true, Depth + 1, false, ForceImportantDeps); + } + return true; +} + /*}}}*/ static bool MarkInstall_InstallDependencies(pkgDepCache &Cache, bool const DebugAutoInstall, bool const DebugMarker, pkgCache::PkgIterator const &Pkg, unsigned long Depth, bool const ForceImportantDeps, std::vector &toInstall, APT::PackageVector *const toMoveAuto, bool const propagateProtected, bool const FromUser) /*{{{*/ { auto const IsSatisfiedByInstalled = [&](auto &D) { return (Cache[pkgCache::DepIterator{Cache, &D}] & pkgDepCache::DepInstall) == pkgDepCache::DepInstall; }; @@ -1705,6 +1730,8 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg, bool AutoInst, operator bool() noexcept { return already; } } propagateProtected{PkgState[Pkg->ID]}; + if (not MarkInstall_UpgradeOtherBinaries(*this, DebugAutoInstall, Depth, ForceImportantDeps, Pkg, P.CandidateVerIter(*this))) + return false; if (not MarkInstall_UpgradeOrRemoveConflicts(*this, DebugAutoInstall, Depth, ForceImportantDeps, toUpgrade, propagateProtected, FromUser)) { if (failEarly) diff --git a/test/integration/test-ubuntu-bug-614993 b/test/integration/test-ubuntu-bug-614993 index e7357bc67..542e55105 100755 --- a/test/integration/test-ubuntu-bug-614993 +++ b/test/integration/test-ubuntu-bug-614993 @@ -11,8 +11,9 @@ setupaptarchive UPGRADE="Reading package lists... Building dependency tree... The following additional packages will be installed: - libdrm-intel1 libdrm-nouveau1 libmtdev1 libutouch-grail1 libx11-xcb1 - libxcb-aux0 libxcb-dri2-0 libxfont1 xserver-common xserver-xorg-core + libdrm-intel1 libdrm-nouveau1 libdrm-radeon1 libdrm2 libmtdev1 + libutouch-grail1 libx11-xcb1 libxcb-aux0 libxcb-dri2-0 libxfont1 + xserver-common xserver-xorg-core xserver-xorg-input-all xserver-xorg-input-evdev xserver-xorg-input-mouse xserver-xorg-input-synaptics xserver-xorg-input-vmmouse xserver-xorg-input-wacom xserver-xorg-video-all xserver-xorg-video-apm @@ -36,8 +37,9 @@ The following packages will be REMOVED: The following NEW packages will be installed: libmtdev1 libutouch-grail1 libx11-xcb1 libxcb-aux0 libxcb-dri2-0 The following packages will be upgraded: - libdrm-intel1 libdrm-nouveau1 libxfont1 xserver-common xserver-xorg - xserver-xorg-core xserver-xorg-input-evdev xserver-xorg-input-mouse + libdrm-intel1 libdrm-nouveau1 libdrm-radeon1 libdrm2 libxfont1 + xserver-common xserver-xorg xserver-xorg-core xserver-xorg-input-all + xserver-xorg-input-evdev xserver-xorg-input-mouse xserver-xorg-input-synaptics xserver-xorg-input-vmmouse xserver-xorg-input-wacom xserver-xorg-video-all xserver-xorg-video-apm xserver-xorg-video-ark xserver-xorg-video-ati xserver-xorg-video-chips @@ -51,9 +53,9 @@ The following packages will be upgraded: xserver-xorg-video-sisusb xserver-xorg-video-tdfx xserver-xorg-video-trident xserver-xorg-video-tseng xserver-xorg-video-vesa xserver-xorg-video-vmware xserver-xorg-video-voodoo -41 upgraded, 5 newly installed, 1 to remove and 3 not upgraded. -Need to get 0 B/5505 kB of archives. -After this operation, 2294 kB disk space will be freed. +44 upgraded, 5 newly installed, 1 to remove and 0 not upgraded. +Need to get 0 B/5561 kB of archives. +After this operation, 3027 kB disk space will be freed. E: Trivial Only specified but this is not a trivial operation." testfailureequal "$UPGRADE" aptget install xserver-xorg --trivial-only -- cgit v1.2.3-70-g09d2 From c4bab3c93567fd5a17652e453d4a65d7c83eb4fb Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Fri, 8 Jul 2022 14:07:45 +0200 Subject: Avoid recursion by looping of other binaries twice First mark them for upgrade without autoInst, so we don't call their "mark other binaries loop"; then call them again with it. Without this change, each binary package would upgrade the next one in the list, recursively. --- apt-pkg/depcache.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index f1ad7729e..6aa1fe946 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1496,6 +1496,7 @@ static bool MarkInstall_UpgradeOrRemoveConflicts(pkgDepCache &Cache, bool const /*}}}*/ static bool MarkInstall_UpgradeOtherBinaries(pkgDepCache &Cache, bool const DebugAutoInstall, unsigned long Depth, bool const ForceImportantDeps, pkgCache::PkgIterator Pkg, pkgCache::VerIterator Ver) /*{{{*/ { + APT::PackageSet toUpgrade; auto SrcGrp = Cache.FindGrp(Ver.SourcePkgName()); for (auto OtherBinary = SrcGrp.VersionsInSource(); not OtherBinary.end(); OtherBinary = OtherBinary.NextInSource()) { @@ -1514,8 +1515,13 @@ static bool MarkInstall_UpgradeOtherBinaries(pkgDepCache &Cache, bool const Debu continue; if (DebugAutoInstall) std::clog << OutputInDepth(Depth) << "Upgrading " << APT::PrettyPkg(&Cache, OtherPkg) << " due to " << Pkg.FullName() << '\n'; - Cache.MarkInstall(OtherPkg, true, Depth + 1, false, ForceImportantDeps); + + toUpgrade.insert(OtherPkg); } + for (auto &OtherPkg : toUpgrade) + Cache.MarkInstall(OtherPkg, false, Depth + 1, false, ForceImportantDeps); + for (auto &OtherPkg : toUpgrade) + Cache.MarkInstall(OtherPkg, true, Depth + 1, false, ForceImportantDeps); return true; } /*}}}*/ -- cgit v1.2.3-70-g09d2 From 518746f7e03115eb7bdf894d23e74ae115c8717b Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 24 Jul 2022 15:44:13 +0200 Subject: Add flag to disable upgrade by source and test case --- apt-pkg/depcache.cc | 4 ++ doc/examples/configure-index | 1 + test/integration/test-apt-get-upgrade-by-source | 53 +++++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100755 test/integration/test-apt-get-upgrade-by-source diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 6aa1fe946..bc5843153 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1497,6 +1497,10 @@ static bool MarkInstall_UpgradeOrRemoveConflicts(pkgDepCache &Cache, bool const static bool MarkInstall_UpgradeOtherBinaries(pkgDepCache &Cache, bool const DebugAutoInstall, unsigned long Depth, bool const ForceImportantDeps, pkgCache::PkgIterator Pkg, pkgCache::VerIterator Ver) /*{{{*/ { APT::PackageSet toUpgrade; + + if (not _config->FindB("APT::Get::Upgrade-By-Source-Package", true)) + return true; + auto SrcGrp = Cache.FindGrp(Ver.SourcePkgName()); for (auto OtherBinary = SrcGrp.VersionsInSource(); not OtherBinary.end(); OtherBinary = OtherBinary.NextInSource()) { diff --git a/doc/examples/configure-index b/doc/examples/configure-index index 07feea4dc..b3deccaaf 100644 --- a/doc/examples/configure-index +++ b/doc/examples/configure-index @@ -103,6 +103,7 @@ APT Upgrade ""; Only-Upgrade ""; Upgrade-Allow-New ""; + Upgrade-By-Source-Package ""; Always-Include-Phased-Updates ""; Never-Include-Phased-Updates ""; Phase-Policy ""; // internal diff --git a/test/integration/test-apt-get-upgrade-by-source b/test/integration/test-apt-get-upgrade-by-source new file mode 100755 index 000000000..0f87005d3 --- /dev/null +++ b/test/integration/test-apt-get-upgrade-by-source @@ -0,0 +1,53 @@ +#!/bin/sh +set -e + +TESTDIR="$(readlink -f "$(dirname "$0")")" +. "$TESTDIR/framework" + +setupenvironment + +insertinstalledpackage 'pkg' 'all' '1' 'Source: pkg' +insertinstalledpackage 'pkg-foo' 'all' '1' 'Source: pkg' +insertinstalledpackage 'pkg-bar' 'all' '1' 'Source: pkg' +insertpackage 'unstable' 'pkg' 'all' '2' 'Source: pkg' +insertpackage 'unstable' 'pkg-foo' 'all' '2' 'Source: pkg' +insertpackage 'unstable' 'pkg-bar' 'all' '2' 'Source: pkg' + +configarchitecture 'arm64' +setupaptarchive + +noprogress() { + "$@" | sed /^Progress/d +} + +testsuccessequal "Reading package lists... +Building dependency tree... + MarkInstall pkg:arm64 < 1 -> 2 @ii puU > FU=1 + Upgrading pkg-bar:arm64 < 1 | 2 @ii uH > due to pkg:arm64 + Upgrading pkg-foo:arm64 < 1 | 2 @ii uH > due to pkg:arm64 +Starting pkgProblemResolver with broken count: 0 +Starting 2 pkgProblemResolver with broken count: 0 +Done +The following additional packages will be installed: + pkg-bar pkg-foo +The following packages will be upgraded: + pkg pkg-bar pkg-foo +3 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Inst pkg [1] (2 unstable [all]) +Inst pkg-bar [1] (2 unstable [all]) +Inst pkg-foo [1] (2 unstable [all]) +Conf pkg (2 unstable [all]) +Conf pkg-bar (2 unstable [all]) +Conf pkg-foo (2 unstable [all])" aptget install pkg -o debug::pkgdepcache::marker=1 -o Debug::pkgProblemResolver=1 -o Debug::pkgDepCache::AutoInstall=1 -s + +testsuccessequal "Reading package lists... +Building dependency tree... + MarkInstall pkg:arm64 < 1 -> 2 @ii puU > FU=1 +Starting pkgProblemResolver with broken count: 0 +Starting 2 pkgProblemResolver with broken count: 0 +Done +The following packages will be upgraded: + pkg +1 upgraded, 0 newly installed, 0 to remove and 2 not upgraded. +Inst pkg [1] (2 unstable [all]) +Conf pkg (2 unstable [all])" aptget install pkg -o debug::pkgdepcache::marker=1 -o Debug::pkgProblemResolver=1 -o Debug::pkgDepCache::AutoInstall=1 -o APT::Get::Upgrade-By-Source-Package=0 -s -- cgit v1.2.3-70-g09d2 From c28fc7366c6645cb6d1010a44ce494b5ae1b9a9f Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Sun, 24 Jul 2022 16:28:53 +0200 Subject: Add NEWS entry --- debian/NEWS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/debian/NEWS b/debian/NEWS index 382a6df9c..a5607e94d 100644 --- a/debian/NEWS +++ b/debian/NEWS @@ -1,3 +1,11 @@ +apt (2.5.2) UNRELEASED; urgency=medium + + Installing or upgrading a binary package now upgrades other binaries from + the same source package if they have the same candidate version. You can + disable this by setting `APT::Get::Upgrade-By-Source-Package` to `false`. + + -- Julian Andres Klode Sun, 24 Jul 2022 15:45:15 +0200 + apt (2.4.0) unstable; urgency=medium GPG verification now first tries only the trusted.gpg.d keys, before -- cgit v1.2.3-70-g09d2