]> git.saurik.com Git - apt.git/blob - apt-pkg/upgrade.cc
Merge remote-tracking branch 'vnwildman/debian/sid' into debian/sid
[apt.git] / apt-pkg / upgrade.cc
1 // Include Files /*{{{*/
2 #include <config.h>
3
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>
13
14 #include <string>
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 */
27 bool pkgDistUpgrade(pkgDepCache &Cache)
28 {
29 std::string const solver = _config->Find("APT::Solver", "internal");
30 if (solver != "internal") {
31 OpTextProgress Prog(*_config);
32 return EDSP::ResolveExternal(solver.c_str(), Cache, false, true, false, &Prog);
33 }
34
35 pkgDepCache::ActionGroup group(Cache);
36
37 /* Upgrade all installed packages first without autoinst to help the resolver
38 in versioned or-groups to upgrade the old solver instead of installing
39 a new one (if the old solver is not the first one [anymore]) */
40 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
41 if (I->CurrentVer != 0)
42 Cache.MarkInstall(I, false, 0, false);
43
44 /* Auto upgrade all installed packages, this provides the basis
45 for the installation */
46 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
47 if (I->CurrentVer != 0)
48 Cache.MarkInstall(I, true, 0, false);
49
50 /* Now, install each essential package which is not installed
51 (and not provided by another package in the same name group) */
52 std::string essential = _config->Find("pkgCacheGen::Essential", "all");
53 if (essential == "all")
54 {
55 for (pkgCache::GrpIterator G = Cache.GrpBegin(); G.end() == false; ++G)
56 {
57 bool isEssential = false;
58 bool instEssential = false;
59 for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P))
60 {
61 if ((P->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential)
62 continue;
63 isEssential = true;
64 if (Cache[P].Install() == true)
65 {
66 instEssential = true;
67 break;
68 }
69 }
70 if (isEssential == false || instEssential == true)
71 continue;
72 pkgCache::PkgIterator P = G.FindPreferredPkg();
73 Cache.MarkInstall(P, true, 0, false);
74 }
75 }
76 else if (essential != "none")
77 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
78 if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
79 Cache.MarkInstall(I, true, 0, false);
80
81 /* We do it again over all previously installed packages to force
82 conflict resolution on them all. */
83 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
84 if (I->CurrentVer != 0)
85 Cache.MarkInstall(I, false, 0, false);
86
87 pkgProblemResolver Fix(&Cache);
88
89 // Hold back held packages.
90 if (_config->FindB("APT::Ignore-Hold",false) == false)
91 {
92 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
93 {
94 if (I->SelectedState == pkgCache::State::Hold)
95 {
96 Fix.Protect(I);
97 Cache.MarkKeep(I, false, false);
98 }
99 }
100 }
101
102 return Fix.Resolve();
103 }
104 /*}}}*/
105 // AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs /*{{{*/
106 static bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache)
107 {
108 std::string const solver = _config->Find("APT::Solver", "internal");
109 if (solver != "internal") {
110 OpTextProgress Prog(*_config);
111 return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog);
112 }
113
114 pkgDepCache::ActionGroup group(Cache);
115
116 pkgProblemResolver Fix(&Cache);
117
118 if (Cache.BrokenCount() != 0)
119 return false;
120
121 // Upgrade all installed packages
122 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
123 {
124 if (Cache[I].Install() == true)
125 Fix.Protect(I);
126
127 if (_config->FindB("APT::Ignore-Hold",false) == false)
128 if (I->SelectedState == pkgCache::State::Hold)
129 continue;
130
131 if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
132 Cache.MarkInstall(I, false, 0, false);
133 }
134
135 return Fix.ResolveByKeep();
136 }
137 /*}}}*/
138 // AllUpgradeWithNewInstalls - Upgrade + install new packages as needed /*{{{*/
139 // ---------------------------------------------------------------------
140 /* Right now the system must be consistent before this can be called.
141 * Upgrade as much as possible without deleting anything (useful for
142 * stable systems)
143 */
144 static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache)
145 {
146 std::string const solver = _config->Find("APT::Solver", "internal");
147 if (solver != "internal") {
148 OpTextProgress Prog(*_config);
149 return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog);
150 }
151
152 pkgDepCache::ActionGroup group(Cache);
153
154 pkgProblemResolver Fix(&Cache);
155
156 if (Cache.BrokenCount() != 0)
157 return false;
158
159 // provide the initial set of stuff we want to upgrade by marking
160 // all upgradable packages for upgrade
161 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
162 {
163 if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
164 {
165 if (_config->FindB("APT::Ignore-Hold",false) == false)
166 if (I->SelectedState == pkgCache::State::Hold)
167 continue;
168
169 Cache.MarkInstall(I, false, 0, false);
170 }
171 }
172
173 // then let auto-install loose
174 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
175 if (Cache[I].Install())
176 Cache.MarkInstall(I, true, 0, false);
177
178 // ... but it may remove stuff, we we need to clean up afterwards again
179 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
180 if (Cache[I].Delete() == true)
181 Cache.MarkKeep(I, false, false);
182
183 // resolve remaining issues via keep
184 return Fix.ResolveByKeep();
185 }
186 /*}}}*/
187 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
188 // ---------------------------------------------------------------------
189 /* Right now the system must be consistent before this can be called.
190 It also will not change packages marked for install, it only tries
191 to install packages not marked for install */
192 bool pkgAllUpgrade(pkgDepCache &Cache)
193 {
194 return pkgAllUpgradeNoNewPackages(Cache);
195 }
196 /*}}}*/
197 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
198 // ---------------------------------------------------------------------
199 /* This simply goes over the entire set of packages and tries to keep
200 each package marked for upgrade. If a conflict is generated then
201 the package is restored. */
202 bool pkgMinimizeUpgrade(pkgDepCache &Cache)
203 {
204 pkgDepCache::ActionGroup group(Cache);
205
206 if (Cache.BrokenCount() != 0)
207 return false;
208
209 // We loop for 10 tries to get the minimal set size.
210 bool Change = false;
211 unsigned int Count = 0;
212 do
213 {
214 Change = false;
215 for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
216 {
217 // Not interesting
218 if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
219 continue;
220
221 // Keep it and see if that is OK
222 Cache.MarkKeep(I, false, false);
223 if (Cache.BrokenCount() != 0)
224 Cache.MarkInstall(I, false, 0, false);
225 else
226 {
227 // If keep didn't actually do anything then there was no change..
228 if (Cache[I].Upgrade() == false)
229 Change = true;
230 }
231 }
232 ++Count;
233 }
234 while (Change == true && Count < 10);
235
236 if (Cache.BrokenCount() != 0)
237 return _error->Error("Internal Error in pkgMinimizeUpgrade");
238
239 return true;
240 }
241 /*}}}*/
242 // APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/
243 bool APT::Upgrade::Upgrade(pkgDepCache &Cache, int mode)
244 {
245 if (mode == 0)
246 {
247 return pkgDistUpgrade(Cache);
248 }
249 else if ((mode & ~FORBID_REMOVE_PACKAGES) == 0)
250 {
251 return pkgAllUpgradeWithNewPackages(Cache);
252 }
253 else if ((mode & ~(FORBID_REMOVE_PACKAGES|FORBID_INSTALL_NEW_PACKAGES)) == 0)
254 {
255 return pkgAllUpgradeNoNewPackages(Cache);
256 }
257 else
258 _error->Error("pkgAllUpgrade called with unsupported mode %i", mode);
259
260 return false;
261 }
262 /*}}}*/