1 // Include Files /*{{{*/
4 #include <apt-pkg/algorithms.h>
5 #include <apt-pkg/configuration.h>
6 #include <apt-pkg/edsp.h>
7 #include <apt-pkg/error.h>
8 #include <apt-pkg/progress.h>
9 #include <apt-pkg/upgrade.h>
10 #include <apt-pkg/depcache.h>
11 #include <apt-pkg/pkgcache.h>
12 #include <apt-pkg/cacheiterators.h>
19 // DistUpgrade - Distribution upgrade /*{{{*/
20 // ---------------------------------------------------------------------
21 /* This autoinstalls every package and then force installs every
22 pre-existing package. This creates the initial set of conditions which
23 most likely contain problems because too many things were installed.
25 The problem resolver is used to resolve the problems.
27 static bool pkgDistUpgrade(pkgDepCache
&Cache
, OpProgress
* const Progress
)
29 std::string
const solver
= _config
->Find("APT::Solver", "internal");
30 auto const ret
= EDSP::ResolveExternal(solver
.c_str(), Cache
, EDSP::Request::UPGRADE_ALL
, Progress
);
31 if (solver
!= "internal")
35 Progress
->OverallProgress(0, 100, 1, _("Calculating upgrade"));
37 pkgDepCache::ActionGroup
group(Cache
);
39 /* Upgrade all installed packages first without autoinst to help the resolver
40 in versioned or-groups to upgrade the old solver instead of installing
41 a new one (if the old solver is not the first one [anymore]) */
42 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
43 if (I
->CurrentVer
!= 0)
44 Cache
.MarkInstall(I
, false, 0, false);
47 Progress
->Progress(10);
49 /* Auto upgrade all installed packages, this provides the basis
50 for the installation */
51 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
52 if (I
->CurrentVer
!= 0)
53 Cache
.MarkInstall(I
, true, 0, false);
56 Progress
->Progress(50);
58 /* Now, install each essential package which is not installed
59 (and not provided by another package in the same name group) */
60 std::string essential
= _config
->Find("pkgCacheGen::Essential", "all");
61 if (essential
== "all")
63 for (pkgCache::GrpIterator G
= Cache
.GrpBegin(); G
.end() == false; ++G
)
65 bool isEssential
= false;
66 bool instEssential
= false;
67 for (pkgCache::PkgIterator P
= G
.PackageList(); P
.end() == false; P
= G
.NextPkg(P
))
69 if ((P
->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
72 if (Cache
[P
].Install() == true)
78 if (isEssential
== false || instEssential
== true)
80 pkgCache::PkgIterator P
= G
.FindPreferredPkg();
81 Cache
.MarkInstall(P
, true, 0, false);
84 else if (essential
!= "none")
85 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
86 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
87 Cache
.MarkInstall(I
, true, 0, false);
90 Progress
->Progress(55);
92 /* We do it again over all previously installed packages to force
93 conflict resolution on them all. */
94 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
95 if (I
->CurrentVer
!= 0)
96 Cache
.MarkInstall(I
, false, 0, false);
99 Progress
->Progress(65);
101 pkgProblemResolver
Fix(&Cache
);
103 if (Progress
!= NULL
)
104 Progress
->Progress(95);
106 // Hold back held packages.
107 if (_config
->FindB("APT::Ignore-Hold",false) == false)
109 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
111 if (I
->SelectedState
== pkgCache::State::Hold
)
114 Cache
.MarkKeep(I
, false, false);
119 bool const success
= Fix
.ResolveInternal(false);
120 if (Progress
!= NULL
)
124 bool pkgDistUpgrade(pkgDepCache
&Cache
)
126 return pkgDistUpgrade(Cache
, NULL
);
129 // AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs /*{{{*/
130 static bool pkgAllUpgradeNoNewPackages(pkgDepCache
&Cache
, OpProgress
* const Progress
)
132 std::string
const solver
= _config
->Find("APT::Solver", "internal");
133 constexpr auto flags
= EDSP::Request::UPGRADE_ALL
| EDSP::Request::FORBID_NEW_INSTALL
| EDSP::Request::FORBID_REMOVE
;
134 auto const ret
= EDSP::ResolveExternal(solver
.c_str(), Cache
, flags
, Progress
);
135 if (solver
!= "internal")
138 if (Progress
!= NULL
)
139 Progress
->OverallProgress(0, 100, 1, _("Calculating upgrade"));
141 pkgDepCache::ActionGroup
group(Cache
);
142 pkgProblemResolver
Fix(&Cache
);
144 // Upgrade all installed packages
145 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
147 if (Cache
[I
].Install() == true)
150 if (_config
->FindB("APT::Ignore-Hold",false) == false)
151 if (I
->SelectedState
== pkgCache::State::Hold
)
154 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
155 Cache
.MarkInstall(I
, false, 0, false);
158 if (Progress
!= NULL
)
159 Progress
->Progress(50);
161 // resolve remaining issues via keep
162 bool const success
= Fix
.ResolveByKeepInternal();
163 if (Progress
!= NULL
)
168 // AllUpgradeWithNewInstalls - Upgrade + install new packages as needed /*{{{*/
169 // ---------------------------------------------------------------------
170 /* Right now the system must be consistent before this can be called.
171 * Upgrade as much as possible without deleting anything (useful for
174 static bool pkgAllUpgradeWithNewPackages(pkgDepCache
&Cache
, OpProgress
* const Progress
)
176 std::string
const solver
= _config
->Find("APT::Solver", "internal");
177 constexpr auto flags
= EDSP::Request::UPGRADE_ALL
| EDSP::Request::FORBID_REMOVE
;
178 auto const ret
= EDSP::ResolveExternal(solver
.c_str(), Cache
, flags
, Progress
);
179 if (solver
!= "internal")
182 if (Progress
!= NULL
)
183 Progress
->OverallProgress(0, 100, 1, _("Calculating upgrade"));
185 pkgDepCache::ActionGroup
group(Cache
);
186 pkgProblemResolver
Fix(&Cache
);
188 // provide the initial set of stuff we want to upgrade by marking
189 // all upgradable packages for upgrade
190 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
192 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
194 if (_config
->FindB("APT::Ignore-Hold",false) == false)
195 if (I
->SelectedState
== pkgCache::State::Hold
)
198 Cache
.MarkInstall(I
, false, 0, false);
202 if (Progress
!= NULL
)
203 Progress
->Progress(10);
205 // then let auto-install loose
206 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
207 if (Cache
[I
].Install())
208 Cache
.MarkInstall(I
, true, 0, false);
210 if (Progress
!= NULL
)
211 Progress
->Progress(50);
213 // ... but it may remove stuff, we we need to clean up afterwards again
214 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
215 if (Cache
[I
].Delete() == true)
216 Cache
.MarkKeep(I
, false, false);
218 if (Progress
!= NULL
)
219 Progress
->Progress(60);
221 // resolve remaining issues via keep
222 bool const success
= Fix
.ResolveByKeepInternal();
223 if (Progress
!= NULL
)
228 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
229 // ---------------------------------------------------------------------
230 /* Right now the system must be consistent before this can be called.
231 It also will not change packages marked for install, it only tries
232 to install packages not marked for install */
233 static bool pkgAllUpgrade(pkgDepCache
&Cache
, OpProgress
* const Progress
)
235 return pkgAllUpgradeNoNewPackages(Cache
, Progress
);
237 bool pkgAllUpgrade(pkgDepCache
&Cache
)
239 return pkgAllUpgrade(Cache
, NULL
);
242 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
243 // ---------------------------------------------------------------------
244 /* This simply goes over the entire set of packages and tries to keep
245 each package marked for upgrade. If a conflict is generated then
246 the package is restored. */
247 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
249 pkgDepCache::ActionGroup
group(Cache
);
251 if (Cache
.BrokenCount() != 0)
254 // We loop for 10 tries to get the minimal set size.
256 unsigned int Count
= 0;
260 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
263 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
266 // Keep it and see if that is OK
267 Cache
.MarkKeep(I
, false, false);
268 if (Cache
.BrokenCount() != 0)
269 Cache
.MarkInstall(I
, false, 0, false);
272 // If keep didn't actually do anything then there was no change..
273 if (Cache
[I
].Upgrade() == false)
279 while (Change
== true && Count
< 10);
281 if (Cache
.BrokenCount() != 0)
282 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
287 // APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/
288 bool APT::Upgrade::Upgrade(pkgDepCache
&Cache
, int mode
, OpProgress
* const Progress
)
290 APT_IGNORE_DEPRECATED_PUSH
291 if (mode
== ALLOW_EVERYTHING
)
292 return pkgDistUpgrade(Cache
, Progress
);
293 else if ((mode
& ~FORBID_REMOVE_PACKAGES
) == 0)
294 return pkgAllUpgradeWithNewPackages(Cache
, Progress
);
295 else if ((mode
& ~(FORBID_REMOVE_PACKAGES
|FORBID_INSTALL_NEW_PACKAGES
)) == 0)
296 return pkgAllUpgradeNoNewPackages(Cache
, Progress
);
298 _error
->Error("pkgAllUpgrade called with unsupported mode %i", mode
);
299 APT_IGNORE_DEPRECATED_POP