Skip to content

Commit 68ef41e

Browse files
committed
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.
1 parent 89dd48b commit 68ef41e

File tree

2 files changed

+119
-4
lines changed

2 files changed

+119
-4
lines changed

apt-pkg/upgrade.cc

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,13 @@ struct PhasedUpgrader
8585
{
8686
if (Pkg->CurrentVer == 0)
8787
return false;
88-
if (Cache[Pkg].InstallVer == 0)
88+
if (Cache[Pkg].CandidateVer == 0)
8989
return false;
90-
if (Cache[Pkg].InstVerIter(Cache).PhasedUpdatePercentage() == 100)
90+
if (Cache[Pkg].CandidateVerIter(Cache).PhasedUpdatePercentage() == 100)
9191
return false;
92-
if (IsSecurityUpdate(Cache[Pkg].InstVerIter(Cache)))
92+
if (IsSecurityUpdate(Cache[Pkg].CandidateVerIter(Cache)))
9393
return false;
94-
if (!IsIgnoredPhasedUpdate(Cache[Pkg].InstVerIter(Cache)))
94+
if (!IsIgnoredPhasedUpdate(Cache[Pkg].CandidateVerIter(Cache)))
9595
return false;
9696

9797
return true;
@@ -133,22 +133,31 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
133133
Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
134134

135135
pkgDepCache::ActionGroup group(Cache);
136+
PhasedUpgrader phasedUpgrader;
136137

137138
/* Upgrade all installed packages first without autoinst to help the resolver
138139
in versioned or-groups to upgrade the old solver instead of installing
139140
a new one (if the old solver is not the first one [anymore]) */
140141
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
142+
{
143+
if (phasedUpgrader.ShouldKeep(Cache, I))
144+
continue;
141145
if (I->CurrentVer != 0)
142146
Cache.MarkInstall(I, false, 0, false);
147+
}
143148

144149
if (Progress != NULL)
145150
Progress->Progress(10);
146151

147152
/* Auto upgrade all installed packages, this provides the basis
148153
for the installation */
149154
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
155+
{
156+
if (phasedUpgrader.ShouldKeep(Cache, I))
157+
continue;
150158
if (I->CurrentVer != 0)
151159
Cache.MarkInstall(I, true, 0, false);
160+
}
152161

153162
if (Progress != NULL)
154163
Progress->Progress(50);
@@ -176,22 +185,32 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
176185
if (isEssential == false || instEssential == true)
177186
continue;
178187
pkgCache::PkgIterator P = G.FindPreferredPkg();
188+
if (phasedUpgrader.ShouldKeep(Cache, P))
189+
continue;
179190
Cache.MarkInstall(P, true, 0, false);
180191
}
181192
}
182193
else if (essential != "none")
183194
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
195+
{
196+
if (phasedUpgrader.ShouldKeep(Cache, I))
197+
continue;
184198
if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
185199
Cache.MarkInstall(I, true, 0, false);
200+
}
186201

187202
if (Progress != NULL)
188203
Progress->Progress(55);
189204

190205
/* We do it again over all previously installed packages to force
191206
conflict resolution on them all. */
192207
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
208+
{
209+
if (phasedUpgrader.ShouldKeep(Cache, I))
210+
continue;
193211
if (I->CurrentVer != 0)
194212
Cache.MarkInstall(I, false, 0, false);
213+
}
195214

