diff options
| author | Julian Andres Klode <julian.klode@canonical.com> | 2023-07-07 14:24:52 +0200 |
|---|---|---|
| committer | Julian Andres Klode <julian.klode@canonical.com> | 2023-07-07 14:28:59 +0200 |
| commit | 68ef41ea912f4879b0ee43419c13a3a8c9bfcd22 (patch) | |
| tree | 87e0c3dd974b9003f8320db0fea93ce82c47f149 /apt-pkg | |
| parent | 89dd48bdea93849246fc33b447d6d7ad52bb1c4b (diff) | |
Do not mark updates for install that are still phasing
This fixes an issue where phased updates gain new dependencies
and cause them to be installed despite themselves not being
installed.
In the cause of investigation, it turned out that we also need
to evaluate the candidate version at those early stage rather
than the install version (which is only valid *after* MarkInstall).
This does not fully resolve the problem: If an update pulls in
a phased update, depends are still being installed. Resolving
this while ensuring that phased updates cannot uninstall packages
requires us to do a minimization of changes by trying to keep
back each new install removal and then seeing if any dependency
is being broken by it. This is more complex and will happen
later.
Diffstat (limited to 'apt-pkg')
| -rw-r--r-- | apt-pkg/upgrade.cc | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/apt-pkg/upgrade.cc b/apt-pkg/upgrade.cc index 3e1bb292b..994a05859 100644 --- a/apt-pkg/upgrade.cc +++ b/apt-pkg/upgrade.cc @@ -85,13 +85,13 @@ struct PhasedUpgrader { if (Pkg->CurrentVer == 0) return false; - if (Cache[Pkg].InstallVer == 0) + if (Cache[Pkg].CandidateVer == 0) return false; - if (Cache[Pkg].InstVerIter(Cache).PhasedUpdatePercentage() == 100) + if (Cache[Pkg].CandidateVerIter(Cache).PhasedUpdatePercentage() == 100) return false; - if (IsSecurityUpdate(Cache[Pkg].InstVerIter(Cache))) + if (IsSecurityUpdate(Cache[Pkg].CandidateVerIter(Cache))) return false; - if (!IsIgnoredPhasedUpdate(Cache[Pkg].InstVerIter(Cache))) + if (!IsIgnoredPhasedUpdate(Cache[Pkg].CandidateVerIter(Cache))) return false; return true; @@ -133,13 +133,18 @@ 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)) + continue; if (I->CurrentVer != 0) Cache.MarkInstall(I, false, 0, false); + } if (Progress != NULL) Progress->Progress(10); @@ -147,8 +152,12 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) /* Auto upgrade all installed packages, this provides the basis for the installation */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + { + if (phasedUpgrader.ShouldKeep(Cache, I)) + continue; if (I->CurrentVer != 0) Cache.MarkInstall(I, true, 0, false); + } if (Progress != NULL) Progress->Progress(50); @@ -176,13 +185,19 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) if (isEssential == false || instEssential == true) continue; pkgCache::PkgIterator P = G.FindPreferredPkg(); + if (phasedUpgrader.ShouldKeep(Cache, P)) + continue; Cache.MarkInstall(P, true, 0, false); } } else if (essential != "none") for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + { + if (phasedUpgrader.ShouldKeep(Cache, I)) + continue; if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) Cache.MarkInstall(I, true, 0, false); + } if (Progress != NULL) Progress->Progress(55); @@ -190,8 +205,12 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress) /* We do it again over all previously installed packages to force conflict resolution on them all. */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + { + if (phasedUpgrader.ShouldKeep(Cache, I)) + continue; if (I->CurrentVer != 0) Cache.MarkInstall(I, false, 0, false); + } if (Progress != NULL) Progress->Progress(65); |
