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 if (solver
!= "internal")
31 return EDSP::ResolveExternal(solver
.c_str(), Cache
, EDSP::Request::UPGRADE_ALL
, Progress
);
34 Progress
->OverallProgress(0, 100, 1, _("Calculating upgrade"));
36 pkgDepCache::ActionGroup
group(Cache
);
38 /* Upgrade all installed packages first without autoinst to help the resolver
39 in versioned or-groups to upgrade the old solver instead of installing
40 a new one (if the old solver is not the first one [anymore]) */
41 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
42 if (I
->CurrentVer
!= 0)
43 Cache
.MarkInstall(I
, false, 0, false);
46 Progress
->Progress(10);
48 /* Auto upgrade all installed packages, this provides the basis
49 for the installation */
50 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
51 if (I
->CurrentVer
!= 0)
52 Cache
.MarkInstall(I
, true, 0, false);
55 Progress
->Progress(50);
57 /* Now, install each essential package which is not installed
58 (and not provided by another package in the same name group) */
59 std::string essential
= _config
->Find("pkgCacheGen::Essential", "all");
60 if (essential
== "all")
62 for (pkgCache::GrpIterator G
= Cache
.GrpBegin(); G
.end() == false; ++G
)
64 bool isEssential
= false;
65 bool instEssential
= false;
66 for (pkgCache::PkgIterator P
= G
.PackageList(); P
.end() == false; P
= G
.NextPkg(P
))
68 if ((P
->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
71 if (Cache
[P
].Install() == true)
77 if (isEssential
== false || instEssential
== true)
79 pkgCache::PkgIterator P
= G
.FindPreferredPkg();
80 Cache
.MarkInstall(P
, true, 0, false);
83 else if (essential
!= "none")
84 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
85 if ((I
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
86 Cache
.MarkInstall(I
, true, 0, false);
89 Progress
->Progress(55);
91 /* We do it again over all previously installed packages to force
92 conflict resolution on them all. */
93 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
94 if (I
->CurrentVer
!= 0)
95 Cache
.MarkInstall(I
, false, 0, false);
98 Progress
->Progress(65);
100 pkgProblemResolver
Fix(&Cache
);
102 if (Progress
!= NULL
)
103 Progress
->Progress(95);
105 // Hold back held packages.
106 if (_config
->FindB("APT::Ignore-Hold",false) == false)
108 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
110 if (I
->SelectedState
== pkgCache::State::Hold
)
113 Cache
.MarkKeep(I
, false, false);
118 bool const success
= Fix
.ResolveInternal(false);
119 if (Progress
!= NULL
)
123 bool pkgDistUpgrade(pkgDepCache
&Cache
)
125 return pkgDistUpgrade(Cache
, NULL
);
128 // AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs /*{{{*/
129 static bool pkgAllUpgradeNoNewPackages(pkgDepCache
&Cache
, OpProgress
* const Progress
)
131 std::string
const solver
= _config
->Find("APT::Solver", "internal");
132 if (solver
!= "internal")
133 return EDSP::ResolveExternal(solver
.c_str(), Cache
,
134 EDSP::Request::UPGRADE_ALL
| EDSP::Request::FORBID_NEW_INSTALL
| EDSP::Request::FORBID_REMOVE
,
137 if (Progress
!= NULL
)
138 Progress
->OverallProgress(0, 100, 1, _("Calculating upgrade"));
140 pkgDepCache::ActionGroup
group(Cache
);
141 pkgProblemResolver
Fix(&Cache
);
143 // Upgrade all installed packages
144 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
146 if (Cache
[I
].Install() == true)
149 if (_config
->FindB("APT::Ignore-Hold",false) == false)
150 if (I
->SelectedState
== pkgCache::State::Hold
)
153 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
154 Cache
.MarkInstall(I
, false, 0, false);
157 if (Progress
!= NULL
)
158 Progress
->Progress(50);
160 // resolve remaining issues via keep
161 bool const success
= Fix
.ResolveByKeepInternal();
162 if (Progress
!= NULL
)
167 // AllUpgradeWithNewInstalls - Upgrade + install new packages as needed /*{{{*/
168 // ---------------------------------------------------------------------
169 /* Right now the system must be consistent before this can be called.
170 * Upgrade as much as possible without deleting anything (useful for
173 static bool pkgAllUpgradeWithNewPackages(pkgDepCache
&Cache
, OpProgress
* const Progress
)
175 std::string
const solver
= _config
->Find("APT::Solver", "internal");
176 if (solver
!= "internal")
177 return EDSP::ResolveExternal(solver
.c_str(), Cache
,
178 EDSP::Request::UPGRADE_ALL
| EDSP::Request::FORBID_REMOVE
,
181 if (Progress
!= NULL
)
182 Progress
->OverallProgress(0, 100, 1, _("Calculating upgrade"));
184 pkgDepCache::ActionGroup
group(Cache
);
185 pkgProblemResolver
Fix(&Cache
);
187 // provide the initial set of stuff we want to upgrade by marking
188 // all upgradable packages for upgrade
189 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
191 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
193 if (_config
->FindB("APT::Ignore-Hold",false) == false)
194 if (I
->SelectedState
== pkgCache::State::Hold
)
197 Cache
.MarkInstall(I
, false, 0, false);
201 if (Progress
!= NULL
)
202 Progress
->Progress(10);
204 // then let auto-install loose
205 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
206 if (Cache
[I
].Install())
207 Cache
.MarkInstall(I
, true, 0, false);
209 if (Progress
!= NULL
)
210 Progress
->Progress(50);
212 // ... but it may remove stuff, we we need to clean up afterwards again
213 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
214 if (Cache
[I
].Delete() == true)
215 Cache
.MarkKeep(I
, false, false);
217 if (Progress
!= NULL
)
218 Progress
->Progress(60);
220 // resolve remaining issues via keep
221 bool const success
= Fix
.ResolveByKeepInternal();
222 if (Progress
!= NULL
)
227 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
228 // ---------------------------------------------------------------------
229 /* Right now the system must be consistent before this can be called.
230 It also will not change packages marked for install, it only tries
231 to install packages not marked for install */
232 static bool pkgAllUpgrade(pkgDepCache
&Cache
, OpProgress
* const Progress
)
234 return pkgAllUpgradeNoNewPackages(Cache
, Progress
);
236 bool pkgAllUpgrade(pkgDepCache
&Cache
)
238 return pkgAllUpgrade(Cache
, NULL
);
241 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
242 // ---------------------------------------------------------------------
243 /* This simply goes over the entire set of packages and tries to keep
244 each package marked for upgrade. If a conflict is generated then
245 the package is restored. */
246 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
248 pkgDepCache::ActionGroup
group(Cache
);
250 if (Cache
.BrokenCount() != 0)
253 // We loop for 10 tries to get the minimal set size.
255 unsigned int Count
= 0;
259 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
262 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
265 // Keep it and see if that is OK
266 Cache
.MarkKeep(I
, false, false);
267 if (Cache
.BrokenCount() != 0)
268 Cache
.MarkInstall(I
, false, 0, false);
271 // If keep didn't actually do anything then there was no change..
272 if (Cache
[I
].Upgrade() == false)
278 while (Change
== true && Count
< 10);
280 if (Cache
.BrokenCount() != 0)
281 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
286 // APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/
287 bool APT::Upgrade::Upgrade(pkgDepCache
&Cache
, int mode
, OpProgress
* const Progress
)
289 APT_IGNORE_DEPRECATED_PUSH
290 if (mode
== ALLOW_EVERYTHING
)
291 return pkgDistUpgrade(Cache
, Progress
);
292 else if ((mode
& ~FORBID_REMOVE_PACKAGES
) == 0)
293 return pkgAllUpgradeWithNewPackages(Cache
, Progress
);
294 else if ((mode
& ~(FORBID_REMOVE_PACKAGES
|FORBID_INSTALL_NEW_PACKAGES
)) == 0)
295 return pkgAllUpgradeNoNewPackages(Cache
, Progress
);
297 _error
->Error("pkgAllUpgrade called with unsupported mode %i", mode
);
298 APT_IGNORE_DEPRECATED_POP