X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/14bed2c0108a99d68f453ff61273d5ae59a5c3f0..70ff288b98a7aae2c2808112015d34f76f2d5114:/apt-pkg/edsp.cc diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index 21f7f3607..f56625feb 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -7,6 +7,7 @@ // Include Files /*{{{*/ #include +#include #include #include #include @@ -339,7 +340,7 @@ static bool WriteScenarioLimitedDependency(FileFd &output, static bool SkipUnavailableVersions(pkgDepCache &Cache, pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const &Ver)/*{{{*/ { /* versions which aren't current and aren't available in - any "online" source file are bad, expect if they are the choosen + any "online" source file are bad, expect if they are the chosen candidate: The exception is for build-dep implementation as it creates such pseudo (package) versions and removes them later on again. We filter out versions at all so packages in 'rc' state only available @@ -439,7 +440,7 @@ bool EDSP::WriteScenario(pkgDepCache &Cache, FileFd &output, OpProgress *Progres Progress->Progress(p); } } - return true; + return Okay; } /*}}}*/ // EDSP::WriteLimitedScenario - to the given file descriptor /*{{{*/ @@ -911,14 +912,14 @@ bool EDSP::WriteSolutionStanza(FileFd &output, char const * const Type, pkgCache /*}}}*/ // EDSP::WriteProgess - pulse to the given file descriptor /*{{{*/ bool EDSP::WriteProgress(unsigned short const percent, const char* const message, FILE* output) { - fprintf(output, "Progress: %s\n", TimeRFC1123(time(NULL)).c_str()); + fprintf(output, "Progress: %s\n", TimeRFC1123(time(NULL), true).c_str()); fprintf(output, "Percentage: %d\n", percent); fprintf(output, "Message: %s\n\n", message); fflush(output); return true; } bool EDSP::WriteProgress(unsigned short const percent, const char* const message, FileFd &output) { - return WriteOkay(output, "Progress: ", TimeRFC1123(time(NULL)), "\n", + return WriteOkay(output, "Progress: ", TimeRFC1123(time(NULL), true), "\n", "Percentage: ", percent, "\n", "Message: ", message, "\n\n") && output.Flush(); } @@ -1016,20 +1017,38 @@ bool EDSP::ExecuteSolver(const char* const solver, int *solver_in, int *solver_o return true; } /*}}}*/ +static bool CreateDumpFile(char const * const id, char const * const type, FileFd &output)/*{{{*/ +{ + auto const dumpfile = _config->FindFile((std::string("Dir::Log::") + type).c_str()); + if (dumpfile.empty()) + return false; + auto const dumpdir = flNotFile(dumpfile); + _error->PushToStack(); + bool errored_out = CreateAPTDirectoryIfNeeded(dumpdir, dumpdir) == false || + output.Open(dumpfile, FileFd::WriteOnly | FileFd::Exclusive | FileFd::Create, FileFd::Extension, 0644) == false; + std::vector downgrademsgs; + while (_error->empty() == false) + { + std::string msg; + _error->PopMessage(msg); + downgrademsgs.emplace_back(std::move(msg)); + } + _error->RevertToStack(); + for (auto && msg : downgrademsgs) + _error->Warning("%s", msg.c_str()); + if (errored_out) + return _error->WarningE(id, _("Could not open file '%s'"), dumpfile.c_str()); + return true; +} + /*}}}*/ // EDSP::ResolveExternal - resolve problems by asking external for help {{{*/ bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache, unsigned int const flags, OpProgress *Progress) { if (strcmp(solver, "internal") == 0) { - auto const dumpfile = _config->FindFile("Dir::Log::Solver"); - if (dumpfile.empty()) - return false; - auto const dumpdir = flNotFile(dumpfile); FileFd output; - if (CreateAPTDirectoryIfNeeded(dumpdir, dumpdir) == false || - output.Open(dumpfile, FileFd::WriteOnly | FileFd::Exclusive | FileFd::Create, FileFd::Extension, 0644) == false) - return _error->WarningE("EDSP::Resolve", _("Could not open file '%s'"), dumpfile.c_str()); - bool Okay = EDSP::WriteRequest(Cache, output, flags, nullptr); + bool Okay = CreateDumpFile("EDSP::Resolve", "solver", output); + Okay &= EDSP::WriteRequest(Cache, output, flags, nullptr); return Okay && EDSP::WriteScenario(Cache, output, nullptr); } int solver_in, solver_out; @@ -1042,20 +1061,21 @@ bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache, return _error->Errno("ResolveExternal", "Opening solver %s stdin on fd %d for writing failed", solver, solver_in); bool Okay = output.Failed() == false; - if (Progress != NULL) + if (Okay && Progress != NULL) Progress->OverallProgress(0, 100, 5, _("Execute external solver")); Okay &= EDSP::WriteRequest(Cache, output, flags, Progress); - if (Progress != NULL) + if (Okay && Progress != NULL) Progress->OverallProgress(5, 100, 20, _("Execute external solver")); Okay &= EDSP::WriteScenario(Cache, output, Progress); output.Close(); - if (Progress != NULL) + if (Okay && Progress != NULL) Progress->OverallProgress(25, 100, 75, _("Execute external solver")); if (Okay && EDSP::ReadResponse(solver_out, Cache, Progress) == false) return false; - return ExecWait(solver_pid, solver); + bool const waited = ExecWait(solver_pid, solver); + return Okay && waited; } bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache, bool const upgrade, bool const distUpgrade, @@ -1074,47 +1094,65 @@ bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache, bool EIPP::OrderInstall(char const * const solver, pkgPackageManager * const PM, /*{{{*/ unsigned int const flags, OpProgress * const Progress) { + if (strcmp(solver, "internal") == 0) + { + FileFd output; + _error->PushToStack(); + bool Okay = CreateDumpFile("EIPP::OrderInstall", "planner", output); + if (Okay == false && dynamic_cast(PM) != nullptr) + { + _error->RevertToStack(); + return false; + } + _error->MergeWithStack(); + Okay &= EIPP::WriteRequest(PM->Cache, output, flags, nullptr); + return Okay && EIPP::WriteScenario(PM->Cache, output, nullptr); + } + int solver_in, solver_out; - pid_t const solver_pid = ExecuteExternal("planer", solver, "Dir::Bin::Planers", &solver_in, &solver_out); + pid_t const solver_pid = ExecuteExternal("planner", solver, "Dir::Bin::Planners", &solver_in, &solver_out); if (solver_pid == 0) return false; FileFd output; if (output.OpenDescriptor(solver_in, FileFd::WriteOnly | FileFd::BufferedWrite, true) == false) - return _error->Errno("OrderInstall", "Opening planer %s stdin on fd %d for writing failed", solver, solver_in); + return _error->Errno("EIPP::OrderInstall", "Opening planner %s stdin on fd %d for writing failed", solver, solver_in); bool Okay = output.Failed() == false; - if (Progress != NULL) - Progress->OverallProgress(0, 100, 5, _("Execute external planer")); + if (Okay && Progress != NULL) + Progress->OverallProgress(0, 100, 5, _("Execute external planner")); Okay &= EIPP::WriteRequest(PM->Cache, output, flags, Progress); - if (Progress != NULL) - Progress->OverallProgress(5, 100, 20, _("Execute external planer")); + if (Okay && Progress != NULL) + Progress->OverallProgress(5, 100, 20, _("Execute external planner")); Okay &= EIPP::WriteScenario(PM->Cache, output, Progress); output.Close(); - if (Progress != NULL) - Progress->OverallProgress(25, 100, 75, _("Execute external planer")); - - // we don't tell the external planers about boring things - for (auto Pkg = PM->Cache.PkgBegin(); Pkg.end() == false; ++Pkg) + if (Okay) { - if (Pkg->CurrentState == pkgCache::State::ConfigFiles && PM->Cache[Pkg].Purge() == true) - PM->Remove(Pkg, true); + if (Progress != nullptr) + Progress->OverallProgress(25, 100, 75, _("Execute external planner")); + + // we don't tell the external planners about boring things + for (auto Pkg = PM->Cache.PkgBegin(); Pkg.end() == false; ++Pkg) + { + if (Pkg->CurrentState == pkgCache::State::ConfigFiles && PM->Cache[Pkg].Purge() == true) + PM->Remove(Pkg, true); + } } - if (Okay && EIPP::ReadResponse(solver_out, PM, Progress) == false) + if (EIPP::ReadResponse(solver_out, PM, Progress) == false) return false; - return ExecWait(solver_pid, solver); + bool const waited = ExecWait(solver_pid, solver); + return Okay && waited; } /*}}}*/ bool EIPP::WriteRequest(pkgDepCache &Cache, FileFd &output, /*{{{*/ unsigned int const flags, OpProgress * const Progress) { - (void)(flags); if (Progress != NULL) - Progress->SubProgress(Cache.Head().PackageCount, _("Send request to planer")); + Progress->SubProgress(Cache.Head().PackageCount, _("Send request to planner")); unsigned long p = 0; string del, inst, reinst; for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg, ++p) @@ -1151,7 +1189,13 @@ bool EIPP::WriteRequest(pkgDepCache &Cache, FileFd &output, /*{{{*/ WriteOkay(Okay, output, "Install:", inst, "\n"); if (reinst.empty() == false) WriteOkay(Okay, output, "ReInstall:", reinst, "\n"); - WriteOkay(Okay, output, "Planer: ", _config->Find("APT::Planer", "internal"), "\n"); + WriteOkay(Okay, output, "Planner: ", _config->Find("APT::Planner", "internal"), "\n"); + if ((flags & Request::IMMEDIATE_CONFIGURATION_ALL) != 0) + WriteOkay(Okay, output, "Immediate-Configuration: yes\n"); + else if ((flags & Request::NO_IMMEDIATE_CONFIGURATION) != 0) + WriteOkay(Okay, output, "Immediate-Configuration: no\n"); + else if ((flags & Request::ALLOW_TEMPORARY_REMOVE_OF_ESSENTIALS) != 0) + WriteOkay(Okay, output, "Allow-Temporary-Remove-of-Essentials: yes\n"); return WriteOkay(Okay, output, "\n"); } /*}}}*/ @@ -1198,7 +1242,7 @@ template void forAllInterestingVersions(pkgDepCache &Cache, bool EIPP::WriteScenario(pkgDepCache &Cache, FileFd &output, OpProgress * const Progress) { if (Progress != NULL) - Progress->SubProgress(Cache.Head().PackageCount, _("Send scenario to planer")); + Progress->SubProgress(Cache.Head().PackageCount, _("Send scenario to planner")); unsigned long p = 0; bool Okay = output.Failed() == false; std::vector archs = APT::Configuration::getArchitectures(); @@ -1265,7 +1309,7 @@ bool EIPP::WriteScenario(pkgDepCache &Cache, FileFd &output, OpProgress * const continue; forAllInterestingVersions(Cache, Pkg, WriteVersion); } - return true; + return Okay; } /*}}}*/ // EIPP::ReadResponse - from the given file descriptor /*{{{*/ @@ -1299,18 +1343,18 @@ bool EIPP::ReadResponse(int const input, pkgPackageManager * const PM, OpProgres } else if (section.Exists("Error") == true) { std::string msg = SubstVar(SubstVar(section.FindS("Message"), "\n .\n", "\n\n"), "\n ", "\n"); if (msg.empty() == true) { - msg = _("External planer failed without a proper error message"); + msg = _("External planner failed without a proper error message"); _error->Error("%s", msg.c_str()); } else - _error->Error("External planer failed with: %s", msg.substr(0,msg.find('\n')).c_str()); + _error->Error("External planner failed with: %s", msg.substr(0,msg.find('\n')).c_str()); if (Progress != NULL) Progress->Done(); - std::cerr << "The planer encountered an error of type: " << section.FindS("Error") << std::endl; + std::cerr << "The planner encountered an error of type: " << section.FindS("Error") << std::endl; std::cerr << "The following information might help you to understand what is wrong:" << std::endl; std::cerr << msg << std::endl << std::endl; return false; - } else if (section.Exists("Install") == true) - type = "Install"; + } else if (section.Exists("Unpack") == true) + type = "Unpack"; else if (section.Exists("Configure") == true) type = "Configure"; else if (section.Exists("Remove") == true) @@ -1335,14 +1379,14 @@ bool EIPP::ReadResponse(int const input, pkgPackageManager * const PM, OpProgres pkgCache::VerIterator Ver(PM->Cache.GetCache(), PM->Cache.GetCache().VerP + VerIdx[id]); auto const Pkg = Ver.ParentPkg(); - if (strcmp(type, "Install") == 0) + if (strcmp(type, "Unpack") == 0) PM->Install(Pkg, PM->FileNames[Pkg->ID]); else if (strcmp(type, "Configure") == 0) PM->Configure(Pkg); else if (strcmp(type, "Remove") == 0) PM->Remove(Pkg, PM->Cache[Pkg].Purge()); } - return true; + return in.Failed() == false; } /*}}}*/ bool EIPP::ReadRequest(int const input, std::list> &actions,/*{{{*/ @@ -1377,8 +1421,17 @@ bool EIPP::ReadRequest(int const input, std::listSet("APT::Architecture", line); else if (LineStartsWithAndStrip(line, "Architectures:")) _config->Set("APT::Architectures", SubstVar(line, " ", ",")); - else if (LineStartsWithAndStrip(line, "Planer:")) + else if (LineStartsWithAndStrip(line, "Planner:")) ; // purely informational line + else if (LineStartsWithAndStrip(line, "Immediate-Configuration:")) + { + if (localStringToBool(line, true)) + flags |= Request::IMMEDIATE_CONFIGURATION_ALL; + else + flags |= Request::NO_IMMEDIATE_CONFIGURATION; + } + else if (ReadFlag(flags, line, "Allow-Temporary-Remove-of-Essentials:", Request::ALLOW_TEMPORARY_REMOVE_OF_ESSENTIALS)) + ; else _error->Warning("Unknown line in EIPP Request stanza: %s", line.c_str()); @@ -1389,9 +1442,6 @@ bool EIPP::ReadRequest(int const input, std::list> &actions,/*{{{*/