apt  2.2.4
About: Apt (Advanced Package Tool) is a management system for software packages (Debian/Ubuntu). Release series 2.2.
  Fossies Dox: apt-2.2.4.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

upgrade.cc
Go to the documentation of this file.
1 // Include Files /*{{{*/
2 #include <config.h>
3 
4 #include <apt-pkg/algorithms.h>
5 #include <apt-pkg/configuration.h>
6 #include <apt-pkg/depcache.h>
7 #include <apt-pkg/edsp.h>
8 #include <apt-pkg/error.h>
9 #include <apt-pkg/pkgcache.h>
10 #include <apt-pkg/progress.h>
11 #include <apt-pkg/upgrade.h>
12 
13 #include <string>
14 
15 #include <apti18n.h>
16  /*}}}*/
17 
18 // DistUpgrade - Distribution upgrade /*{{{*/
19 // ---------------------------------------------------------------------
20 /* This autoinstalls every package and then force installs every
21  pre-existing package. This creates the initial set of conditions which
22  most likely contain problems because too many things were installed.
23 
24  The problem resolver is used to resolve the problems.
25  */
26 static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
27 {
28  std::string const solver = _config->Find("APT::Solver", "internal");
29  auto const ret = EDSP::ResolveExternal(solver.c_str(), Cache, EDSP::Request::UPGRADE_ALL, Progress);
30  if (solver != "internal")
31  return ret;
32 
33  if (Progress != NULL)
34  Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
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 
45  if (Progress != NULL)
46  Progress->Progress(10);
47 
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 
54  if (Progress != NULL)
55  Progress->Progress(50);
56 
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  {
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)
86  Cache.MarkInstall(I, true, 0, false);
87 
88  if (Progress != NULL)
89  Progress->Progress(55);
90 
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 
97  if (Progress != NULL)
98  Progress->Progress(65);
99 
100  pkgProblemResolver Fix(&Cache);
101 
102  if (Progress != NULL)
103  Progress->Progress(95);
104 
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  }
117 
118  bool const success = Fix.ResolveInternal(false);
119  if (Progress != NULL)
120  Progress->Done();
121  return success;
122 } /*}}}*/
123 // AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs /*{{{*/
124 static bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache, OpProgress * const Progress)
125 {
126  std::string const solver = _config->Find("APT::Solver", "internal");
128  auto const ret = EDSP::ResolveExternal(solver.c_str(), Cache, flags, Progress);
129  if (solver != "internal")
130  return ret;
131 
132  if (Progress != NULL)
133  Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
134 
135  pkgDepCache::ActionGroup group(Cache);
136  pkgProblemResolver Fix(&Cache);
137 
138  // Upgrade all installed packages
139  for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
140  {
141  if (Cache[I].Install() == true)
142  Fix.Protect(I);
143 
144  if (_config->FindB("APT::Ignore-Hold",false) == false)
145  if (I->SelectedState == pkgCache::State::Hold)
146  continue;
147 
148  if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
149  Cache.MarkInstall(I, false, 0, false);
150  }
151 
152  if (Progress != NULL)
153  Progress->Progress(50);
154 
155  // resolve remaining issues via keep
156  bool const success = Fix.ResolveByKeepInternal();
157  if (Progress != NULL)
158  Progress->Done();
159  return success;
160 }
161  /*}}}*/
162 // AllUpgradeWithNewInstalls - Upgrade + install new packages as needed /*{{{*/
163 // ---------------------------------------------------------------------
164 /* Right now the system must be consistent before this can be called.
165  * Upgrade as much as possible without deleting anything (useful for
166  * stable systems)
167  */
168 static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache, OpProgress * const Progress)
169 {
170  std::string const solver = _config->Find("APT::Solver", "internal");
172  auto const ret = EDSP::ResolveExternal(solver.c_str(), Cache, flags, Progress);
173  if (solver != "internal")
174  return ret;
175 
176  if (Progress != NULL)
177  Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
178 
179  pkgDepCache::ActionGroup group(Cache);
180  pkgProblemResolver Fix(&Cache);
181 
182  // provide the initial set of stuff we want to upgrade by marking
183  // all upgradable packages for upgrade
184  for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
185  {
186  if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
187  {
188  if (_config->FindB("APT::Ignore-Hold",false) == false)
189  if (I->SelectedState == pkgCache::State::Hold)
190  continue;
191 
192  Cache.MarkInstall(I, false, 0, false);
193  }
194  }
195 
196  if (Progress != NULL)
197  Progress->Progress(10);
198 
199  // then let auto-install loose
200  for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
201  if (Cache[I].Install())
202  Cache.MarkInstall(I, true, 0, false);
203 
204  if (Progress != NULL)
205  Progress->Progress(50);
206 
207  // ... but it may remove stuff, we need to clean up afterwards again
208  for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
209  if (Cache[I].Delete() == true)
210  Cache.MarkKeep(I, false, false);
211 
212  if (Progress != NULL)
213  Progress->Progress(60);
214 
215  // resolve remaining issues via keep
216  bool const success = Fix.ResolveByKeepInternal();
217  if (Progress != NULL)
218  Progress->Done();
219  return success;
220 }
221  /*}}}*/
222 // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
223 // ---------------------------------------------------------------------
224 /* This simply goes over the entire set of packages and tries to keep
225  each package marked for upgrade. If a conflict is generated then
226  the package is restored. */
228 {
229  pkgDepCache::ActionGroup group(Cache);
230 
231  if (Cache.BrokenCount() != 0)
232  return false;
233 
234  // We loop for 10 tries to get the minimal set size.
235  bool Change = false;
236  unsigned int Count = 0;
237  do
238  {
239  Change = false;
240  for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
241  {
242  // Not interesting
243  if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
244  continue;
245 
246  // Keep it and see if that is OK
247  Cache.MarkKeep(I, false, false);
248  if (Cache.BrokenCount() != 0)
249  Cache.MarkInstall(I, false, 0, false);
250  else
251  {
252  // If keep didn't actually do anything then there was no change..
253  if (Cache[I].Upgrade() == false)
254  Change = true;
255  }
256  }
257  ++Count;
258  }
259  while (Change == true && Count < 10);
260 
261  if (Cache.BrokenCount() != 0)
262  return _error->Error("Internal Error in pkgMinimizeUpgrade");
263 
264  return true;
265 }
266  /*}}}*/
267 // APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/
268 bool APT::Upgrade::Upgrade(pkgDepCache &Cache, int mode, OpProgress * const Progress)
269 {
270  if (mode == ALLOW_EVERYTHING)
271  return pkgDistUpgrade(Cache, Progress);
272  else if ((mode & ~FORBID_REMOVE_PACKAGES) == 0)
273  return pkgAllUpgradeWithNewPackages(Cache, Progress);
274  else if ((mode & ~(FORBID_REMOVE_PACKAGES|FORBID_INSTALL_NEW_PACKAGES)) == 0)
275  return pkgAllUpgradeNoNewPackages(Cache, Progress);
276  else
277  _error->Error("pkgAllUpgrade called with unsupported mode %i", mode);
278  return false;
279 }
280  /*}}}*/
static bool std::string const metaIndex const *const pkgAcqMetaClearSig *const pkgAcquire::Item *const I
std::string Find(const char *Name, const char *Default=0) const
bool FindB(const char *Name, bool const &Default=false) const
virtual void Done()
Definition: progress.h:60
void OverallProgress(unsigned long long Current, unsigned long long Total, unsigned long long Size, const std::string &Op)
Definition: progress.cc:55
void Progress(unsigned long long Current)
Definition: progress.cc:43
Represents an active action group.
Definition: depcache.h:166
bool MarkKeep(PkgIterator const &Pkg, bool Soft=false, bool FromUser=true, unsigned long Depth=0)
Definition: depcache.cc:931
bool MarkInstall(PkgIterator const &Pkg, bool AutoInst=true, unsigned long Depth=0, bool FromUser=true, bool ForceImportantDeps=false)
Definition: depcache.cc:1560
PkgIterator PkgBegin()
Definition: depcache.h:356
unsigned long BrokenCount()
Definition: depcache.h:497
GrpIterator GrpBegin()
Definition: depcache.h:355
APT_HIDDEN bool ResolveByKeepInternal()
Definition: algorithms.cc:1265
APT_HIDDEN bool ResolveInternal(bool const BrokenFix=false)
Definition: algorithms.cc:764
void Protect(pkgCache::PkgIterator Pkg)
Definition: algorithms.h:130
Configuration * _config
@ FORBID_REMOVE_PACKAGES
Definition: upgrade.h:23
@ FORBID_INSTALL_NEW_PACKAGES
Definition: upgrade.h:24
@ ALLOW_EVERYTHING
Definition: upgrade.h:25
APT_PUBLIC bool Upgrade(pkgDepCache &Cache, int UpgradeMode, OpProgress *const Progress=NULL)
Definition: upgrade.cc:268
@ FORBID_REMOVE
Definition: edsp.h:35
@ FORBID_NEW_INSTALL
Definition: edsp.h:34
@ UPGRADE_ALL
Definition: edsp.h:33
APT_PUBLIC bool ResolveExternal(const char *const solver, pkgDepCache &Cache, unsigned int const flags=0, OpProgress *Progress=NULL)
call an external resolver to handle the request
Definition: edsp.cc:748
pkgCache - Structure definitions for the cache file
Definition: rred.cc:136
static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache, OpProgress *const Progress)
Definition: upgrade.cc:168
static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress *const Progress)
Definition: upgrade.cc:26
bool pkgMinimizeUpgrade(pkgDepCache &Cache)
Definition: upgrade.cc:227
static bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache, OpProgress *const Progress)
Definition: upgrade.cc:124