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 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
);
152 pkgDepCache::ActionGroup
group(Cache
);
154 pkgProblemResolver
Fix(&Cache
);
156 if (Cache
.BrokenCount() != 0)
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
)
163 if (I
->CurrentVer
!= 0 && Cache
[I
].InstallVer
!= 0)
165 if (_config
->FindB("APT::Ignore-Hold",false) == false)
166 if (I
->SelectedState
== pkgCache::State::Hold
)
169 Cache
.MarkInstall(I
, false, 0, false);
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);
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);
183 // resolve remaining issues via keep
184 return Fix
.ResolveByKeep();
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
)
194 return pkgAllUpgradeNoNewPackages(Cache
);
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
)
204 pkgDepCache::ActionGroup
group(Cache
);
206 if (Cache
.BrokenCount() != 0)
209 // We loop for 10 tries to get the minimal set size.
211 unsigned int Count
= 0;
215 for (pkgCache::PkgIterator I
= Cache
.PkgBegin(); I
.end() == false; ++I
)
218 if (Cache
[I
].Upgrade() == false || Cache
[I
].NewInstall() == true)
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);
227 // If keep didn't actually do anything then there was no change..
228 if (Cache
[I
].Upgrade() == false)
234 while (Change
== true && Count
< 10);
236 if (Cache
.BrokenCount() != 0)
237 return _error
->Error("Internal Error in pkgMinimizeUpgrade");
242 // APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/
243 bool APT::Upgrade::Upgrade(pkgDepCache
&Cache
, int mode
)
247 return pkgDistUpgrade(Cache
);
249 else if ((mode
& ~FORBID_REMOVE_PACKAGES
) == 0)
251 return pkgAllUpgradeWithNewPackages(Cache
);
253 else if ((mode
& ~(FORBID_REMOVE_PACKAGES
|FORBID_INSTALL_NEW_PACKAGES
)) == 0)
255 return pkgAllUpgradeNoNewPackages(Cache
);
258 _error
->Error("pkgAllUpgrade called with unsupported mode %i", mode
);