196215
if (Progress != NULL)
197216
Progress->Progress(65);
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/bin/sh
2+
set -e
3+
4+
TESTDIR="$(readlink -f "$(dirname "$0")")"
5+
. "$TESTDIR/framework"
6+
7+
setupenvironment
8+
echo 'Debug::Phasing "1";' > rootdir/etc/apt/apt.conf.d/debug-phasing
9+
configarchitecture 'i386'
10+
11+
insertinstalledpackage 'has-new-depends' 'all' '1' ''
12+
insertinstalledpackage 'has-new-recommends' 'all' '1' ''
13+
insertinstalledpackage 'has-new-conflicts' 'all' '1' ''
14+
insertinstalledpackage 'new-conflicts' 'all' '1' ''
15+
16+
insertpackage 'unstable-updates' 'new-depends' 'all' '2'
17+
insertpackage 'unstable-updates' 'new-recommends' 'all' '2'
18+
insertpackage 'unstable-updates' 'has-new-depends' 'all' '2' 'Phased-Update-Percentage: 0
19+
Depends: new-depends'
20+
insertpackage 'unstable-updates' 'has-new-recommends' 'all' '2' 'Phased-Update-Percentage: 0
21+
Recommends: new-recommends'
22+
insertpackage 'unstable-updates' 'has-new-conflicts' 'all' '2' 'Phased-Update-Percentage: 0
23+
Conflicts: new-conflicts'
24+
25+
setupaptarchive
26+
27+
28+
testsuccessequal "Reading package lists...
29+
Building dependency tree...
30+
Calculating upgrade...
31+
The following packages have been kept back:
32+
has-new-conflicts has-new-depends has-new-recommends
33+
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded." aptget upgrade -s -q -o APT::Get::Always-Include-Phased-Updates=1
34+
35+
testsuccessequal "Reading package lists...
36+
Building dependency tree...
37+
Calculating upgrade...
38+
The following packages have been kept back:
39+
has-new-conflicts has-new-depends has-new-recommends
40+
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded." aptget upgrade -s -q
41+
42+
43+
testsuccessequal "Reading package lists...
44+
Building dependency tree...
45+
Calculating upgrade...
46+
The following NEW packages will be installed:
47+
new-depends new-recommends
48+
The following packages have been kept back:
49+
has-new-conflicts
50+
The following packages will be upgraded:
51+
has-new-depends has-new-recommends
52+
2 upgraded, 2 newly installed, 0 to remove and 1 not upgraded.
53+
Inst new-depends (2 unstable-updates [all])
54+
Inst has-new-depends [1] (2 unstable-updates [all])
55+
Inst has-new-recommends [1] (2 unstable-updates [all])
56+
Inst new-recommends (2 unstable-updates [all])
57+
Conf new-depends (2 unstable-updates [all])
58+
Conf has-new-depends (2 unstable-updates [all])
59+
Conf has-new-recommends (2 unstable-updates [all])
60+
Conf new-recommends (2 unstable-updates [all])" aptget upgrade -s -q --with-new-pkgs -o APT::Get::Always-Include-Phased-Updates=1
61+
62+
testsuccessequal "Reading package lists...
63+
Building dependency tree...
64+
Calculating upgrade...
65+
The following packages have been kept back:
66+
has-new-conflicts has-new-depends has-new-recommends
67+
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded." aptget upgrade -s -q --with-new-pkgs
68+
69+
: testsuccessequal "Reading package lists...
70+
Building dependency tree...
71+
Calculating upgrade...
72+
The following packages will be REMOVED:
73+
new-conflicts
74+
The following NEW packages will be installed:
75+
new-depends new-recommends
76+
The following packages will be upgraded:
77+
has-new-conflicts has-new-depends has-new-recommends
78+
3 upgraded, 2 newly installed, 1 to remove and 0 not upgraded.
79+
Remv new-conflicts [1]
80+
Inst has-new-conflicts [1] (2 unstable-updates [all])
81+
Inst new-depends (2 unstable-updates [all])
82+
Inst has-new-depends [1] (2 unstable-updates [all])
83+
Inst has-new-recommends [1] (2 unstable-updates [all])
84+
Inst new-recommends (2 unstable-updates [all])
85+
Conf has-new-conflicts (2 unstable-updates [all])
86+
Conf new-depends (2 unstable-updates [all])
87+
Conf has-new-depends (2 unstable-updates [all])
88+
Conf has-new-recommends (2 unstable-updates [all])
89+
Conf new-recommends (2 unstable-updates [all])" aptget dist-upgrade -s -q -o APT::Get::Always-Include-Phased-Updates=1
90+
91+
testsuccessequal "Reading package lists...
92+
Building dependency tree...
93+
Calculating upgrade...
94+
The following packages have been kept back:
95+
has-new-conflicts has-new-depends has-new-recommends
96+
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded." aptget dist-upgrade -s -q

0 commit comments

Comments
 (0)