diff options
-rw-r--r-- | apt-pkg/algorithms.cc | 20 | ||||
-rw-r--r-- | apt-pkg/algorithms.h | 2 | ||||
-rw-r--r-- | apt-pkg/cachefilter-patterns.cc | 4 | ||||
-rw-r--r-- | apt-pkg/cachefilter-patterns.h | 19 | ||||
-rw-r--r-- | apt-pkg/cacheiterators.h | 1 | ||||
-rw-r--r-- | apt-pkg/depcache.cc | 55 | ||||
-rw-r--r-- | apt-pkg/depcache.h | 6 | ||||
-rw-r--r-- | apt-pkg/pkgcache.cc | 25 | ||||
-rw-r--r-- | apt-pkg/upgrade.cc | 118 | ||||
-rw-r--r-- | apt-private/private-install.cc | 17 | ||||
-rw-r--r-- | apt-private/private-output.cc | 10 | ||||
-rw-r--r-- | apt-private/private-output.h | 1 | ||||
-rw-r--r-- | debian/libapt-pkg6.0.symbols | 4 | ||||
-rw-r--r-- | doc/apt-patterns.7.xml | 6 | ||||
-rwxr-xr-x | test/integration/test-phased-updates-new-depends | 6 | ||||
-rwxr-xr-x | test/integration/test-phased-updates-upgrade | 51 | ||||
-rwxr-xr-x | test/integration/test-ubuntu-bug-2025462-phased-dist-upgrade | 4 |
17 files changed, 227 insertions, 122 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 3d4096a94..d841d6dd8 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -1246,6 +1246,26 @@ bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I) return false; } /*}}}*/ +// ProblemResolver::KeepPhasedUpdates - Keep back phased updates /*{{{*/ +// --------------------------------------------------------------------- +// Hold back upgrades to phased versions of already installed packages, unless +// they are security updates +bool pkgProblemResolver::KeepPhasedUpdates() +{ + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + { + if (not Cache.PhasingApplied(I)) + continue; + + Cache.MarkKeep(I, false, false); + Cache.MarkProtected(I); + Protect(I); + } + + return true; +} + + /*}}}*/ // ProblemResolver::ResolveByKeep - Resolve problems using keep /*{{{*/ // --------------------------------------------------------------------- /* This is the work horse of the soft upgrade routine. It is very gentle diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index f06a38c1b..558beecd3 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -140,6 +140,8 @@ class APT_PUBLIC pkgProblemResolver /*{{{*/ inline void AllowBrokenPolicy(pkgCache::PkgIterator Pkg) { Flags[Pkg->ID] |= BrokenPolicyAllowed; }; #endif + bool KeepPhasedUpdates(); + // Try to intelligently resolve problems by installing and removing packages bool Resolve(bool BrokenFix = false, OpProgress * const Progress = NULL); APT_HIDDEN bool ResolveInternal(bool const BrokenFix = false); diff --git a/apt-pkg/cachefilter-patterns.cc b/apt-pkg/cachefilter-patterns.cc index faf5735b8..7e6d84ff6 100644 --- a/apt-pkg/cachefilter-patterns.cc +++ b/apt-pkg/cachefilter-patterns.cc @@ -498,8 +498,12 @@ std::unique_ptr<APT::CacheFilter::Matcher> PatternParser::aPattern(std::unique_p return std::make_unique<Patterns::PackageIsObsolete>(); if (node->matches("?origin", 1, 1)) return std::make_unique<Patterns::VersionIsOrigin>(aWord(node->arguments[0])); + if (node->matches("?phasing", 0, 0)) + return std::make_unique<Patterns::PackageIsPhasing>(file); if (node->matches("?section", 1, 1)) return std::make_unique<Patterns::VersionIsSection>(aWord(node->arguments[0])); + if (node->matches("?security", 0, 0)) + return std::make_unique<Patterns::VersionIsSecurity>(); if (node->matches("?source-package", 1, 1)) return std::make_unique<Patterns::VersionIsSourcePackage>(aWord(node->arguments[0])); if (node->matches("?source-version", 1, 1)) diff --git a/apt-pkg/cachefilter-patterns.h b/apt-pkg/cachefilter-patterns.h index 2d48a1cc9..fa4605253 100644 --- a/apt-pkg/cachefilter-patterns.h +++ b/apt-pkg/cachefilter-patterns.h @@ -243,6 +243,16 @@ struct APT_HIDDEN PackageIsObsolete : public PackageMatcher } }; +struct APT_HIDDEN PackageIsPhasing : public PackageMatcher +{ + pkgCacheFile *Cache; + explicit PackageIsPhasing(pkgCacheFile *Cache) : Cache(Cache) {} + bool operator()(pkgCache::PkgIterator const &pkg) override + { + return (*Cache)->PhasingApplied(pkg); + } +}; + struct APT_HIDDEN PackageIsUpgradable : public PackageMatcher { pkgCacheFile *Cache; @@ -405,6 +415,15 @@ struct APT_HIDDEN VersionIsSection : public VersionAnyMatcher } }; +struct APT_HIDDEN VersionIsSecurity : public VersionAnyMatcher +{ + VersionIsSecurity() {} + bool operator()(pkgCache::VerIterator const &Ver) override + { + return Ver.IsSecurityUpdate(); + } +}; + struct APT_HIDDEN VersionIsSourcePackage : public VersionAnyMatcher { BaseRegexMatcher matcher; diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 9273369bd..074973048 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -246,6 +246,7 @@ class APT_PUBLIC pkgCache::VerIterator : public Iterator<Version, VerIterator> { bool Automatic() const; VerFileIterator NewestFile() const; + bool IsSecurityUpdate() const; #ifdef APT_COMPILING_APT inline unsigned int PhasedUpdatePercentage() const diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 322bf1bbe..c965781a4 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -30,11 +30,12 @@ #include <algorithm> #include <iostream> -#include <memory> -#include <sstream> #include <iterator> #include <list> +#include <memory> +#include <random> #include <set> +#include <sstream> #include <string> #include <unordered_map> #include <utility> @@ -141,6 +142,7 @@ struct pkgDepCache::Private { std::unique_ptr<InRootSetFunc> inRootSetFunc; std::unique_ptr<APT::CacheFilter::Matcher> IsAVersionedKernelPackage, IsProtectedKernelPackage; + std::string machineID; }; pkgDepCache::pkgDepCache(pkgCache *const pCache, Policy *const Plcy) : group_level(0), Cache(pCache), PkgState(0), DepState(0), iUsrSize(0), iDownloadSize(0), iInstCount(0), iDelCount(0), iKeepCount(0), @@ -148,6 +150,7 @@ pkgDepCache::pkgDepCache(pkgCache *const pCache, Policy *const Plcy) : group_lev { DebugMarker = _config->FindB("Debug::pkgDepCache::Marker", false); DebugAutoInstall = _config->FindB("Debug::pkgDepCache::AutoInstall", false); + d->machineID = APT::Configuration::getMachineID(); delLocalPolicy = 0; LocalPolicy = Plcy; if (LocalPolicy == 0) @@ -2562,3 +2565,51 @@ bool pkgDepCache::MarkAndSweep() return false; } /*}}}*/ + +// DepCache::PhasingApplied /*{{{*/ +// Check if this version is a phased update that should be ignored, not considering whether +// it is a security update. +static bool IsIgnoredPhasedUpdate(std::string machineID, pkgCache::VerIterator const &Ver) +{ + if (_config->FindB("APT::Get::Phase-Policy", false)) + return false; + + // The order and fallbacks for the always/never checks come from update-manager and exist + // to preserve compatibility. + if (_config->FindB("APT::Get::Always-Include-Phased-Updates", + _config->FindB("Update-Manager::Always-Include-Phased-Updates", false))) + return false; + + if (_config->FindB("APT::Get::Never-Include-Phased-Updates", + _config->FindB("Update-Manager::Never-Include-Phased-Updates", false))) + return true; + + if (machineID.empty() // no machine-id + || getenv("SOURCE_DATE_EPOCH") != nullptr // reproducible build - always include + || APT::Configuration::isChroot()) + return false; + + std::string seedStr = std::string(Ver.SourcePkgName()) + "-" + Ver.SourceVerStr() + "-" + machineID; + std::seed_seq seed(seedStr.begin(), seedStr.end()); + std::minstd_rand rand(seed); + std::uniform_int_distribution<unsigned int> dist(0, 100); + + return dist(rand) > Ver.PhasedUpdatePercentage(); +} + +bool pkgDepCache::PhasingApplied(pkgCache::PkgIterator Pkg) const +{ + if (Pkg->CurrentVer == 0) + return false; + if ((*this)[Pkg].CandidateVer == 0) + return false; + if ((*this)[Pkg].CandidateVerIter(*Cache).PhasedUpdatePercentage() == 100) + return false; + if ((*this)[Pkg].CandidateVerIter(*Cache).IsSecurityUpdate()) + return false; + if (!IsIgnoredPhasedUpdate(d->machineID, (*this)[Pkg].CandidateVerIter(*Cache))) + return false; + + return true; +} + /*}}}*/ diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index be27b1d77..a850cf91a 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -381,6 +381,12 @@ class APT_PUBLIC pkgDepCache : protected pkgCache::Namespace bool MarkAndSweep(InRootSetFunc &rootFunc); bool MarkAndSweep(); + /** Check if the phased update is ready. + * + * \return \b false if this is a phased update that is not yet ready for us + */ + bool PhasingApplied(PkgIterator Pkg) const; + /** \name State Manipulators */ // @{ diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 76336b9b3..06689aa33 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -1017,5 +1017,30 @@ pkgCache::DescIterator pkgCache::VerIterator::TranslatedDescription() const } /*}}}*/ +// VerIterator::IsSecurity - check if it is a security update /*{{{*/ +// See if this version is a security update. This also checks, for installed packages, +// if any of the previous versions is a security update +bool pkgCache::VerIterator::IsSecurityUpdate() const +{ + auto Pkg = ParentPkg(); + auto Installed = Pkg.CurrentVer(); + + auto OtherVer = Pkg.VersionList(); + + // Advance to first version < our version + while (OtherVer->ID != S->ID) + ++OtherVer; + + // Iterate over all versions < our version + for (; !OtherVer.end() && (Installed.end() || OtherVer->ID != Installed->ID); OtherVer++) + { + for (auto PF = OtherVer.FileList(); !PF.end(); PF++) + if (PF.File() && PF.File().Archive() != nullptr && APT::String::Endswith(PF.File().Archive(), "-security")) + return true; + } + return false; +} + + /*}}}*/ pkgCache::~pkgCache() {} diff --git a/apt-pkg/upgrade.cc b/apt-pkg/upgrade.cc index c7e566a55..fad47838c 100644 --- a/apt-pkg/upgrade.cc +++ b/apt-pkg/upgrade.cc @@ -18,101 +18,6 @@ #include <apti18n.h> /*}}}*/ -struct PhasedUpgrader -{ - std::string machineID; - bool isChroot; - - PhasedUpgrader() - { - machineID = APT::Configuration::getMachineID(); - } - - // See if this version is a security update. This also checks, for installed packages, - // if any of the previous versions is a security update - bool IsSecurityUpdate(pkgCache::VerIterator const &Ver) - { - auto Pkg = Ver.ParentPkg(); - auto Installed = Pkg.CurrentVer(); - - auto OtherVer = Pkg.VersionList(); - - // Advance to first version < our version - while (OtherVer->ID != Ver->ID) - ++OtherVer; - - // Iterate over all versions < our version - for (; !OtherVer.end() && (Installed.end() || OtherVer->ID != Installed->ID); OtherVer++) - { - for (auto PF = OtherVer.FileList(); !PF.end(); PF++) - if (PF.File() && PF.File().Archive() != nullptr && APT::String::Endswith(PF.File().Archive(), "-security")) - return true; - } - return false; - } - - // Check if this version is a phased update that should be ignored - bool IsIgnoredPhasedUpdate(pkgCache::VerIterator const &Ver) - { - if (_config->FindB("APT::Get::Phase-Policy", false)) - return false; - - // The order and fallbacks for the always/never checks come from update-manager and exist - // to preserve compatibility. - if (_config->FindB("APT::Get::Always-Include-Phased-Updates", - _config->FindB("Update-Manager::Always-Include-Phased-Updates", false))) - return false; - - if (_config->FindB("APT::Get::Never-Include-Phased-Updates", - _config->FindB("Update-Manager::Never-Include-Phased-Updates", false))) - return true; - - if (machineID.empty() // no machine-id - || getenv("SOURCE_DATE_EPOCH") != nullptr // reproducible build - always include - || APT::Configuration::isChroot()) - return false; - - std::string seedStr = std::string(Ver.SourcePkgName()) + "-" + Ver.SourceVerStr() + "-" + machineID; - std::seed_seq seed(seedStr.begin(), seedStr.end()); - std::minstd_rand rand(seed); - std::uniform_int_distribution<unsigned int> dist(0, 100); - - return dist(rand) > Ver.PhasedUpdatePercentage(); - } - - bool ShouldKeep(pkgDepCache &Cache, pkgCache::PkgIterator Pkg) - { - if (Pkg->CurrentVer == 0) - return false; - if (Cache[Pkg].CandidateVer == 0) - return false; - if (Cache[Pkg].CandidateVerIter(Cache).PhasedUpdatePercentage() == 100) - return false; - if (IsSecurityUpdate(Cache[Pkg].CandidateVerIter(Cache))) - return false; - if (!IsIgnoredPhasedUpdate(Cache[Pkg].CandidateVerIter(Cache))) - return false; - - return true; - } - - // Hold back upgrades to phased versions of already installed packages, unless - // they are security updates - void HoldBackIgnoredPhasedUpdates(pkgDepCache &Cache, pkgProblemResolver *Fix) - { - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) - { - if (not ShouldKeep(Cache, I)) - continue; - - Cache.MarkKeep(I, false, false); - Cache.MarkProtected(I); - if (Fix != nullptr) - Fix->Protect(I); - } - } -}; - // DistUpgrade - Distribution upgrade /*{{{*/ // --------------------------------------------------------------------- /* This autoinstalls every package and then force installs every @@ -132,14 +37,13 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) Progress->OverallProgress(0, 100, 1, _("Calculating upgrade")); pkgDepCache::ActionGroup group(Cache); - PhasedUpgrader phasedUpgrader; /* Upgrade all installed packages first without autoinst to help the resolver in versioned or-groups to upgrade the old solver instead of installing a new one (if the old solver is not the first one [anymore]) */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { - if (phasedUpgrader.ShouldKeep(Cache, I)) + if (Cache.PhasingApplied(I)) continue; if (I->CurrentVer != 0) Cache.MarkInstall(I, false, 0, false); @@ -152,7 +56,7 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) for the installation */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { - if (phasedUpgrader.ShouldKeep(Cache, I)) + if (Cache.PhasingApplied(I)) continue; if (I->CurrentVer != 0) Cache.MarkInstall(I, true, 0, false); @@ -184,7 +88,7 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) if (isEssential == false || instEssential == true) continue; pkgCache::PkgIterator P = G.FindPreferredPkg(); - if (phasedUpgrader.ShouldKeep(Cache, P)) + if (Cache.PhasingApplied(P)) continue; Cache.MarkInstall(P, true, 0, false); } @@ -192,7 +96,7 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) else if (essential != "none") for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { - if (phasedUpgrader.ShouldKeep(Cache, I)) + if (Cache.PhasingApplied(I)) continue; if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) Cache.MarkInstall(I, true, 0, false); @@ -205,7 +109,7 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) conflict resolution on them all. */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { - if (phasedUpgrader.ShouldKeep(Cache, I)) + if (Cache.PhasingApplied(I)) continue; if (I->CurrentVer != 0) Cache.MarkInstall(I, false, 0, false); @@ -245,7 +149,7 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) if (Cache[I].InstPolicyBroken()) FixPhasing.AllowBrokenPolicy(I); - PhasedUpgrader().HoldBackIgnoredPhasedUpdates(Cache, &FixPhasing); + FixPhasing.KeepPhasedUpdates(); success = FixPhasing.ResolveByKeepInternal(); } @@ -267,7 +171,6 @@ static bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache, OpProgress * const Pr pkgDepCache::ActionGroup group(Cache); pkgProblemResolver Fix(&Cache); - PhasedUpgrader phasedUpgrader; // Upgrade all installed packages for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { @@ -278,7 +181,7 @@ static bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache, OpProgress * const Pr if (I->SelectedState == pkgCache::State::Hold) continue; - if (phasedUpgrader.ShouldKeep(Cache, I)) + if (Cache.PhasingApplied(I)) continue; if (I->CurrentVer != 0 && Cache[I].InstallVer != 0) @@ -288,7 +191,7 @@ static bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache, OpProgress * const Pr if (Progress != NULL) Progress->Progress(50); - phasedUpgrader.HoldBackIgnoredPhasedUpdates(Cache, &Fix); + Fix.KeepPhasedUpdates(); // resolve remaining issues via keep bool const success = Fix.ResolveByKeepInternal(); @@ -316,7 +219,6 @@ static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache, OpProgress * const pkgDepCache::ActionGroup group(Cache); pkgProblemResolver Fix(&Cache); - PhasedUpgrader phasedUpgrader; // provide the initial set of stuff we want to upgrade by marking // all upgradable packages for upgrade @@ -327,7 +229,7 @@ static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache, OpProgress * const if (_config->FindB("APT::Ignore-Hold",false) == false) if (I->SelectedState == pkgCache::State::Hold) continue; - if (phasedUpgrader.ShouldKeep(Cache, I)) + if (Cache.PhasingApplied(I)) continue; Cache.MarkInstall(I, false, 0, false); @@ -353,7 +255,7 @@ static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache, OpProgress * const if (Progress != NULL) Progress->Progress(60); - phasedUpgrader.HoldBackIgnoredPhasedUpdates(Cache, &Fix); + Fix.KeepPhasedUpdates(); // resolve remaining issues via keep bool const success = Fix.ResolveByKeepInternal(); diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc index 2f254ca27..dbcba8fd1 100644 --- a/apt-private/private-install.cc +++ b/apt-private/private-install.cc @@ -210,11 +210,26 @@ bool InstallPackages(CacheFile &Cache, APT::PackageVector &HeldBackPackages, boo return false; } + APT::PackageVector PhasingPackages; + APT::PackageVector NotPhasingHeldBackPackages; + for (auto const &Pkg : HeldBackPackages) + { + if (Cache->PhasingApplied(Pkg)) + PhasingPackages.push_back(Pkg); + else + NotPhasingHeldBackPackages.push_back(Pkg); + } + // Show all the various warning indicators ShowDel(c1out,Cache); ShowNew(c1out,Cache); if (ShwKept == true) - ShowKept(c1out,Cache, HeldBackPackages); + { + ShowPhasing(c1out, Cache, PhasingPackages); + ShowKept(c1out, Cache, NotPhasingHeldBackPackages); + if (not PhasingPackages.empty() && not NotPhasingHeldBackPackages.empty()) + _error->Notice("Some packages may have been kept back due to phasing."); + } bool const Hold = not ShowHold(c1out,Cache); if (_config->FindB("APT::Get::Show-Upgraded",true) == true) ShowUpgraded(c1out,Cache); diff --git a/apt-private/private-output.cc b/apt-private/private-output.cc index 03fbe47e1..c73d5229b 100644 --- a/apt-private/private-output.cc +++ b/apt-private/private-output.cc @@ -490,6 +490,16 @@ void ShowDel(ostream &out,CacheFile &Cache) CandidateVersion(&Cache)); } /*}}}*/ +// ShowPhasing - Show packages kept due to phasing /*{{{*/ +void ShowPhasing(ostream &out, CacheFile &Cache, APT::PackageVector const &HeldBackPackages) +{ + SortedPackageUniverse Universe(Cache); + ShowList(out, _("The following upgrades have been deferred due to phasing:"), HeldBackPackages, + &AlwaysTrue, + &PrettyFullName, + CurrentToCandidateVersion(&Cache)); +} + /*}}}*/ // ShowKept - Show kept packages /*{{{*/ void ShowKept(ostream &out,CacheFile &Cache, APT::PackageVector const &HeldBackPackages) { diff --git a/apt-private/private-output.h b/apt-private/private-output.h index d6f25e1ec..c3e73d592 100644 --- a/apt-private/private-output.h +++ b/apt-private/private-output.h @@ -93,6 +93,7 @@ template<class Container, class PredicateC, class DisplayP, class DisplayV> bool void ShowNew(std::ostream &out,CacheFile &Cache); void ShowDel(std::ostream &out,CacheFile &Cache); void ShowKept(std::ostream &out,CacheFile &Cache, APT::PackageVector const &HeldBackPackages); +void ShowPhasing(std::ostream &out, CacheFile &Cache, APT::PackageVector const &HeldBackPackages); void ShowUpgraded(std::ostream &out,CacheFile &Cache); bool ShowDowngraded(std::ostream &out,CacheFile &Cache); bool ShowHold(std::ostream &out,CacheFile &Cache); diff --git a/debian/libapt-pkg6.0.symbols b/debian/libapt-pkg6.0.symbols index d297eb1c9..e12f98de7 100644 --- a/debian/libapt-pkg6.0.symbols +++ b/debian/libapt-pkg6.0.symbols @@ -1354,6 +1354,10 @@ libapt-pkg.so.6.0 libapt-pkg6.0 #MINVER# (c++)"vtable for pkgDirStream@APTPKG_6.0" 0.8.0 (c++)"vtable for debDebFile::ControlExtract@APTPKG_6.0" 0.8.0 (c++)"vtable for debDebFile::MemControlExtract@APTPKG_6.0" 0.8.0 +### phased update API + (c++)"pkgCache::VerIterator::IsSecurityUpdate() const@APTPKG_6.0" 2.7.11 + (c++)"pkgDepCache::PhasingApplied(pkgCache::PkgIterator) const@APTPKG_6.0" 2.7.11 + (c++)"pkgProblemResolver::KeepPhasedUpdates()@APTPKG_6.0" 2.7.11 ### gcc artifacts (c++|optional=std)"void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag)@APTPKG_6.0" 1.7.0~alpha3~ (c++|optional=std)"typeinfo for std::_Mutex_base<(__gnu_cxx::_Lock_policy)2>@APTPKG_6.0" 1.9.11~ diff --git a/doc/apt-patterns.7.xml b/doc/apt-patterns.7.xml index 6b3f91e96..e87fef23d 100644 --- a/doc/apt-patterns.7.xml +++ b/doc/apt-patterns.7.xml @@ -116,6 +116,9 @@ <varlistentry><term><code>?obsolete</code></term><term><code>~o</code></term> <listitem><para>Selects packages that no longer exist in repositories.</para></listitem> </varlistentry> + <varlistentry><term><code>?phasing</code></term> + <listitem><para>Selects packages that will be kept back in upgrades due to phasing.</para></listitem> + </varlistentry> <varlistentry><term><code>?upgradable</code></term><term><code>~U</code></term> <listitem><para>Selects packages that can be upgraded (have a newer candidate).</para></listitem> </varlistentry> @@ -159,6 +162,9 @@ <varlistentry><term><code>?priority(NAME)</code></term><term><code>~pNAME</code></term> <listitem><para>Selects versions where the Priority string equals the given name.</para></listitem> </varlistentry> + <varlistentry><term><code>?security</code></term> + <listitem><para>Selects packages that are a security update or succeed a security update.</para></listitem> + </varlistentry> </variablelist> </refsect1> diff --git a/test/integration/test-phased-updates-new-depends b/test/integration/test-phased-updates-new-depends index 8cc9314ad..5d6ac80d8 100755 --- a/test/integration/test-phased-updates-new-depends +++ b/test/integration/test-phased-updates-new-depends @@ -35,7 +35,7 @@ The following packages have been kept back: testsuccessequal "Reading package lists... Building dependency tree... Calculating upgrade... -The following packages have been kept back: +The following upgrades have been deferred due to phasing: has-new-conflicts has-new-depends has-new-recommends 0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded." aptget upgrade -s -q @@ -62,7 +62,7 @@ Conf new-recommends (2 unstable-updates [all])" aptget upgrade -s -q --with-new- testsuccessequal "Reading package lists... Building dependency tree... Calculating upgrade... -The following packages have been kept back: +The following upgrades have been deferred due to phasing: has-new-conflicts has-new-depends has-new-recommends 0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded." aptget upgrade -s -q --with-new-pkgs @@ -91,6 +91,6 @@ Conf new-recommends (2 unstable-updates [all])" aptget dist-upgrade -s -q -o APT testsuccessequal "Reading package lists... Building dependency tree... Calculating upgrade... -The following packages have been kept back: +The following upgrades have been deferred due to phasing: has-new-conflicts has-new-depends has-new-recommends 0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded." aptget dist-upgrade -s -q diff --git a/test/integration/test-phased-updates-upgrade b/test/integration/test-phased-updates-upgrade index 2f5327f05..4f415f22e 100755 --- a/test/integration/test-phased-updates-upgrade +++ b/test/integration/test-phased-updates-upgrade @@ -53,8 +53,10 @@ Building dependency tree... Calculating upgrade... The following NEW packages will be installed: phased-new +The following upgrades have been deferred due to phasing: + phased phased-dep phased-depends-ready-dep The following packages have been kept back: - depends-phased-dep phased phased-dep phased-depends-ready-dep ready-dep + depends-phased-dep ready-dep The following packages will be upgraded: depends-phased-new phased-security phased-security-same 3 upgraded, 1 newly installed, 0 to remove and 5 not upgraded. @@ -67,6 +69,32 @@ Conf depends-phased-new (3 unstable-updates [all]) Conf phased-security (3 unstable-updates [all]) Conf phased-security-same (3 unstable-security, unstable-updates [all])" aptget dist-upgrade -s -q +testequal "Reading package lists... +Building dependency tree... +Calculating upgrade... +The following NEW packages will be installed: + phased-new +The following upgrades have been deferred due to phasing: + phased phased-dep phased-depends-ready-dep +The following packages have been kept back: + depends-phased-dep ready-dep +The following packages will be upgraded: + depends-phased-new phased-security phased-security-same +3 upgraded, 1 newly installed, 0 to remove and 5 not upgraded. +Need to get 0 B/168 B of archives. +After this operation, 43.0 kB of additional disk space will be used. +N: Some packages may have been kept back due to phasing. +Do you want to continue? [Y/n] Abort." apt dist-upgrade < /dev/null + +testsuccessequal "Listing... +phased-dep/unstable-updates 3 all [upgradable from: 1] +phased-depends-ready-dep/unstable-updates 3 all [upgradable from: 1] +phased/unstable-updates 3 all [upgradable from: 1]" apt list '?phasing' + +testsuccessequal "Listing... +phased-security-same/unstable-security,unstable-updates 3 all [upgradable from: 1] +phased-security/unstable-updates 3 all [upgradable from: 1]" apt list '?security' + for always in APT::Get::Always-Include-Phased-Updates Update-Manager::Always-Include-Phased-Updates; do testsuccessequal "Reading package lists... Building dependency tree... @@ -131,8 +159,10 @@ Building dependency tree... Calculating upgrade... The following NEW packages will be installed: phased-new +The following upgrades have been deferred due to phasing: + phased phased-dep phased-depends-ready-dep The following packages have been kept back: - depends-phased-dep phased phased-dep phased-depends-ready-dep ready-dep + depends-phased-dep ready-dep The following packages will be upgraded: depends-phased-new phased-security phased-security-same 3 upgraded, 1 newly installed, 0 to remove and 5 not upgraded. @@ -151,8 +181,10 @@ Building dependency tree... Calculating upgrade... The following NEW packages will be installed: phased-new +The following upgrades have been deferred due to phasing: + phased phased-dep phased-depends-ready-dep The following packages have been kept back: - depends-phased-dep phased phased-dep phased-depends-ready-dep ready-dep + depends-phased-dep ready-dep The following packages will be upgraded: depends-phased-new phased-security phased-security-same 3 upgraded, 1 newly installed, 0 to remove and 5 not upgraded. @@ -168,9 +200,10 @@ Conf phased-security-same (3 unstable-security, unstable-updates [all])" aptget testsuccessequal "Reading package lists... Building dependency tree... Calculating upgrade... +The following upgrades have been deferred due to phasing: + phased phased-dep phased-depends-ready-dep The following packages have been kept back: - depends-phased-dep depends-phased-new phased phased-dep - phased-depends-ready-dep ready-dep + depends-phased-dep depends-phased-new ready-dep The following packages will be upgraded: phased-security phased-security-same 2 upgraded, 0 newly installed, 0 to remove and 6 not upgraded. @@ -185,8 +218,10 @@ Building dependency tree... Calculating upgrade... The following NEW packages will be installed: phased-new +The following upgrades have been deferred due to phasing: + phased phased-depends-ready-dep The following packages have been kept back: - phased phased-depends-ready-dep ready-dep + ready-dep The following packages will be upgraded: depends-phased-dep depends-phased-new phased-dep phased-security phased-security-same @@ -208,8 +243,10 @@ done testsuccessequal "Reading package lists... Building dependency tree... Calculating upgrade... +The following upgrades have been deferred due to phasing: + phased phased-depends-ready-dep The following packages have been kept back: - depends-phased-new phased phased-depends-ready-dep ready-dep + depends-phased-new ready-dep The following packages will be upgraded: depends-phased-dep phased-dep phased-security phased-security-same 4 upgraded, 0 newly installed, 0 to remove and 4 not upgraded. diff --git a/test/integration/test-ubuntu-bug-2025462-phased-dist-upgrade b/test/integration/test-ubuntu-bug-2025462-phased-dist-upgrade index eecadcda3..567864230 100755 --- a/test/integration/test-ubuntu-bug-2025462-phased-dist-upgrade +++ b/test/integration/test-ubuntu-bug-2025462-phased-dist-upgrade @@ -32,8 +32,10 @@ setupaptarchive testsuccessequal "Reading package lists... Building dependency tree... Calculating upgrade... +The following upgrades have been deferred due to phasing: + mutter The following packages have been kept back: - gnome-shell gnome-shell-common mutter + gnome-shell gnome-shell-common 0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded." aptget dist-upgrade -s -q testsuccessequal "Reading package lists... |