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
);
139 pkgProblemResolver
Fix(&Cache
);
141 // Upgrade all installed packages
142 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
144 if (Cache
[I
].Install() == true)
147 if (_config
->FindB("APT::Ignore-Hold",false) == false)
148 if (I
->SelectedState
== pkgCache::State::Hold
)
151 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
152 Cache
.MarkInstall(I
, false, 0, false);
155 if (Progress
!= NULL
)
156 Progress
->Progress(50);
158 // resolve remaining issues via keep
159 bool const success
= Fix
.ResolveByKeep(Progress
);
160 if (Progress
!= NULL
)
165 // AllUpgradeWithNewInstalls - Upgrade + install new packages as needed /*{{{*/
166 // ---------------------------------------------------------------------
167 /* Right now the system must be consistent before this can be called.
168 * Upgrade as much as possible without deleting anything (useful for
171 static bool pkgAllUpgradeWithNewPackages(pkgDepCache
&Cache
, OpProgress
* const Progress
)
173 std::string
const solver
= _config
->Find("APT::Solver", "internal");
174 if (solver
!= "internal")
175 return EDSP::ResolveExternal(solver
.c_str(), Cache
, true, false, false, Progress
);
177 if (Progress
!= NULL
)
178 Progress
->OverallProgress(0, 100, 1, _("Calculating upgrade"));
180 pkgDepCache::ActionGroup
group(Cache
);
181 pkgProblemResolver
Fix(&Cache
);
183 // provide the initial set of stuff we want to upgrade by marking
184 // all upgradable packages for upgrade
185 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
187 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
189 if (_config
->FindB("APT::Ignore-Hold",false) == false)
190 if (I
->SelectedState
== pkgCache::State::Hold
)
193 Cache
.MarkInstall(I
, false, 0, false);
197 if (Progress
!= NULL
)
198 Progress
->Progress(10);
200 // then let auto-install loose
201 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
202 if (Cache
[I
].Install())
203 Cache
.MarkInstall(I
, true, 0, false);
205 if (Progress
!= NULL
)
206 Progress
->Progress(50);
208 // ... but it may remove stuff, we we need to clean up afterwards again
209 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
210 if (Cache
[I
].Delete() == true)
211 Cache
.MarkKeep(I
, false, false);
213 if (Progress
!= NULL
)
214 Progress
->Progress(60);
216 // resolve remaining issues via keep
217 bool const success
= Fix
.ResolveByKeep(Progress
);
218 if (Progress
!= NULL
)
223 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
224 // ---------------------------------------------------------------------
225 /* Right now the system must be consistent before this can be called.
226 It also will not change packages marked for install, it only tries
227 to install packages not marked for install */
228 static bool pkgAllUpgrade(pkgDepCache
&Cache
, OpProgress
* const Progress
)
230 return pkgAllUpgradeNoNewPackages(Cache
, Progress
);
232 bool pkgAllUpgrade(pkgDepCache
&Cache
)
234 return pkgAllUpgrade(Cache
, NULL
);
237 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
238 // ---------------------------------------------------------------------
239 /* This simply goes over the entire set of packages and tries to keep
240 each package marked for upgrade. If a conflict is generated then
241 the package is restored. */
242 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
244 pkgDepCache::ActionGroup
group(Cache
);
246 if (Cache
.BrokenCount() != 0)
249 // We loop for 10 tries to get the minimal set size.
251 unsigned int Count
= 0;
255 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
258 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
261 // Keep it and see if that is OK
262 Cache
.MarkKeep(I
, false, false);
263 if (Cache
.BrokenCount() != 0)
264 Cache
.MarkInstall(I
, false, 0, false);
267 // If keep didn't actually do anything then there was no change..
268 if (Cache
[I
].Upgrade() == false)
274 while (Change
== true && Count
< 10);
276 if (Cache
.BrokenCount() != 0)
277 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
282 // APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/
283 bool APT::Upgrade::Upgrade(pkgDepCache
&Cache
, int mode
, OpProgress
* const Progress
)
285 APT_IGNORE_DEPRECATED_PUSH
286 if (mode
== ALLOW_EVERYTHING
)
287 return pkgDistUpgrade(Cache
, Progress
);
288 else if ((mode
& ~FORBID_REMOVE_PACKAGES
) == 0)
289 return pkgAllUpgradeWithNewPackages(Cache
, Progress
);
290 else if ((mode
& ~(FORBID_REMOVE_PACKAGES
|FORBID_INSTALL_NEW_PACKAGES
)) == 0)
291 return pkgAllUpgradeNoNewPackages(Cache
, Progress
);
293 _error
->Error("pkgAllUpgrade called with unsupported mode %i", mode
);
294 APT_IGNORE_DEPRECATED_POP