summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/algorithms.cc6
-rw-r--r--apt-pkg/edsp.cc95
-rw-r--r--apt-pkg/edsp.h27
-rw-r--r--apt-pkg/upgrade.cc10
-rw-r--r--cmdline/apt-internal-solver.cc21
-rw-r--r--doc/external-dependency-solver-protocol.txt27
6 files changed, 139 insertions, 47 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index fbc809ed0..d202951a9 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -637,7 +637,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix, OpProgress * const Progress)
{
std::string const solver = _config->Find("APT::Solver", "internal");
if (solver != "internal")
- return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false, Progress);
+ return EDSP::ResolveExternal(solver.c_str(), Cache, 0, Progress);
return ResolveInternal(BrokenFix);
}
/*}}}*/
@@ -1134,7 +1134,9 @@ bool pkgProblemResolver::ResolveByKeep(OpProgress * const Progress)
{
std::string const solver = _config->Find("APT::Solver", "internal");
if (solver != "internal")
- return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, Progress);
+ return EDSP::ResolveExternal(solver.c_str(), Cache,
+ EDSP::Request::UPGRADE_ALL | EDSP::Request::FORBID_NEW_INSTALL | EDSP::Request::FORBID_REMOVE,
+ Progress);
return ResolveByKeepInternal();
}
/*}}}*/
diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc
index 9596a9eb3..6fd97845b 100644
--- a/apt-pkg/edsp.cc
+++ b/apt-pkg/edsp.cc
@@ -527,8 +527,8 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade,
fprintf(output, "\n");
return true;
}
-bool EDSP::WriteRequest(pkgDepCache &Cache, FileFd &output, bool const Upgrade,
- bool const DistUpgrade, bool const AutoRemove,
+bool EDSP::WriteRequest(pkgDepCache &Cache, FileFd &output,
+ unsigned int const flags,
OpProgress *Progress)
{
if (Progress != NULL)
@@ -564,12 +564,20 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FileFd &output, bool const Upgrade,
WriteOkay(Okay, output, "Remove:", del, "\n");
if (inst.empty() == false)
WriteOkay(Okay, output, "Install:", inst, "\n");
- if (Upgrade == true)
- WriteOkay(Okay, output, "Upgrade: yes\n");
- if (DistUpgrade == true)
- WriteOkay(Okay, output, "Dist-Upgrade: yes\n");
- if (AutoRemove == true)
+ if (flags & Request::AUTOREMOVE)
WriteOkay(Okay, output, "Autoremove: yes\n");
+ if (flags & Request::UPGRADE_ALL)
+ {
+ WriteOkay(Okay, output, "Upgrade-All: yes\n");
+ if (flags & (Request::FORBID_NEW_INSTALL | Request::FORBID_REMOVE))
+ WriteOkay(Okay, output, "Upgrade: yes\n");
+ else
+ WriteOkay(Okay, output, "Dist-Upgrade: yes\n");
+ }
+ if (flags & Request::FORBID_NEW_INSTALL)
+ WriteOkay(Okay, output, "Forbid-New-Install: yes\n");
+ if (flags & Request::FORBID_REMOVE)
+ WriteOkay(Okay, output, "Forbid-Remove: yes\n");
if (_config->FindB("APT::Solver::Strict-Pinning", true) == false)
WriteOkay(Okay, output, "Strict-Pinning: no\n");
string solverpref("APT::Solver::");
@@ -711,15 +719,23 @@ static bool StringToBool(char const *answer, bool const defValue) {
}
/*}}}*/
// EDSP::ReadRequest - first stanza from the given file descriptor /*{{{*/
+static bool ReadFlag(unsigned int &flags, std::string const &line, APT::StringView const name, unsigned int const setflag)
+{
+ if (line.compare(0, name.length(), name.data()) != 0)
+ return false;
+ auto const l = line.c_str() + name.length() + 1;
+ if (StringToBool(l, false))
+ flags |= setflag;
+ else
+ flags &= ~setflag;
+ return true;
+}
bool EDSP::ReadRequest(int const input, std::list<std::string> &install,
- std::list<std::string> &remove, bool &upgrade,
- bool &distUpgrade, bool &autoRemove)
+ std::list<std::string> &remove, unsigned int &flags)
{
install.clear();
remove.clear();
- upgrade = false;
- distUpgrade = false;
- autoRemove = false;
+ flags = 0;
std::string line;
while (ReadLine(input, line) == true)
{
@@ -747,12 +763,13 @@ bool EDSP::ReadRequest(int const input, std::list<std::string> &install,
line.erase(0, 7);
request = &remove;
}
- else if (line.compare(0, 8, "Upgrade:") == 0)
- upgrade = StringToBool(line.c_str() + 9, false);
- else if (line.compare(0, 13, "Dist-Upgrade:") == 0)
- distUpgrade = StringToBool(line.c_str() + 14, false);
- else if (line.compare(0, 11, "Autoremove:") == 0)
- autoRemove = StringToBool(line.c_str() + 12, false);
+ else if (ReadFlag(flags, line, "Upgrade:", (Request::UPGRADE_ALL | Request::FORBID_REMOVE | Request::FORBID_NEW_INSTALL)) ||
+ ReadFlag(flags, line, "Dist-Upgrade:", Request::UPGRADE_ALL) ||
+ ReadFlag(flags, line, "Upgrade-All:", Request::UPGRADE_ALL) ||
+ ReadFlag(flags, line, "Forbid-New-Install:", Request::FORBID_NEW_INSTALL) ||
+ ReadFlag(flags, line, "Forbid-Remove:", Request::FORBID_REMOVE) ||
+ ReadFlag(flags, line, "Autoremove:", Request::AUTOREMOVE))
+ ;
else if (line.compare(0, 13, "Architecture:") == 0)
_config->Set("APT::Architecture", line.c_str() + 14);
else if (line.compare(0, 14, "Architectures:") == 0)
@@ -784,6 +801,31 @@ bool EDSP::ReadRequest(int const input, std::list<std::string> &install,
}
return false;
}
+bool EDSP::ReadRequest(int const input, std::list<std::string> &install,
+ std::list<std::string> &remove, bool &upgrade,
+ bool &distUpgrade, bool &autoRemove)
+{
+ unsigned int flags;
+ auto const ret = ReadRequest(input, install, remove, flags);
+ autoRemove = (flags & Request::AUTOREMOVE);
+ if (flags & Request::UPGRADE_ALL)
+ {
+ if (flags & (Request::FORBID_NEW_INSTALL | Request::FORBID_REMOVE))
+ {
+ upgrade = true;
+ distUpgrade = false;
+ } else {
+ upgrade = false;
+ distUpgrade = false;
+ }
+ }
+ else
+ {
+ upgrade = false;
+ distUpgrade = false;
+ }
+ return ret;
+}
/*}}}*/
// EDSP::ApplyRequest - first stanza from the given file descriptor /*{{{*/
bool EDSP::ApplyRequest(std::list<std::string> const &install,
@@ -954,8 +996,7 @@ bool EDSP::ExecuteSolver(const char* const solver, int *solver_in, int *solver_o
/*}}}*/
// EDSP::ResolveExternal - resolve problems by asking external for help {{{*/
bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache,
- bool const upgrade, bool const distUpgrade,
- bool const autoRemove, OpProgress *Progress) {
+ unsigned int const flags, OpProgress *Progress) {
int solver_in, solver_out;
pid_t const solver_pid = EDSP::ExecuteSolver(solver, &solver_in, &solver_out, true);
if (solver_pid == 0)
@@ -968,7 +1009,7 @@ bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache,
bool Okay = output.Failed() == false;
if (Progress != NULL)
Progress->OverallProgress(0, 100, 5, _("Execute external solver"));
- Okay &= EDSP::WriteRequest(Cache, output, upgrade, distUpgrade, autoRemove, Progress);
+ Okay &= EDSP::WriteRequest(Cache, output, flags, Progress);
if (Progress != NULL)
Progress->OverallProgress(5, 100, 20, _("Execute external solver"));
Okay &= EDSP::WriteScenario(Cache, output, Progress);
@@ -981,4 +1022,16 @@ bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache,
return ExecWait(solver_pid, solver);
}
+bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache,
+ bool const upgrade, bool const distUpgrade,
+ bool const autoRemove, OpProgress *Progress) {
+ unsigned int flags = 0;
+ if (autoRemove)
+ flags |= Request::AUTOREMOVE;
+ if (upgrade)
+ flags |= Request::UPGRADE_ALL | Request::FORBID_REMOVE | Request::FORBID_NEW_INSTALL;
+ if (distUpgrade)
+ flags |= Request::UPGRADE_ALL;
+ return ResolveExternal(solver, Cache, flags, Progress);
+}
/*}}}*/
diff --git a/apt-pkg/edsp.h b/apt-pkg/edsp.h
index 433600bcd..9e92e59d9 100644
--- a/apt-pkg/edsp.h
+++ b/apt-pkg/edsp.h
@@ -29,6 +29,16 @@ class OpProgress;
namespace EDSP /*{{{*/
{
+ namespace Request
+ {
+ enum Flags
+ {
+ AUTOREMOVE = (1 << 0), /*!< removal of unneeded packages should be performed */
+ UPGRADE_ALL = (1 << 1), /*!< upgrade all installed packages, like 'apt-get full-upgrade' without forbid flags */
+ FORBID_NEW_INSTALL = (1 << 2), /*!< forbid the resolver to install new packages */
+ FORBID_REMOVE = (1 << 3), /*!< forbid the resolver to remove packages */
+ };
+ }
/** \brief creates the EDSP request stanza
*
* In the EDSP protocol the first thing send to the resolver is a stanza
@@ -38,17 +48,13 @@ namespace EDSP /*{{{*/
*
* \param Cache in which the request is encoded
* \param output is written to this "file"
- * \param upgrade is true if it is an request like apt-get upgrade
- * \param distUpgrade is true if it is a request like apt-get dist-upgrade
- * \param autoRemove is true if removal of unneeded packages should be performed
+ * \param flags effecting the request documented in #EDSP::Request::Flags
* \param Progress is an instance to report progress to
*
* \return true if request was composed successfully, otherwise false
*/
bool WriteRequest(pkgDepCache &Cache, FileFd &output,
- bool const upgrade = false,
- bool const distUpgrade = false,
- bool const autoRemove = false,
+ unsigned int const flags = 0,
OpProgress *Progress = NULL);
bool WriteRequest(pkgDepCache &Cache, FILE* output,
bool const upgrade = false,
@@ -130,6 +136,8 @@ namespace EDSP /*{{{*/
* \return true if the request could be found and worked on, otherwise false
*/
bool ReadRequest(int const input, std::list<std::string> &install,
+ std::list<std::string> &remove, unsigned int &flags);
+ APT_DEPRECATED_MSG("use the flag-based version instead") bool ReadRequest(int const input, std::list<std::string> &install,
std::list<std::string> &remove, bool &upgrade,
bool &distUpgrade, bool &autoRemove);
@@ -212,15 +220,16 @@ namespace EDSP /*{{{*/
*
* \param solver to execute
* \param Cache with the problem and as universe to work in
- * \param upgrade is true if it is a request like apt-get upgrade
- * \param distUpgrade is true if it is a request like apt-get dist-upgrade
- * \param autoRemove is true if unneeded packages should be removed
+ * \param flags effecting the request documented in #EDSP::Request::Flags
* \param Progress is an instance to report progress to
*
* \return true if the solver has successfully solved the problem,
* otherwise false
*/
bool ResolveExternal(const char* const solver, pkgDepCache &Cache,
+ unsigned int const flags = 0,
+ OpProgress *Progress = NULL);
+ APT_DEPRECATED_MSG("use the flag-based version instead") bool ResolveExternal(const char* const solver, pkgDepCache &Cache,
bool const upgrade, bool const distUpgrade,
bool const autoRemove, OpProgress *Progress = NULL);
}
diff --git a/apt-pkg/upgrade.cc b/apt-pkg/upgrade.cc
index 06707847e..8ba48e786 100644
--- a/apt-pkg/upgrade.cc
+++ b/apt-pkg/upgrade.cc
@@ -28,7 +28,7 @@ static bool pkgDistUpgrade(pkgDepCache &Cache, OpProgress * const Progress)
{
std::string const solver = _config->Find("APT::Solver", "internal");
if (solver != "internal")
- return EDSP::ResolveExternal(solver.c_str(), Cache, false, true, false, Progress);
+ return EDSP::ResolveExternal(solver.c_str(), Cache, EDSP::Request::UPGRADE_ALL, Progress);
if (Progress != NULL)
Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
@@ -130,7 +130,9 @@ static bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache, OpProgress * const Pr
{
std::string const solver = _config->Find("APT::Solver", "internal");
if (solver != "internal")
- return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, Progress);
+ return EDSP::ResolveExternal(solver.c_str(), Cache,
+ EDSP::Request::UPGRADE_ALL | EDSP::Request::FORBID_NEW_INSTALL | EDSP::Request::FORBID_REMOVE,
+ Progress);
if (Progress != NULL)
Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
@@ -172,7 +174,9 @@ static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache, OpProgress * const
{
std::string const solver = _config->Find("APT::Solver", "internal");
if (solver != "internal")
- return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, Progress);
+ return EDSP::ResolveExternal(solver.c_str(), Cache,
+ EDSP::Request::UPGRADE_ALL | EDSP::Request::FORBID_REMOVE,
+ Progress);
if (Progress != NULL)
Progress->OverallProgress(0, 100, 1, _("Calculating upgrade"));
diff --git a/cmdline/apt-internal-solver.cc b/cmdline/apt-internal-solver.cc
index 2df1d3bef..fa54657c0 100644
--- a/cmdline/apt-internal-solver.cc
+++ b/cmdline/apt-internal-solver.cc
@@ -121,8 +121,8 @@ int main(int argc,const char *argv[]) /*{{{*/
DIE("WAIT timed out in the resolver");
std::list<std::string> install, remove;
- bool upgrade, distUpgrade, autoRemove;
- if (EDSP::ReadRequest(input, install, remove, upgrade, distUpgrade, autoRemove) == false)
+ unsigned int flags;
+ if (EDSP::ReadRequest(input, install, remove, flags) == false)
DIE("Parsing the request failed!");
EDSP::WriteProgress(5, "Read scenario…", output);
@@ -159,12 +159,19 @@ int main(int argc,const char *argv[]) /*{{{*/
EDSP::WriteProgress(60, "Call problemresolver on current scenario…", output);
std::string failure;
- if (upgrade == true) {
- if (APT::Upgrade::Upgrade(CacheFile, APT::Upgrade::FORBID_REMOVE_PACKAGES | APT::Upgrade::FORBID_INSTALL_NEW_PACKAGES) == false)
+ if (flags & EDSP::Request::UPGRADE_ALL) {
+ int upgrade_flags = APT::Upgrade::ALLOW_EVERYTHING;
+ if (flags & EDSP::Request::FORBID_NEW_INSTALL)
+ upgrade_flags |= APT::Upgrade::FORBID_INSTALL_NEW_PACKAGES;
+ if (flags & EDSP::Request::FORBID_REMOVE)
+ upgrade_flags |= APT::Upgrade::FORBID_REMOVE_PACKAGES;
+
+ if (APT::Upgrade::Upgrade(CacheFile, upgrade_flags))
+ ;
+ else if (upgrade_flags == APT::Upgrade::ALLOW_EVERYTHING)
+ failure = "ERR_UNSOLVABLE_FULL_UPGRADE";
+ else
failure = "ERR_UNSOLVABLE_UPGRADE";
- } else if (distUpgrade == true) {
- if (APT::Upgrade::Upgrade(CacheFile, APT::Upgrade::ALLOW_EVERYTHING) == false)
- failure = "ERR_UNSOLVABLE_DIST_UPGRADE";
} else if (Fix.Resolve() == false)
failure = "ERR_UNSOLVABLE";
diff --git a/doc/external-dependency-solver-protocol.txt b/doc/external-dependency-solver-protocol.txt
index 9b9073346..c932b8b77 100644
--- a/doc/external-dependency-solver-protocol.txt
+++ b/doc/external-dependency-solver-protocol.txt
@@ -156,17 +156,26 @@ The following **action fields** are supported in request stanzas:
Install. This field denotes a list of packages that the user wants to
remove, usually via APT `remove` or `purge` requests.
-- **Upgrade:** (optional, defaults to `no`). Allowed values: `yes`,
+- **Upgrade-All:** (optional, defaults to `no`). Allowed values `yes`,
`no`. When set to `yes`, an upgrade of all installed packages has been
- requested, usually via an APT `upgrade` request.
-
-- **Dist-Upgrade:** (optional, defaults to `no`). Allowed values: `yes`,
- `no`. Same as Upgrade, but for APT `dist-upgrade` requests.
+ requested, usually via an upgrade command like 'apt full-upgrade'.
- **Autoremove:** (optional, defaults to `no`). Allowed values: `yes`,
`no`. When set to `yes`, a clean up of unused automatically installed
packages has been requested, usually via an APT `autoremove` request.
+- **Upgrade:** (deprecated, optional, defaults to `no`). Allowed values:
+ `yes`, `no`. When set to `yes`, an upgrade of all installed packages
+ has been requested, usually via an APT `upgrade` request. A value of
+ `yes` is equivalent to the fields `Upgrade-All`,
+ `Forbid-New-Install`and `Forbid-Remove` all set to `yes`.
+
+- **Dist-Upgrade:** (deprecated, optional, defaults to `no`). Allowed
+ values: `yes`, `no`. Same as Upgrade, but for APT `dist-upgrade`
+ requests. A value of `yes` is equivalent to the field `Upgrade-All`
+ set to `yes` and the fields `Forbid-New-Install`and `Forbid-Remove`
+ set to `no`.
+
The following **preference fields** are supported in request stanzas:
- **Strict-Pinning:** (optional, defaults to `yes`). Allowed values:
@@ -178,6 +187,14 @@ The following **preference fields** are supported in request stanzas:
field comes from the `APT::Solver::Strict-Pinning` configuration
option.
+- **Forbid-New-Install:* (optional, defaults to `no`). Allowed values:
+ `yes`, `no`. When set to `yes` the resolver is forbidden to install
+ new packages in its returned solution.
+
+- **Forbid-Remove:* (optional, defaults to `no`). Allowed values: `yes`,
+ `no`. When set to `yes` the resolver is forbidden to remove currently
+ installed packages in its returned solution.
+
- **Solver:** (optional, defaults to the empty string) a purely
informational string specifying to which solver this request was send
initially.