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 bool pkgDistUpgrade(pkgDepCache
&Cache
)
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
);
35 pkgDepCache::ActionGroup
group(Cache
);
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);
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);
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")
55 for (pkgCache::GrpIterator G
= Cache
.GrpBegin(); G
.end() == false; ++G
)
57 bool isEssential
= false;
58 bool instEssential
= false;
59 for (pkgCache::PkgIterator P
= G
.PackageList(); P
.end() == false; P
= G
.NextPkg(P
))
61 if ((P
->Flags
& pkgCache::Flag::Essential
) != pkgCache::Flag::Essential
)
64 if (Cache
[P
].Install() == true)
70 if (isEssential
== false || instEssential
== true)
72 pkgCache::PkgIterator P
= G
.FindPreferredPkg();
73 Cache
.MarkInstall(P
, true, 0, false);
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);
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);
87 pkgProblemResolver
Fix(&Cache
);
89 // Hold back held packages.
90 if (_config
->FindB("APT::Ignore-Hold",false) == false)
92 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
94 if (I
->SelectedState
== pkgCache::State::Hold
)
97 Cache
.MarkKeep(I
, false, false);
102 return Fix
.Resolve();
105 // AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs /*{{{*/
106 static bool pkgAllUpgradeNoNewPackages(pkgDepCache
&Cache
)
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
);
114 pkgDepCache::ActionGroup
group(Cache
);
116 pkgProblemResolver
Fix(&Cache
);
118 if (Cache
.BrokenCount() != 0)
121 // Upgrade all installed packages
122 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
124 if (Cache
[I
].Install() == true)
127 if (_config
->FindB("APT::Ignore-Hold",false) == false)
128 if (I
->SelectedState
== pkgCache::State::Hold
)
131 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
132 Cache
.MarkInstall(I
, false, 0, false);
135 return Fix
.ResolveByKeep();
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
144 static bool pkgAllUpgradeWithNewPackages(pkgDepCache
&Cache
)
146 pkgDepCache::ActionGroup
group(Cache
);
148 pkgProblemResolver
Fix(&Cache
);
150 if (Cache
.BrokenCount() != 0)
153 // provide the initial set of stuff we want to upgrade by marking
154 // all upgradable packages for upgrade
155 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
157 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
159 if (_config
->FindB("APT::Ignore-Hold",false) == false)
160 if (I
->SelectedState
== pkgCache::State::Hold
)
163 Cache
.MarkInstall(I
, false, 0, false);
167 // then let auto-install loose
168 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
169 if (Cache
[I
].Install())
170 Cache
.MarkInstall(I
, true, 0, false);
172 // ... but it may remove stuff, we we need to clean up afterwards again
173 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
174 if (Cache
[I
].Delete() == true)
175 Cache
.MarkKeep(I
, false, false);
177 // resolve remaining issues via keep
178 return Fix
.ResolveByKeep();
181 // AllUpgrade - Upgrade as many packages as possible /*{{{*/
182 // ---------------------------------------------------------------------
183 /* Right now the system must be consistent before this can be called.
184 It also will not change packages marked for install, it only tries
185 to install packages not marked for install */
186 bool pkgAllUpgrade(pkgDepCache
&Cache
)
188 return pkgAllUpgradeNoNewPackages(Cache
);
191 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
192 // ---------------------------------------------------------------------
193 /* This simply goes over the entire set of packages and tries to keep
194 each package marked for upgrade. If a conflict is generated then
195 the package is restored. */
196 bool pkgMinimizeUpgrade(pkgDepCache
&Cache
)
198 pkgDepCache::ActionGroup
group(Cache
);
200 if (Cache
.BrokenCount() != 0)
203 // We loop for 10 tries to get the minimal set size.
205 unsigned int Count
= 0;
209 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
212 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
215 // Keep it and see if that is OK
216 Cache
.MarkKeep(I
, false, false);
217 if (Cache
.BrokenCount() != 0)
218 Cache
.MarkInstall(I
, false, 0, false);
221 // If keep didn't actually do anything then there was no change..
222 if (Cache
[I
].Upgrade() == false)
228 while (Change
== true && Count
< 10);
230 if (Cache
.BrokenCount() != 0)
231 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
236 // APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/
237 bool APT::Upgrade::Upgrade(pkgDepCache
&Cache
, int mode
)
241 return pkgDistUpgrade(Cache
);
243 else if ((mode
& ~FORBID_REMOVE_PACKAGES
) == 0)
245 return pkgAllUpgradeWithNewPackages(Cache
);
247 else if ((mode
& ~(FORBID_REMOVE_PACKAGES
|FORBID_INSTALL_NEW_PACKAGES
)) == 0)
249 return pkgAllUpgradeNoNewPackages(Cache
);
252 _error
->Error("pkgAllUpgrade called with unsupported mode %i", mode
);