]> git.saurik.com Git - apt.git/blame - apt-pkg/upgrade.cc
refactor EDSP classes for better internal reuse
[apt.git] / apt-pkg / upgrade.cc
CommitLineData
82e369c4
MV
1// Include Files /*{{{*/
2#include <config.h>
3
4#include <apt-pkg/algorithms.h>
82e369c4 5#include <apt-pkg/configuration.h>
82e369c4 6#include <apt-pkg/edsp.h>
453b82a3 7#include <apt-pkg/error.h>
82e369c4 8#include <apt-pkg/progress.h>
453b82a3
DK
9#include <apt-pkg/upgrade.h>
10#include <apt-pkg/depcache.h>
11#include <apt-pkg/pkgcache.h>
12#include <apt-pkg/cacheiterators.h>
82e369c4 13
453b82a3 14#include <string>
82e369c4
MV
15
16#include <apti18n.h>
17 /*}}}*/
18
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.
24
25 The problem resolver is used to resolve the problems.
26 */
fa5404ab 27static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
82e369c4
MV
28{
29 std::string const solver = _config->Find("APT::Solver", "internal");
2a884c61 30 if (solver != "internal")
43c71fad 31 return EDSP::ResolveExternal(solver.c_str(), Cache, EDSP::Request::UPGRADE_ALL, Progress);
2a884c61
DK
32
33 if (Progress != NULL)
34 Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
82e369c4
MV
35
36 pkgDepCache::ActionGroup group(Cache);
37
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);
44
2a884c61
DK
45 if (Progress != NULL)
46 Progress->Progress(10);
47
82e369c4
MV
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);
53
2a884c61
DK
54 if (Progress != NULL)
55 Progress->Progress(50);
56
82e369c4
MV
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")
61 {
62 for (pkgCache::GrpIterator G = Cache.GrpBegin(); G.end() == false; ++G)
63 {
64 bool isEssential = false;
65 bool instEssential = false;
66 for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P))
67 {
68 if ((P->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential)
69 continue;
70 isEssential = true;
71 if (Cache[P].Install() == true)
72 {
73 instEssential = true;
74 break;
75 }
76 }
77 if (isEssential == false || instEssential == true)
78 continue;
79 pkgCache::PkgIterator P = G.FindPreferredPkg();
80 Cache.MarkInstall(P, true, 0, false);
81 }
82 }
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);
2a884c61
DK
87
88 if (Progress != NULL)
89 Progress->Progress(55);
90
82e369c4
MV
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);
96
2a884c61
DK
97 if (Progress != NULL)
98 Progress->Progress(65);
99
82e369c4
MV
100 pkgProblemResolver Fix(&Cache);
101
2a884c61
DK
102 if (Progress != NULL)
103 Progress->Progress(95);
104
82e369c4
MV
105 // Hold back held packages.
106 if (_config->FindB("APT::Ignore-Hold",false) == false)
107 {
108 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
109 {
110 if (I->SelectedState == pkgCache::State::Hold)
111 {
112 Fix.Protect(I);
113 Cache.MarkKeep(I, false, false);
114 }
115 }
116 }
2a884c61
DK
117
118 bool const success = Fix.Resolve(false, Progress);
119 if (Progress != NULL)
120 Progress->Done();
121 return success;
fa5404ab
DK
122}
123bool pkgDistUpgrade(pkgDepCache &Cache)
124{
125 return pkgDistUpgrade(Cache, NULL);
82e369c4
MV
126}
127 /*}}}*/
128// AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs /*{{{*/
2a884c61 129static bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache, OpProgress * const Progress)
82e369c4
MV
130{
131 std::string const solver = _config->Find("APT::Solver", "internal");
2a884c61 132 if (solver != "internal")
43c71fad
DK
133 return EDSP::ResolveExternal(solver.c_str(), Cache,
134 EDSP::Request::UPGRADE_ALL | EDSP::Request::FORBID_NEW_INSTALL | EDSP::Request::FORBID_REMOVE,
135 Progress);
2a884c61
DK
136
137 if (Progress != NULL)
138 Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
82e369c4
MV
139
140 pkgDepCache::ActionGroup group(Cache);
82e369c4
MV
141 pkgProblemResolver Fix(&Cache);
142
82e369c4
MV
143 // Upgrade all installed packages
144 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
145 {
146 if (Cache[I].Install() == true)
147 Fix.Protect(I);
148
149 if (_config->FindB("APT::Ignore-Hold",false) == false)
150 if (I->SelectedState == pkgCache::State::Hold)
151 continue;
152
153 if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
154 Cache.MarkInstall(I, false, 0, false);
155 }
2a884c61
DK
156
157 if (Progress != NULL)
158 Progress->Progress(50);
159
160 // resolve remaining issues via keep
161 bool const success = Fix.ResolveByKeep(Progress);
162 if (Progress != NULL)
163 Progress->Done();
164 return success;
82e369c4
MV
165}
166 /*}}}*/
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
171 * stable systems)
172 */
2a884c61 173static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache, OpProgress * const Progress)
82e369c4 174{
172947cd 175 std::string const solver = _config->Find("APT::Solver", "internal");
2a884c61 176 if (solver != "internal")
43c71fad
DK
177 return EDSP::ResolveExternal(solver.c_str(), Cache,
178 EDSP::Request::UPGRADE_ALL | EDSP::Request::FORBID_REMOVE,
179 Progress);
2a884c61
DK
180
181 if (Progress != NULL)
182 Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
172947cd 183
82e369c4 184 pkgDepCache::ActionGroup group(Cache);
82e369c4
MV
185 pkgProblemResolver Fix(&Cache);
186
82e369c4
MV
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)
190 {
191 if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
192 {
193 if (_config->FindB("APT::Ignore-Hold",false) == false)
194 if (I->SelectedState == pkgCache::State::Hold)
195 continue;
196
197 Cache.MarkInstall(I, false, 0, false);
198 }
199 }
200
2a884c61
DK
201 if (Progress != NULL)
202 Progress->Progress(10);
203
82e369c4
MV
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);
208
2a884c61
DK
209 if (Progress != NULL)
210 Progress->Progress(50);
211
82e369c4
MV
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);
216
2a884c61
DK
217 if (Progress != NULL)
218 Progress->Progress(60);
219
82e369c4 220 // resolve remaining issues via keep
2a884c61
DK
221 bool const success = Fix.ResolveByKeep(Progress);
222 if (Progress != NULL)
223 Progress->Done();
224 return success;
82e369c4
MV
225}
226 /*}}}*/
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 */
fa5404ab 232static bool pkgAllUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
82e369c4 233{
2a884c61 234 return pkgAllUpgradeNoNewPackages(Cache, Progress);
fa5404ab
DK
235}
236bool pkgAllUpgrade(pkgDepCache &Cache)
237{
238 return pkgAllUpgrade(Cache, NULL);
82e369c4
MV
239}
240 /*}}}*/
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. */
246bool pkgMinimizeUpgrade(pkgDepCache &Cache)
247{
248 pkgDepCache::ActionGroup group(Cache);
249
250 if (Cache.BrokenCount() != 0)
251 return false;
252
253 // We loop for 10 tries to get the minimal set size.
254 bool Change = false;
255 unsigned int Count = 0;
256 do
257 {
258 Change = false;
259 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
260 {
261 // Not interesting
262 if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
263 continue;
264
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);
269 else
270 {
1e3f4083 271 // If keep didn't actually do anything then there was no change..
82e369c4
MV
272 if (Cache[I].Upgrade() == false)
273 Change = true;
274 }
275 }
276 ++Count;
277 }
278 while (Change == true && Count < 10);
279
280 if (Cache.BrokenCount() != 0)
281 return _error->Error("Internal Error in pkgMinimizeUpgrade");
282
283 return true;
284}
285 /*}}}*/
2a884c61
DK
286// APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/
287bool APT::Upgrade::Upgrade(pkgDepCache &Cache, int mode, OpProgress * const Progress)
82e369c4 288{
586d8704 289APT_IGNORE_DEPRECATED_PUSH
67caa2e6 290 if (mode == ALLOW_EVERYTHING)
2a884c61 291 return pkgDistUpgrade(Cache, Progress);
82e369c4 292 else if ((mode & ~FORBID_REMOVE_PACKAGES) == 0)
2a884c61 293 return pkgAllUpgradeWithNewPackages(Cache, Progress);
3f506f68 294 else if ((mode & ~(FORBID_REMOVE_PACKAGES|FORBID_INSTALL_NEW_PACKAGES)) == 0)
2a884c61 295 return pkgAllUpgradeNoNewPackages(Cache, Progress);
82e369c4
MV
296 else
297 _error->Error("pkgAllUpgrade called with unsupported mode %i", mode);
586d8704 298APT_IGNORE_DEPRECATED_POP
82e369c4
MV
299 return false;
300}
301 /*}}}*/