summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/algorithms.cc20
-rw-r--r--apt-pkg/algorithms.h2
-rw-r--r--apt-pkg/cachefilter-patterns.cc4
-rw-r--r--apt-pkg/cachefilter-patterns.h19
-rw-r--r--apt-pkg/cacheiterators.h1
-rw-r--r--apt-pkg/depcache.cc55
-rw-r--r--apt-pkg/depcache.h6
-rw-r--r--apt-pkg/pkgcache.cc25
-rw-r--r--apt-pkg/upgrade.cc118
9 files changed, 140 insertions, 110 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();