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
, false, true, false, 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
.Resolve(false, Progress
);
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
, true, false, false, Progress
);
135 if (Progress
!= NULL
)
136 Progress
->OverallProgress(0, 100, 1, _("Calculating upgrade"));
138 pkgDepCache::ActionGroup
group(Cache
);
140 pkgProblemResolver
Fix(&Cache
);
142 if (Cache
.BrokenCount() != 0)
145 // Upgrade all installed packages
146 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
148 if (Cache
[I
].Install() == true)
151 if (_config
->FindB("APT::Ignore-Hold",false) == false)
152 if (I
->SelectedState
== pkgCache::State::Hold
)
155 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
156 Cache
.MarkInstall(I
, false, 0, false);
159 if (Progress
!= NULL
)
160 Progress
->Progress(50);
162 // resolve remaining issues via keep
163 bool const success
= Fix
.ResolveByKeep(Progress
);
164 if (Progress
!= NULL
)
169 // AllUpgradeWithNewInstalls - Upgrade + install new packages as needed /*{{{*/
170 // ---------------------------------------------------------------------
171 /* Right now the system must be consistent before this can be called.
172 * Upgrade as much as possible without deleting anything (useful for
175 static bool pkgAllUpgradeWithNewPackages(pkgDepCache
&Cache
, OpProgress
* const Progress
)
177 std::string
const solver
= _config
->Find("APT::Solver", "internal");
178 if (solver
!= "internal")
179 return EDSP::ResolveExternal(solver
.c_str(), Cache
, true, false, false, Progress
);
181 if (Progress
!= NULL
)
182 Progress
->OverallProgress(0, 100, 1, _("Calculating upgrade"));
184 pkgDepCache::ActionGroup
group(Cache
);
186 pkgProblemResolver
Fix(&Cache
);
188 if (Cache
.BrokenCount() != 0)
191 // provide the initial set of stuff we want to upgrade by marking
192 // all upgradable packages for upgrade
193 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
195 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
197 if (_config
->FindB("APT::Ignore-Hold",false) == false)
198 if (I
->SelectedState
== pkgCache::State::Hold
)
201 Cache
.MarkInstall(I
, false, 0, false);
205 if (Progress
!= NULL
)
206 Progress
->Progress(10);
208 // then let auto-install loose
209 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
210 if (Cache
[I
].Install())
211 Cache
.MarkInstall(I
, true, 0, false);
213 if (Progress
!= NULL
)
214 Progress
->Progress(50);
216 // ... but it may remove stuff, we we need to clean up afterwards again
217 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
218 if (Cache
[I
].Delete() == true)
219 Cache
.MarkKeep(I
, false, false);
221 if (Progress
!= NULL
)
222 Progress
->Progress(60);
224 // resolve remaining issues via keep
225 bool const success
= Fix
.ResolveByKeep(Progress
);
226 if (Progress
!= NULL
)
231 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
232 // ---------------------------------------------------------------------
233 /* Right now the system must be consistent before this can be called.
234 It also will not change packages marked for install, it only tries
235 to install packages not marked for install */
236 static bool pkgAllUpgrade(pkgDepCache
&Cache
, OpProgress
* const Progress
)
238 return pkgAllUpgradeNoNewPackages(Cache
, Progress
);
240 bool pkgAllUpgrade(pkgDepCache
&Cache
)
242 return pkgAllUpgrade(Cache
, NULL
);
245 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
246 // ---------------------------------------------------------------------
247 /* This simply goes over the entire set of packages and tries to keep
248 each package marked for upgrade. If a conflict is generated then
249 the package is restored. */
250 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
252 pkgDepCache::ActionGroup
group(Cache
);
254 if (Cache
.BrokenCount() != 0)
257 // We loop for 10 tries to get the minimal set size.
259 unsigned int Count
= 0;
263 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
266 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
269 // Keep it and see if that is OK
270 Cache
.MarkKeep(I
, false, false);
271 if (Cache
.BrokenCount() != 0)
272 Cache
.MarkInstall(I
, false, 0, false);
275 // If keep didn't actually do anything then there was no change..
276 if (Cache
[I
].Upgrade() == false)
282 while (Change
== true && Count
< 10);
284 if (Cache
.BrokenCount() != 0)
285 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
290 // APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/
291 bool APT::Upgrade::Upgrade(pkgDepCache
&Cache
, int mode
, OpProgress
* const Progress
)
293 APT_IGNORE_DEPRECATED_PUSH
294 if (mode
== ALLOW_EVERYTHING
)
295 return pkgDistUpgrade(Cache
, Progress
);
296 else if ((mode
& ~FORBID_REMOVE_PACKAGES
) == 0)
297 return pkgAllUpgradeWithNewPackages(Cache
, Progress
);
298 else if ((mode
& ~(FORBID_REMOVE_PACKAGES
|FORBID_INSTALL_NEW_PACKAGES
)) == 0)
299 return pkgAllUpgradeNoNewPackages(Cache
, Progress
);
301 _error
->Error("pkgAllUpgrade called with unsupported mode %i", mode
);
302 APT_IGNORE_DEPRECATED_POP