summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorMichael Vogt <mvo@debian.org>2013-10-22 21:24:13 +0200
committerMichael Vogt <mvo@debian.org>2013-10-22 21:24:13 +0200
commit4c9234d668bc1a250fd1af4c5d90497a08be67fd (patch)
tree6f7851c01a98a98013625af3de28cceeab3e2db9 /apt-pkg
parentc08cf1dc784a98a253296a51433f6de7d16d3125 (diff)
parent3f506f684c6199a9a2bc68365732a9c00dc551c1 (diff)
Merge remote-tracking branch 'mvo/feature/upgrade-api' into debian/sid
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/algorithms.cc310
-rw-r--r--apt-pkg/algorithms.h18
-rw-r--r--apt-pkg/makefile5
-rw-r--r--apt-pkg/update.cc126
-rw-r--r--apt-pkg/update.h21
-rw-r--r--apt-pkg/upgrade.cc263
-rw-r--r--apt-pkg/upgrade.h30
7 files changed, 450 insertions, 323 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index 69d4acd83..8644a8138 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -336,217 +336,6 @@ bool pkgFixBroken(pkgDepCache &Cache)
return Fix.Resolve(true);
}
/*}}}*/
-// DistUpgrade - Distribution upgrade /*{{{*/
-// ---------------------------------------------------------------------
-/* This autoinstalls every package and then force installs every
- pre-existing package. This creates the initial set of conditions which
- most likely contain problems because too many things were installed.
-
- The problem resolver is used to resolve the problems.
- */
-bool pkgDistUpgrade(pkgDepCache &Cache)
-{
- std::string const solver = _config->Find("APT::Solver", "internal");
- if (solver != "internal") {
- OpTextProgress Prog(*_config);
- return EDSP::ResolveExternal(solver.c_str(), Cache, false, true, false, &Prog);
- }
-
- pkgDepCache::ActionGroup group(Cache);
-
- /* Upgrade all installed packages first without autoinst to help the resolver
- in versioned or-groups to upgrade the old solver instead of installing
- a new one (if the old solver is not the first one [anymore]) */
- for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
- if (I->CurrentVer != 0)
- Cache.MarkInstall(I, false, 0, false);
-
- /* Auto upgrade all installed packages, this provides the basis
- for the installation */
- for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
- if (I->CurrentVer != 0)
- Cache.MarkInstall(I, true, 0, false);
-
- /* Now, install each essential package which is not installed
- (and not provided by another package in the same name group) */
- std::string essential = _config->Find("pkgCacheGen::Essential", "all");
- if (essential == "all")
- {
- for (pkgCache::GrpIterator G = Cache.GrpBegin(); G.end() == false; ++G)
- {
- bool isEssential = false;
- bool instEssential = false;
- for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P))
- {
- if ((P->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential)
- continue;
- isEssential = true;
- if (Cache[P].Install() == true)
- {
- instEssential = true;
- break;
- }
- }
- if (isEssential == false || instEssential == true)
- continue;
- pkgCache::PkgIterator P = G.FindPreferredPkg();
- Cache.MarkInstall(P, true, 0, false);
- }
- }
- else if (essential != "none")
- for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
- if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
- Cache.MarkInstall(I, true, 0, false);
-
- /* We do it again over all previously installed packages to force
- conflict resolution on them all. */
- for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
- if (I->CurrentVer != 0)
- Cache.MarkInstall(I, false, 0, false);
-
- pkgProblemResolver Fix(&Cache);
-
- // Hold back held packages.
- if (_config->FindB("APT::Ignore-Hold",false) == false)
- {
- for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
- {
- if (I->SelectedState == pkgCache::State::Hold)
- {
- Fix.Protect(I);
- Cache.MarkKeep(I, false, false);
- }
- }
- }
-
- return Fix.Resolve();
-}
- /*}}}*/
-// AllUpgrade - Upgrade as many packages as possible /*{{{*/
-// ---------------------------------------------------------------------
-/* Right now the system must be consistent before this can be called.
- It also will not change packages marked for install, it only tries
- to install packages not marked for install */
-bool pkgAllUpgrade(pkgDepCache &Cache)
-{
- std::string const solver = _config->Find("APT::Solver", "internal");
- if (solver != "internal") {
- OpTextProgress Prog(*_config);
- return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog);
- }
-
- pkgDepCache::ActionGroup group(Cache);
-
- pkgProblemResolver Fix(&Cache);
-
- if (Cache.BrokenCount() != 0)
- return false;
-
- // Upgrade all installed packages
- for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
- {
- if (Cache[I].Install() == true)
- Fix.Protect(I);
-
- if (_config->FindB("APT::Ignore-Hold",false) == false)
- if (I->SelectedState == pkgCache::State::Hold)
- continue;
-
- if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
- Cache.MarkInstall(I, false, 0, false);
- }
-
- return Fix.ResolveByKeep();
-}
- /*}}}*/
-// AllUpgradeNoDelete - Upgrade without removing packages /*{{{*/
-// ---------------------------------------------------------------------
-/* Right now the system must be consistent before this can be called.
- * Upgrade as much as possible without deleting anything (useful for
- * stable systems)
- */
-bool pkgAllUpgradeNoDelete(pkgDepCache &Cache)
-{
- pkgDepCache::ActionGroup group(Cache);
-
- pkgProblemResolver Fix(&Cache);
-
- if (Cache.BrokenCount() != 0)
- return false;
-
- // provide the initial set of stuff we want to upgrade by marking
- // all upgradable packages for upgrade
- for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
- {
- if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
- {
- if (_config->FindB("APT::Ignore-Hold",false) == false)
- if (I->SelectedState == pkgCache::State::Hold)
- continue;
-
- Cache.MarkInstall(I, false, 0, false);
- }
- }
-
- // then let auto-install loose
- for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
- if (Cache[I].Install())
- Cache.MarkInstall(I, true, 0, false);
-
- // ... but it may remove stuff, we we need to clean up afterwards again
- for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
- if (Cache[I].Delete() == true)
- Cache.MarkKeep(I, false, false);
-
- // resolve remaining issues via keep
- return Fix.ResolveByKeep();
-}
- /*}}}*/
-// MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
-// ---------------------------------------------------------------------
-/* This simply goes over the entire set of packages and tries to keep
- each package marked for upgrade. If a conflict is generated then
- the package is restored. */
-bool pkgMinimizeUpgrade(pkgDepCache &Cache)
-{
- pkgDepCache::ActionGroup group(Cache);
-
- if (Cache.BrokenCount() != 0)
- return false;
-
- // We loop for 10 tries to get the minimal set size.
- bool Change = false;
- unsigned int Count = 0;
- do
- {
- Change = false;
- for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
- {
- // Not interesting
- if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
- continue;
-
- // Keep it and see if that is OK
- Cache.MarkKeep(I, false, false);
- if (Cache.BrokenCount() != 0)
- Cache.MarkInstall(I, false, 0, false);
- else
- {
- // If keep didnt actually do anything then there was no change..
- if (Cache[I].Upgrade() == false)
- Change = true;
- }
- }
- ++Count;
- }
- while (Change == true && Count < 10);
-
- if (Cache.BrokenCount() != 0)
- return _error->Error("Internal Error in pkgMinimizeUpgrade");
-
- return true;
-}
- /*}}}*/
// ProblemResolver::pkgProblemResolver - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -1548,102 +1337,3 @@ void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List)
qsort(List,Count,sizeof(*List),PrioComp);
}
/*}}}*/
-// ListUpdate - construct Fetcher and update the cache files /*{{{*/
-// ---------------------------------------------------------------------
-/* This is a simple wrapper to update the cache. it will fetch stuff
- * from the network (or any other sources defined in sources.list)
- */
-bool ListUpdate(pkgAcquireStatus &Stat,
- pkgSourceList &List,
- int PulseInterval)
-{
- pkgAcquire Fetcher;
- if (Fetcher.Setup(&Stat, _config->FindDir("Dir::State::Lists")) == false)
- return false;
-
- // Populate it with the source selection
- if (List.GetIndexes(&Fetcher) == false)
- return false;
-
- return AcquireUpdate(Fetcher, PulseInterval, true);
-}
- /*}}}*/
-// AcquireUpdate - take Fetcher and update the cache files /*{{{*/
-// ---------------------------------------------------------------------
-/* This is a simple wrapper to update the cache with a provided acquire
- * If you only need control over Status and the used SourcesList use
- * ListUpdate method instead.
- */
-bool AcquireUpdate(pkgAcquire &Fetcher, int const PulseInterval,
- bool const RunUpdateScripts, bool const ListCleanup)
-{
- // Run scripts
- if (RunUpdateScripts == true)
- RunScripts("APT::Update::Pre-Invoke");
-
- pkgAcquire::RunResult res;
- if(PulseInterval > 0)
- res = Fetcher.Run(PulseInterval);
- else
- res = Fetcher.Run();
-
- if (res == pkgAcquire::Failed)
- return false;
-
- bool Failed = false;
- bool TransientNetworkFailure = false;
- for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin();
- I != Fetcher.ItemsEnd(); ++I)
- {
- if ((*I)->Status == pkgAcquire::Item::StatDone)
- continue;
-
- (*I)->Finished();
-
- ::URI uri((*I)->DescURI());
- uri.User.clear();
- uri.Password.clear();
- string descUri = string(uri);
- _error->Warning(_("Failed to fetch %s %s\n"), descUri.c_str(),
- (*I)->ErrorText.c_str());
-
- if ((*I)->Status == pkgAcquire::Item::StatTransientNetworkError)
- {
- TransientNetworkFailure = true;
- continue;
- }
-
- Failed = true;
- }
-
- // Clean out any old list files
- // Keep "APT::Get::List-Cleanup" name for compatibility, but
- // this is really a global option for the APT library now
- if (!TransientNetworkFailure && !Failed && ListCleanup == true &&
- (_config->FindB("APT::Get::List-Cleanup",true) == true &&
- _config->FindB("APT::List-Cleanup",true) == true))
- {
- if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
- Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
- // something went wrong with the clean
- return false;
- }
-
- if (TransientNetworkFailure == true)
- _error->Warning(_("Some index files failed to download. They have been ignored, or old ones used instead."));
- else if (Failed == true)
- return _error->Error(_("Some index files failed to download. They have been ignored, or old ones used instead."));
-
-
- // Run the success scripts if all was fine
- if (RunUpdateScripts == true)
- {
- if(!TransientNetworkFailure && !Failed)
- RunScripts("APT::Update::Post-Invoke-Success");
-
- // Run the other scripts
- RunScripts("APT::Update::Post-Invoke");
- }
- return true;
-}
- /*}}}*/
diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h
index a499db8ba..80f6578eb 100644
--- a/apt-pkg/algorithms.h
+++ b/apt-pkg/algorithms.h
@@ -40,10 +40,15 @@
#ifndef APT_8_CLEANER_HEADERS
#include <apt-pkg/acquire.h>
+// include pkg{DistUpgrade,AllUpgrade,MiniizeUpgrade} here for compatiblity
using std::ostream;
#endif
-class pkgAcquireStatus;
+#ifndef APT_9_CLEANER_HEADERS
+#include <apt-pkg/upgrade.h>
+#include <apt-pkg/update.h>
+#endif
+
class pkgSimulate : public pkgPackageManager /*{{{*/
{
@@ -85,6 +90,7 @@ private:
/*}}}*/
class pkgProblemResolver /*{{{*/
{
+ private:
/** \brief dpointer placeholder (for later in case we need it) */
void *d;
@@ -140,20 +146,10 @@ class pkgProblemResolver /*{{{*/
~pkgProblemResolver();
};
/*}}}*/
-bool pkgDistUpgrade(pkgDepCache &Cache);
bool pkgApplyStatus(pkgDepCache &Cache);
bool pkgFixBroken(pkgDepCache &Cache);
-bool pkgAllUpgrade(pkgDepCache &Cache);
-
-bool pkgAllUpgradeNoDelete(pkgDepCache &Cache);
-
-bool pkgMinimizeUpgrade(pkgDepCache &Cache);
-
void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List);
-bool ListUpdate(pkgAcquireStatus &progress, pkgSourceList &List, int PulseInterval=0);
-bool AcquireUpdate(pkgAcquire &Fetcher, int const PulseInterval = 0,
- bool const RunUpdateScripts = true, bool const ListCleanup = true);
#endif
diff --git a/apt-pkg/makefile b/apt-pkg/makefile
index 59729faf5..dc943aad4 100644
--- a/apt-pkg/makefile
+++ b/apt-pkg/makefile
@@ -43,7 +43,8 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \
srcrecords.cc cachefile.cc versionmatch.cc policy.cc \
pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \
indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \
- aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc
+ aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc \
+ upgrade.cc update.cc
HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \
orderlist.h sourcelist.h packagemanager.h tagfile.h \
init.h pkgcache.h version.h progress.h pkgrecords.h \
@@ -51,7 +52,7 @@ HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \
clean.h srcrecords.h cachefile.h versionmatch.h policy.h \
pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \
vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \
- cachefilter.h cacheset.h edsp.h
+ cachefilter.h cacheset.h edsp.h upgrade.h update.h
# Source code for the debian specific components
# In theory the deb headers do not need to be exported..
diff --git a/apt-pkg/update.cc b/apt-pkg/update.cc
new file mode 100644
index 000000000..97be5490b
--- /dev/null
+++ b/apt-pkg/update.cc
@@ -0,0 +1,126 @@
+
+// Include Files /*{{{*/
+#include <config.h>
+
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/update.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/edsp.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/progress.h>
+
+#include <sys/types.h>
+#include <cstdlib>
+#include <algorithm>
+#include <iostream>
+#include <stdio.h>
+
+#include <apti18n.h>
+ /*}}}*/
+
+using namespace std;
+
+// ListUpdate - construct Fetcher and update the cache files /*{{{*/
+// ---------------------------------------------------------------------
+/* This is a simple wrapper to update the cache. it will fetch stuff
+ * from the network (or any other sources defined in sources.list)
+ */
+bool ListUpdate(pkgAcquireStatus &Stat,
+ pkgSourceList &List,
+ int PulseInterval)
+{
+ pkgAcquire Fetcher;
+ if (Fetcher.Setup(&Stat, _config->FindDir("Dir::State::Lists")) == false)
+ return false;
+
+ // Populate it with the source selection
+ if (List.GetIndexes(&Fetcher) == false)
+ return false;
+
+ return AcquireUpdate(Fetcher, PulseInterval, true);
+}
+ /*}}}*/
+// AcquireUpdate - take Fetcher and update the cache files /*{{{*/
+// ---------------------------------------------------------------------
+/* This is a simple wrapper to update the cache with a provided acquire
+ * If you only need control over Status and the used SourcesList use
+ * ListUpdate method instead.
+ */
+bool AcquireUpdate(pkgAcquire &Fetcher, int const PulseInterval,
+ bool const RunUpdateScripts, bool const ListCleanup)
+{
+ // Run scripts
+ if (RunUpdateScripts == true)
+ RunScripts("APT::Update::Pre-Invoke");
+
+ pkgAcquire::RunResult res;
+ if(PulseInterval > 0)
+ res = Fetcher.Run(PulseInterval);
+ else
+ res = Fetcher.Run();
+
+ if (res == pkgAcquire::Failed)
+ return false;
+
+ bool Failed = false;
+ bool TransientNetworkFailure = false;
+ for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin();
+ I != Fetcher.ItemsEnd(); ++I)
+ {
+ if ((*I)->Status == pkgAcquire::Item::StatDone)
+ continue;
+
+ (*I)->Finished();
+
+ ::URI uri((*I)->DescURI());
+ uri.User.clear();
+ uri.Password.clear();
+ string descUri = string(uri);
+ _error->Warning(_("Failed to fetch %s %s\n"), descUri.c_str(),
+ (*I)->ErrorText.c_str());
+
+ if ((*I)->Status == pkgAcquire::Item::StatTransientNetworkError)
+ {
+ TransientNetworkFailure = true;
+ continue;
+ }
+
+ Failed = true;
+ }
+
+ // Clean out any old list files
+ // Keep "APT::Get::List-Cleanup" name for compatibility, but
+ // this is really a global option for the APT library now
+ if (!TransientNetworkFailure && !Failed && ListCleanup == true &&
+ (_config->FindB("APT::Get::List-Cleanup",true) == true &&
+ _config->FindB("APT::List-Cleanup",true) == true))
+ {
+ if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
+ Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
+ // something went wrong with the clean
+ return false;
+ }
+
+ if (TransientNetworkFailure == true)
+ _error->Warning(_("Some index files failed to download. They have been ignored, or old ones used instead."));
+ else if (Failed == true)
+ return _error->Error(_("Some index files failed to download. They have been ignored, or old ones used instead."));
+
+
+ // Run the success scripts if all was fine
+ if (RunUpdateScripts == true)
+ {
+ if(!TransientNetworkFailure && !Failed)
+ RunScripts("APT::Update::Post-Invoke-Success");
+
+ // Run the other scripts
+ RunScripts("APT::Update::Post-Invoke");
+ }
+ return true;
+}
+ /*}}}*/
diff --git a/apt-pkg/update.h b/apt-pkg/update.h
new file mode 100644
index 000000000..3835644de
--- /dev/null
+++ b/apt-pkg/update.h
@@ -0,0 +1,21 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* ######################################################################
+
+ Update - ListUpdate releated code
+
+ ##################################################################### */
+ /*}}}*/
+
+#ifndef PKGLIB_UPDATE_H
+#define PKGLIB_UPDATE_H
+
+class pkgAcquireStatus;
+
+
+bool ListUpdate(pkgAcquireStatus &progress, pkgSourceList &List, int PulseInterval=0);
+bool AcquireUpdate(pkgAcquire &Fetcher, int const PulseInterval = 0,
+ bool const RunUpdateScripts = true, bool const ListCleanup = true);
+
+
+#endif
diff --git a/apt-pkg/upgrade.cc b/apt-pkg/upgrade.cc
new file mode 100644
index 000000000..f06f6d40d
--- /dev/null
+++ b/apt-pkg/upgrade.cc
@@ -0,0 +1,263 @@
+
+// Include Files /*{{{*/
+#include <config.h>
+
+#include <apt-pkg/algorithms.h>
+#include <apt-pkg/upgrade.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/configuration.h>
+#include <apt-pkg/version.h>
+#include <apt-pkg/sptr.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/edsp.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/progress.h>
+
+#include <sys/types.h>
+#include <cstdlib>
+#include <algorithm>
+#include <iostream>
+#include <stdio.h>
+
+#include <apti18n.h>
+ /*}}}*/
+
+// DistUpgrade - Distribution upgrade /*{{{*/
+// ---------------------------------------------------------------------
+/* This autoinstalls every package and then force installs every
+ pre-existing package. This creates the initial set of conditions which
+ most likely contain problems because too many things were installed.
+
+ The problem resolver is used to resolve the problems.
+ */
+bool pkgDistUpgrade(pkgDepCache &Cache)
+{
+ std::string const solver = _config->Find("APT::Solver", "internal");
+ if (solver != "internal") {
+ OpTextProgress Prog(*_config);
+ return EDSP::ResolveExternal(solver.c_str(), Cache, false, true, false, &Prog);
+ }
+
+ pkgDepCache::ActionGroup group(Cache);
+
+ /* Upgrade all installed packages first without autoinst to help the resolver
+ in versioned or-groups to upgrade the old solver instead of installing
+ a new one (if the old solver is not the first one [anymore]) */
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ if (I->CurrentVer != 0)
+ Cache.MarkInstall(I, false, 0, false);
+
+ /* Auto upgrade all installed packages, this provides the basis
+ for the installation */
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ if (I->CurrentVer != 0)
+ Cache.MarkInstall(I, true, 0, false);
+
+ /* Now, install each essential package which is not installed
+ (and not provided by another package in the same name group) */
+ std::string essential = _config->Find("pkgCacheGen::Essential", "all");
+ if (essential == "all")
+ {
+ for (pkgCache::GrpIterator G = Cache.GrpBegin(); G.end() == false; ++G)
+ {
+ bool isEssential = false;
+ bool instEssential = false;
+ for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P))
+ {
+ if ((P->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential)
+ continue;
+ isEssential = true;
+ if (Cache[P].Install() == true)
+ {
+ instEssential = true;
+ break;
+ }
+ }
+ if (isEssential == false || instEssential == true)
+ continue;
+ pkgCache::PkgIterator P = G.FindPreferredPkg();
+ Cache.MarkInstall(P, true, 0, false);
+ }
+ }
+ else if (essential != "none")
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+ Cache.MarkInstall(I, true, 0, false);
+
+ /* We do it again over all previously installed packages to force
+ conflict resolution on them all. */
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ if (I->CurrentVer != 0)
+ Cache.MarkInstall(I, false, 0, false);
+
+ pkgProblemResolver Fix(&Cache);
+
+ // Hold back held packages.
+ if (_config->FindB("APT::Ignore-Hold",false) == false)
+ {
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ {
+ if (I->SelectedState == pkgCache::State::Hold)
+ {
+ Fix.Protect(I);
+ Cache.MarkKeep(I, false, false);
+ }
+ }
+ }
+
+ return Fix.Resolve();
+}
+ /*}}}*/
+// AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs /*{{{*/
+static bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache)
+{
+ std::string const solver = _config->Find("APT::Solver", "internal");
+ if (solver != "internal") {
+ OpTextProgress Prog(*_config);
+ return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog);
+ }
+
+ pkgDepCache::ActionGroup group(Cache);
+
+ pkgProblemResolver Fix(&Cache);
+
+ if (Cache.BrokenCount() != 0)
+ return false;
+
+ // Upgrade all installed packages
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ {
+ if (Cache[I].Install() == true)
+ Fix.Protect(I);
+
+ if (_config->FindB("APT::Ignore-Hold",false) == false)
+ if (I->SelectedState == pkgCache::State::Hold)
+ continue;
+
+ if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
+ Cache.MarkInstall(I, false, 0, false);
+ }
+
+ return Fix.ResolveByKeep();
+}
+ /*}}}*/
+// AllUpgradeWithNewInstalls - Upgrade + install new packages as needed /*{{{*/
+// ---------------------------------------------------------------------
+/* Right now the system must be consistent before this can be called.
+ * Upgrade as much as possible without deleting anything (useful for
+ * stable systems)
+ */
+static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache)
+{
+ pkgDepCache::ActionGroup group(Cache);
+
+ pkgProblemResolver Fix(&Cache);
+
+ if (Cache.BrokenCount() != 0)
+ return false;
+
+ // provide the initial set of stuff we want to upgrade by marking
+ // all upgradable packages for upgrade
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ {
+ if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
+ {
+ if (_config->FindB("APT::Ignore-Hold",false) == false)
+ if (I->SelectedState == pkgCache::State::Hold)
+ continue;
+
+ Cache.MarkInstall(I, false, 0, false);
+ }
+ }
+
+ // then let auto-install loose
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ if (Cache[I].Install())
+ Cache.MarkInstall(I, true, 0, false);
+
+ // ... but it may remove stuff, we we need to clean up afterwards again
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ if (Cache[I].Delete() == true)
+ Cache.MarkKeep(I, false, false);
+
+ // resolve remaining issues via keep
+ return Fix.ResolveByKeep();
+}
+ /*}}}*/
+// AllUpgrade - Upgrade as many packages as possible /*{{{*/
+// ---------------------------------------------------------------------
+/* Right now the system must be consistent before this can be called.
+ It also will not change packages marked for install, it only tries
+ to install packages not marked for install */
+bool pkgAllUpgrade(pkgDepCache &Cache)
+{
+ return pkgAllUpgradeNoNewPackages(Cache);
+}
+ /*}}}*/
+// MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
+// ---------------------------------------------------------------------
+/* This simply goes over the entire set of packages and tries to keep
+ each package marked for upgrade. If a conflict is generated then
+ the package is restored. */
+bool pkgMinimizeUpgrade(pkgDepCache &Cache)
+{
+ pkgDepCache::ActionGroup group(Cache);
+
+ if (Cache.BrokenCount() != 0)
+ return false;
+
+ // We loop for 10 tries to get the minimal set size.
+ bool Change = false;
+ unsigned int Count = 0;
+ do
+ {
+ Change = false;
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I)
+ {
+ // Not interesting
+ if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
+ continue;
+
+ // Keep it and see if that is OK
+ Cache.MarkKeep(I, false, false);
+ if (Cache.BrokenCount() != 0)
+ Cache.MarkInstall(I, false, 0, false);
+ else
+ {
+ // If keep didnt actually do anything then there was no change..
+ if (Cache[I].Upgrade() == false)
+ Change = true;
+ }
+ }
+ ++Count;
+ }
+ while (Change == true && Count < 10);
+
+ if (Cache.BrokenCount() != 0)
+ return _error->Error("Internal Error in pkgMinimizeUpgrade");
+
+ return true;
+}
+ /*}}}*/
+// APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/
+bool APT::Upgrade::Upgrade(pkgDepCache &Cache, int mode)
+{
+ if (mode == 0)
+ {
+ return pkgDistUpgrade(Cache);
+ }
+ else if ((mode & ~FORBID_REMOVE_PACKAGES) == 0)
+ {
+ return pkgAllUpgradeWithNewPackages(Cache);
+ }
+ else if ((mode & ~(FORBID_REMOVE_PACKAGES|FORBID_INSTALL_NEW_PACKAGES)) == 0)
+ {
+ return pkgAllUpgradeNoNewPackages(Cache);
+ }
+ else
+ _error->Error("pkgAllUpgrade called with unsupported mode %i", mode);
+
+ return false;
+}
+ /*}}}*/
diff --git a/apt-pkg/upgrade.h b/apt-pkg/upgrade.h
new file mode 100644
index 000000000..c4973472f
--- /dev/null
+++ b/apt-pkg/upgrade.h
@@ -0,0 +1,30 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* ######################################################################
+
+ Upgrade - Upgrade/DistUpgrade releated code
+
+ ##################################################################### */
+ /*}}}*/
+
+#ifndef PKGLIB_UPGRADE_H
+#define PKGLIB_UPGRADE_H
+
+namespace APT {
+ namespace Upgrade {
+ // FIXME: make this "enum class UpgradeMode {" once we enable c++11
+ enum UpgradeMode {
+ FORBID_REMOVE_PACKAGES = 1,
+ FORBID_INSTALL_NEW_PACKAGES = 2,
+ };
+ bool Upgrade(pkgDepCache &Cache, int UpgradeMode);
+ }
+}
+
+// please use APT::Upgrade::Upgrade() instead
+bool pkgDistUpgrade(pkgDepCache &Cache);
+bool pkgAllUpgrade(pkgDepCache &Cache);
+bool pkgMinimizeUpgrade(pkgDepCache &Cache);
+
+
+#endif