From 6d38011bb93451dd9da3294614d821c77ac91687 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 30 Mar 2011 17:23:43 +0200 Subject: add a first round of stuff needed for talking between APT and solvers based on a very early draft for EDSP by Stefano APT can now write a scenario as well as load most stuff from it. --- apt-pkg/algorithms.cc | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 0b4366e5e..2ca3404a0 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -20,12 +20,15 @@ #include #include #include - +#include + #include #include #include #include #include + +#include /*}}}*/ using namespace std; @@ -731,7 +734,25 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) return true; } /*}}}*/ -// ProblemResolver::Resolve - Run the resolution pass /*{{{*/ +// ProblemResolver::Resolve - calls a resolver to fix the situation /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgProblemResolver::Resolve(bool BrokenFix) +{ + std::string const solver = _config->Find("APT::Solver::Name", "internal"); + if (solver != "internal") + { + FILE* output = fopen("/tmp/universe.log", "w"); + edspWriter::WriteUniverse(Cache, output); + fclose(output); + output = fopen("/tmp/request.log", "w"); + edspWriter::WriteRequest(Cache, output); + fclose(output); + } + return ResolveInternal(BrokenFix); +} + /*}}}*/ +// ProblemResolver::ResolveInternal - Run the resolution pass /*{{{*/ // --------------------------------------------------------------------- /* This routines works by calculating a score for each package. The score is derived by considering the package's priority and all reverse @@ -745,12 +766,10 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) The BrokenFix flag enables a mode where the algorithm tries to upgrade packages to advoid problems. */ -bool pkgProblemResolver::Resolve(bool BrokenFix) +bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) { pkgDepCache::ActionGroup group(Cache); - unsigned long Size = Cache.Head().PackageCount; - // Record which packages are marked for install bool Again = false; do @@ -780,7 +799,9 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) clog << "Starting" << endl; MakeScores(); - + + unsigned long const Size = Cache.Head().PackageCount; + /* We have to order the packages so that the broken fixing pass operates from highest score to lowest. This prevents problems when high score packages cause the removal of lower score packages that -- cgit v1.2.3-70-g09d2 From e3674d91d27a7290d2b01e14eb2540e10be9d883 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 30 Mar 2011 22:15:40 +0200 Subject: be able to write solutions, too --- apt-pkg/algorithms.cc | 6 ++++++ apt-pkg/edsp/edspwriter.cc | 20 ++++++++++++++++++++ apt-pkg/edsp/edspwriter.h | 1 + 3 files changed, 27 insertions(+) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 2ca3404a0..35752a5c4 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -748,6 +748,12 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) output = fopen("/tmp/request.log", "w"); edspWriter::WriteRequest(Cache, output); fclose(output); + if (ResolveInternal(BrokenFix) == false) + return false; + output = fopen("/tmp/solution.log", "w"); + edspWriter::WriteSolution(Cache, output); + fclose(output); + return true; } return ResolveInternal(BrokenFix); } diff --git a/apt-pkg/edsp/edspwriter.cc b/apt-pkg/edsp/edspwriter.cc index 38d0d82c5..ea46065c2 100644 --- a/apt-pkg/edsp/edspwriter.cc +++ b/apt-pkg/edsp/edspwriter.cc @@ -125,6 +125,26 @@ bool edspWriter::WriteRequest(pkgDepCache &Cache, FILE* output) if (upgrade.empty() == false) fprintf(output, "Upgrade: %s\n", upgrade.c_str()+2); + return true; +} + /*}}}*/ +// edspWriter::WriteSolution - to the given file descriptor /*{{{*/ +bool edspWriter::WriteSolution(pkgDepCache &Cache, FILE* output) +{ + bool const Debug = _config->FindB("Debug::EDSPWriter::WriteSolution", false); + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) + { + if (Cache[Pkg].Delete() == true) + fprintf(output, "Remove: %d\n", Cache.GetCandidateVer(Pkg)->ID); + else if (Cache[Pkg].NewInstall() == true || Cache[Pkg].Upgrade() == true) + fprintf(output, "Install: %d\n", Cache.GetCandidateVer(Pkg)->ID); + else + continue; + if (Debug == true) + fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Cache.GetCandidateVer(Pkg).VerStr()); + fprintf(output, "\n"); + } + return true; } /*}}}*/ diff --git a/apt-pkg/edsp/edspwriter.h b/apt-pkg/edsp/edspwriter.h index 52923ff73..c42dfd398 100644 --- a/apt-pkg/edsp/edspwriter.h +++ b/apt-pkg/edsp/edspwriter.h @@ -14,6 +14,7 @@ class edspWriter /*{{{*/ public: bool static WriteUniverse(pkgDepCache &Cache, FILE* output); bool static WriteRequest(pkgDepCache &Cache, FILE* output); + bool static WriteSolution(pkgDepCache &Cache, FILE* output); }; /*}}}*/ #endif -- cgit v1.2.3-70-g09d2 From e0a78caad639a3fa8d50edf3374a06805ab86315 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 31 Mar 2011 11:58:24 +0200 Subject: rename the 'universe' to 'scenario' to reflect the naming in the draft --- apt-pkg/algorithms.cc | 4 ++-- apt-pkg/edsp/edspindexfile.cc | 6 +++--- apt-pkg/edsp/edspindexfile.h | 2 +- apt-pkg/edsp/edspsystem.cc | 10 +++++----- apt-pkg/edsp/edspwriter.cc | 2 +- apt-pkg/edsp/edspwriter.h | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 35752a5c4..b55ff2897 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -742,8 +742,8 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) std::string const solver = _config->Find("APT::Solver::Name", "internal"); if (solver != "internal") { - FILE* output = fopen("/tmp/universe.log", "w"); - edspWriter::WriteUniverse(Cache, output); + FILE* output = fopen("/tmp/scenario.log", "w"); + edspWriter::WriteScenario(Cache, output); fclose(output); output = fopen("/tmp/request.log", "w"); edspWriter::WriteRequest(Cache, output); diff --git a/apt-pkg/edsp/edspindexfile.cc b/apt-pkg/edsp/edspindexfile.cc index 366325d0f..f5881e663 100644 --- a/apt-pkg/edsp/edspindexfile.cc +++ b/apt-pkg/edsp/edspindexfile.cc @@ -1,7 +1,7 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ /* ###################################################################### - The universe file is designed to work as an intermediate file between + The scenario file is designed to work as an intermediate file between APT and the resolver. Its on propose very similar to a dpkg status file ##################################################################### */ /*}}}*/ @@ -51,7 +51,7 @@ bool edspIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const return _error->Errno("fstat","Failed to stat"); CFile->Size = St.st_size; CFile->mtime = St.st_mtime; - CFile->Archive = Gen.WriteUniqString("universe"); + CFile->Archive = Gen.WriteUniqString("edsp::scenario"); if (Gen.MergeList(Parser) == false) return _error->Error("Problem with MergeList %s",File.c_str()); @@ -67,7 +67,7 @@ class edspIFType: public pkgIndexFile::Type // we don't have a record parser for this type as the file is not presistent return NULL; }; - edspIFType() {Label = "APT universe file";}; + edspIFType() {Label = "EDSP scenario file";}; }; static edspIFType _apt_Universe; diff --git a/apt-pkg/edsp/edspindexfile.h b/apt-pkg/edsp/edspindexfile.h index 4ef7787e7..87c06557c 100644 --- a/apt-pkg/edsp/edspindexfile.h +++ b/apt-pkg/edsp/edspindexfile.h @@ -1,7 +1,7 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ /* ###################################################################### - The universe file is designed to work as an intermediate file between + The scenario file is designed to work as an intermediate file between APT and the resolver. Its on propose very similar to a dpkg status file ##################################################################### */ /*}}}*/ diff --git a/apt-pkg/edsp/edspsystem.cc b/apt-pkg/edsp/edspsystem.cc index c8e417b1d..3a0494e19 100644 --- a/apt-pkg/edsp/edspsystem.cc +++ b/apt-pkg/edsp/edspsystem.cc @@ -2,7 +2,7 @@ // Description /*{{{*/ /* ###################################################################### - This system provides the abstraction to use the universe file as the + This system provides the abstraction to use the scenario file as the only source of package information to be able to feed the created file back to APT for its own consumption (eat your own dogfood). @@ -86,9 +86,9 @@ bool edspSystem::ArchiveSupported(const char *Type) // System::Score - Determine if we should use the edsp system /*{{{*/ signed edspSystem::Score(Configuration const &Cnf) { - if (Cnf.Find("Dir::State::universe", "") == "stdin") + if (Cnf.Find("Dir::State::edsp::scenario", "") == "stdin") return 1000; - if (FileExists(Cnf.FindFile("Dir::State::universe","")) == true) + if (FileExists(Cnf.FindFile("Dir::State::edsp::scenario","")) == true) return 1000; return -1000; } @@ -98,10 +98,10 @@ bool edspSystem::AddStatusFiles(vector &List) { if (StatusFile == 0) { - if (_config->Find("Dir::State::universe", "") == "stdin") + if (_config->Find("Dir::State::edsp::scenario", "") == "stdin") StatusFile = new edspIndex("stdin"); else - StatusFile = new edspIndex(_config->FindFile("Dir::State::universe")); + StatusFile = new edspIndex(_config->FindFile("Dir::State::edsp::scenario")); } List.push_back(StatusFile); return true; diff --git a/apt-pkg/edsp/edspwriter.cc b/apt-pkg/edsp/edspwriter.cc index ea46065c2..5c741c45d 100644 --- a/apt-pkg/edsp/edspwriter.cc +++ b/apt-pkg/edsp/edspwriter.cc @@ -18,7 +18,7 @@ /*}}}*/ // edspWriter::WriteUniverse - to the given file descriptor /*{{{*/ -bool edspWriter::WriteUniverse(pkgDepCache &Cache, FILE* output) +bool edspWriter::WriteScenario(pkgDepCache &Cache, FILE* output) { // we could use pkgCache::DepType and ::Priority, but these would be lokalized strings… const char * const PrioMap[] = {0, "important", "required", "standard", diff --git a/apt-pkg/edsp/edspwriter.h b/apt-pkg/edsp/edspwriter.h index c42dfd398..2b417956e 100644 --- a/apt-pkg/edsp/edspwriter.h +++ b/apt-pkg/edsp/edspwriter.h @@ -12,7 +12,7 @@ class edspWriter /*{{{*/ { public: - bool static WriteUniverse(pkgDepCache &Cache, FILE* output); + bool static WriteScenario(pkgDepCache &Cache, FILE* output); bool static WriteRequest(pkgDepCache &Cache, FILE* output); bool static WriteSolution(pkgDepCache &Cache, FILE* output); }; -- cgit v1.2.3-70-g09d2 From c3b851268e6e900be2bf0bd715435db9010fd591 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 31 Mar 2011 15:10:13 +0200 Subject: rename edspwriter to straight edsp in toplevel as it does more than just writing stuff… it also reads and can work for both: - APT talking to an external solver - an external solver (understanding EDSP) talking to APT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apt-pkg/algorithms.cc | 8 +-- apt-pkg/edsp.cc | 160 +++++++++++++++++++++++++++++++++++++++++++++ apt-pkg/edsp.h | 32 +++++++++ apt-pkg/edsp/edspwriter.cc | 160 --------------------------------------------- apt-pkg/edsp/edspwriter.h | 32 --------- apt-pkg/makefile | 9 ++- 6 files changed, 200 insertions(+), 201 deletions(-) create mode 100644 apt-pkg/edsp.cc create mode 100644 apt-pkg/edsp.h delete mode 100644 apt-pkg/edsp/edspwriter.cc delete mode 100644 apt-pkg/edsp/edspwriter.h (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index b55ff2897..00f558420 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include @@ -743,15 +743,15 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) if (solver != "internal") { FILE* output = fopen("/tmp/scenario.log", "w"); - edspWriter::WriteScenario(Cache, output); + EDSP::WriteScenario(Cache, output); fclose(output); output = fopen("/tmp/request.log", "w"); - edspWriter::WriteRequest(Cache, output); + EDSP::WriteRequest(Cache, output); fclose(output); if (ResolveInternal(BrokenFix) == false) return false; output = fopen("/tmp/solution.log", "w"); - edspWriter::WriteSolution(Cache, output); + EDSP::WriteSolution(Cache, output); fclose(output); return true; } diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc new file mode 100644 index 000000000..1af5aed53 --- /dev/null +++ b/apt-pkg/edsp.cc @@ -0,0 +1,160 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + Set of methods to help writing and reading everything needed for EDSP + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include +#include + +#include +#include + +#include + /*}}}*/ + +// EDSP::WriteScenario - to the given file descriptor /*{{{*/ +bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output) +{ + // we could use pkgCache::DepType and ::Priority, but these would be lokalized strings… + const char * const PrioMap[] = {0, "important", "required", "standard", + "optional", "extra"}; + const char * const DepMap[] = {"", "Depends", "PreDepends", "Suggests", + "Recommends" , "Conflicts", "Replaces", + "Obsoletes", "Breaks", "Enhances"}; + + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) + { + for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver) + { + fprintf(output, "Package: %s\n", Pkg.Name()); + fprintf(output, "Architecture: %s\n", Ver.Arch()); + fprintf(output, "Version: %s\n", Ver.VerStr()); + if (Pkg.CurrentVer() == Ver) + fprintf(output, "Installed: yes\n"); + if (Pkg->SelectedState == pkgCache::State::Hold) + fprintf(output, "Hold: yes\n"); + fprintf(output, "APT-ID: %u\n", Ver->ID); + fprintf(output, "Priority: %s\n", PrioMap[Ver->Priority]); + if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + fprintf(output, "Essential: yes\n"); + fprintf(output, "Section: %s\n", Ver.Section()); + if (Ver->MultiArch == pkgCache::Version::Allowed || Ver->MultiArch == pkgCache::Version::AllAllowed) + fprintf(output, "Multi-Arch: allowed\n"); + else if (Ver->MultiArch == pkgCache::Version::Foreign || Ver->MultiArch == pkgCache::Version::AllForeign) + fprintf(output, "Multi-Arch: foreign\n"); + else if (Ver->MultiArch == pkgCache::Version::Same) + fprintf(output, "Multi-Arch: same\n"); + signed short Pin = std::numeric_limits::min(); + for (pkgCache::VerFileIterator File = Ver.FileList(); File.end() == false; ++File) { + signed short const p = Cache.GetPolicy().GetPriority(File.File()); + if (Pin < p) + Pin = p; + } + fprintf(output, "APT-Pin: %d\n", Pin); + if (Cache.GetCandidateVer(Pkg) == Ver) + fprintf(output, "APT-Candidate: yes\n"); + if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) + fprintf(output, "APT-Automatic: yes\n"); + std::string dependencies[pkgCache::Dep::Enhances + 1]; + bool orGroup = false; + for (pkgCache::DepIterator Dep = Ver.DependsList(); Dep.end() == false; ++Dep) + { + // Ignore implicit dependencies for multiarch here + if (strcmp(Pkg.Arch(), Dep.TargetPkg().Arch()) != 0) + continue; + if (orGroup == false) + dependencies[Dep->Type].append(", "); + dependencies[Dep->Type].append(Dep.TargetPkg().Name()); + if (Dep->Version != 0) + dependencies[Dep->Type].append(" (").append(pkgCache::CompTypeDeb(Dep->CompareOp)).append(" ").append(Dep.TargetVer()).append(")"); + if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) + { + dependencies[Dep->Type].append(" | "); + orGroup = true; + } + else + orGroup = false; + } + for (int i = 1; i < pkgCache::Dep::Enhances + 1; ++i) + if (dependencies[i].empty() == false) + fprintf(output, "%s: %s\n", DepMap[i], dependencies[i].c_str()+2); + string provides; + for (pkgCache::PrvIterator Prv = Ver.ProvidesList(); Prv.end() == false; ++Prv) + { + // Ignore implicit provides for multiarch here + if (strcmp(Pkg.Arch(), Prv.ParentPkg().Arch()) != 0 || strcmp(Pkg.Name(),Prv.Name()) == 0) + continue; + provides.append(", ").append(Prv.Name()); + } + if (provides.empty() == false) + fprintf(output, "Provides: %s\n", provides.c_str()+2); + + + fprintf(output, "\n"); + } + } + return true; +} + /*}}}*/ +// EDSP::WriteRequest - to the given file descriptor /*{{{*/ +bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output) +{ + string del, inst, upgrade; + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) + { + string* req; + if (Cache[Pkg].Delete() == true) + req = &del; + else if (Cache[Pkg].NewInstall() == true) + req = &inst; + else if (Cache[Pkg].Upgrade() == true) + req = &upgrade; + else + continue; + req->append(", ").append(Pkg.FullName()); + } + if (del.empty() == false) + fprintf(output, "Remove: %s\n", del.c_str()+2); + if (inst.empty() == false) + fprintf(output, "Install: %s\n", inst.c_str()+2); + if (upgrade.empty() == false) + fprintf(output, "Upgrade: %s\n", upgrade.c_str()+2); + + return true; +} + /*}}}*/ +bool EDSP::ReadResponse(FILE* input, pkgDepCache &Cache) { return false; } + +bool EDSP::ReadRequest(FILE* input, std::list &install, + std::list &remove) +{ return false; } +bool EDSP::ApplyRequest(std::list const &install, + std::list const &remove, + pkgDepCache &Cache) +{ return false; } +// EDSP::WriteSolution - to the given file descriptor /*{{{*/ +bool EDSP::WriteSolution(pkgDepCache &Cache, FILE* output) +{ + bool const Debug = _config->FindB("Debug::EDSPWriter::WriteSolution", false); + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) + { + if (Cache[Pkg].Delete() == true) + fprintf(output, "Remove: %d\n", Cache.GetCandidateVer(Pkg)->ID); + else if (Cache[Pkg].NewInstall() == true || Cache[Pkg].Upgrade() == true) + fprintf(output, "Install: %d\n", Cache.GetCandidateVer(Pkg)->ID); + else + continue; + if (Debug == true) + fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Cache.GetCandidateVer(Pkg).VerStr()); + fprintf(output, "\n"); + } + + return true; +} + /*}}}*/ +bool EDSP::WriteError(std::string const &message, FILE* output) { return false; } diff --git a/apt-pkg/edsp.h b/apt-pkg/edsp.h new file mode 100644 index 000000000..ef137b8f6 --- /dev/null +++ b/apt-pkg/edsp.h @@ -0,0 +1,32 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + Set of methods to help writing and reading everything needed for EDSP + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_EDSP_H +#define PKGLIB_EDSP_H + +#include + +#include + +class EDSP /*{{{*/ +{ +public: + bool static WriteRequest(pkgDepCache &Cache, FILE* output); + bool static WriteScenario(pkgDepCache &Cache, FILE* output); + bool static ReadResponse(FILE* input, pkgDepCache &Cache); + + // ReadScenario is provided by the listparser infrastructure + bool static ReadRequest(FILE* input, std::list &install, + std::list &remove); + bool static ApplyRequest(std::list const &install, + std::list const &remove, + pkgDepCache &Cache); + bool static WriteSolution(pkgDepCache &Cache, FILE* output); + bool static WriteError(std::string const &message, FILE* output); + +}; + /*}}}*/ +#endif diff --git a/apt-pkg/edsp/edspwriter.cc b/apt-pkg/edsp/edspwriter.cc deleted file mode 100644 index 2f6bde5a1..000000000 --- a/apt-pkg/edsp/edspwriter.cc +++ /dev/null @@ -1,160 +0,0 @@ -// -*- mode: cpp; mode: fold -*- -// Description /*{{{*/ -/* ###################################################################### - Set of methods to help writing and reading everything needed for EDSP - ##################################################################### */ - /*}}}*/ -// Include Files /*{{{*/ -#include -#include -#include -#include -#include - -#include -#include - -#include - /*}}}*/ - -// edspWriter::WriteScenario - to the given file descriptor /*{{{*/ -bool edspWriter::WriteScenario(pkgDepCache &Cache, FILE* output) -{ - // we could use pkgCache::DepType and ::Priority, but these would be lokalized strings… - const char * const PrioMap[] = {0, "important", "required", "standard", - "optional", "extra"}; - const char * const DepMap[] = {"", "Depends", "PreDepends", "Suggests", - "Recommends" , "Conflicts", "Replaces", - "Obsoletes", "Breaks", "Enhances"}; - - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) - { - for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver) - { - fprintf(output, "Package: %s\n", Pkg.Name()); - fprintf(output, "Architecture: %s\n", Ver.Arch()); - fprintf(output, "Version: %s\n", Ver.VerStr()); - if (Pkg.CurrentVer() == Ver) - fprintf(output, "Installed: yes\n"); - if (Pkg->SelectedState == pkgCache::State::Hold) - fprintf(output, "Hold: yes\n"); - fprintf(output, "APT-ID: %u\n", Ver->ID); - fprintf(output, "Priority: %s\n", PrioMap[Ver->Priority]); - if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) - fprintf(output, "Essential: yes\n"); - fprintf(output, "Section: %s\n", Ver.Section()); - if (Ver->MultiArch == pkgCache::Version::Allowed || Ver->MultiArch == pkgCache::Version::AllAllowed) - fprintf(output, "Multi-Arch: allowed\n"); - else if (Ver->MultiArch == pkgCache::Version::Foreign || Ver->MultiArch == pkgCache::Version::AllForeign) - fprintf(output, "Multi-Arch: foreign\n"); - else if (Ver->MultiArch == pkgCache::Version::Same) - fprintf(output, "Multi-Arch: same\n"); - signed short Pin = std::numeric_limits::min(); - for (pkgCache::VerFileIterator File = Ver.FileList(); File.end() == false; ++File) { - signed short const p = Cache.GetPolicy().GetPriority(File.File()); - if (Pin < p) - Pin = p; - } - fprintf(output, "APT-Pin: %d\n", Pin); - if (Cache.GetCandidateVer(Pkg) == Ver) - fprintf(output, "APT-Candidate: yes\n"); - if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) - fprintf(output, "APT-Automatic: yes\n"); - std::string dependencies[pkgCache::Dep::Enhances + 1]; - bool orGroup = false; - for (pkgCache::DepIterator Dep = Ver.DependsList(); Dep.end() == false; ++Dep) - { - // Ignore implicit dependencies for multiarch here - if (strcmp(Pkg.Arch(), Dep.TargetPkg().Arch()) != 0) - continue; - if (orGroup == false) - dependencies[Dep->Type].append(", "); - dependencies[Dep->Type].append(Dep.TargetPkg().Name()); - if (Dep->Version != 0) - dependencies[Dep->Type].append(" (").append(pkgCache::CompTypeDeb(Dep->CompareOp)).append(" ").append(Dep.TargetVer()).append(")"); - if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) - { - dependencies[Dep->Type].append(" | "); - orGroup = true; - } - else - orGroup = false; - } - for (int i = 1; i < pkgCache::Dep::Enhances + 1; ++i) - if (dependencies[i].empty() == false) - fprintf(output, "%s: %s\n", DepMap[i], dependencies[i].c_str()+2); - string provides; - for (pkgCache::PrvIterator Prv = Ver.ProvidesList(); Prv.end() == false; ++Prv) - { - // Ignore implicit provides for multiarch here - if (strcmp(Pkg.Arch(), Prv.ParentPkg().Arch()) != 0 || strcmp(Pkg.Name(),Prv.Name()) == 0) - continue; - provides.append(", ").append(Prv.Name()); - } - if (provides.empty() == false) - fprintf(output, "Provides: %s\n", provides.c_str()+2); - - - fprintf(output, "\n"); - } - } - return true; -} - /*}}}*/ -// edspWriter::WriteRequest - to the given file descriptor /*{{{*/ -bool edspWriter::WriteRequest(pkgDepCache &Cache, FILE* output) -{ - string del, inst, upgrade; - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) - { - string* req; - if (Cache[Pkg].Delete() == true) - req = &del; - else if (Cache[Pkg].NewInstall() == true) - req = &inst; - else if (Cache[Pkg].Upgrade() == true) - req = &upgrade; - else - continue; - req->append(", ").append(Pkg.FullName()); - } - if (del.empty() == false) - fprintf(output, "Remove: %s\n", del.c_str()+2); - if (inst.empty() == false) - fprintf(output, "Install: %s\n", inst.c_str()+2); - if (upgrade.empty() == false) - fprintf(output, "Upgrade: %s\n", upgrade.c_str()+2); - - return true; -} - /*}}}*/ -bool edspWriter::ReadResponse(FILE* input, pkgDepCache &Cache) { return false; } - -bool edspWriter::ReadRequest(FILE* input, std::list &install, - std::list &remove) -{ return false; } -bool edspWriter::ApplyRequest(std::list const &install, - std::list const &remove, - pkgDepCache &Cache) -{ return false; } -// edspWriter::WriteSolution - to the given file descriptor /*{{{*/ -bool edspWriter::WriteSolution(pkgDepCache &Cache, FILE* output) -{ - bool const Debug = _config->FindB("Debug::EDSPWriter::WriteSolution", false); - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) - { - if (Cache[Pkg].Delete() == true) - fprintf(output, "Remove: %d\n", Cache.GetCandidateVer(Pkg)->ID); - else if (Cache[Pkg].NewInstall() == true || Cache[Pkg].Upgrade() == true) - fprintf(output, "Install: %d\n", Cache.GetCandidateVer(Pkg)->ID); - else - continue; - if (Debug == true) - fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Cache.GetCandidateVer(Pkg).VerStr()); - fprintf(output, "\n"); - } - - return true; -} - /*}}}*/ -bool edspWriter::WriteError(std::string const &message, FILE* output) { return false; } diff --git a/apt-pkg/edsp/edspwriter.h b/apt-pkg/edsp/edspwriter.h deleted file mode 100644 index c5eed788f..000000000 --- a/apt-pkg/edsp/edspwriter.h +++ /dev/null @@ -1,32 +0,0 @@ -// -*- mode: cpp; mode: fold -*- -// Description /*{{{*/ -/* ###################################################################### - Set of methods to help writing and reading everything needed for EDSP - ##################################################################### */ - /*}}}*/ -#ifndef PKGLIB_EDSPWRITER_H -#define PKGLIB_EDSPWRITER_H - -#include - -#include - -class edspWriter /*{{{*/ -{ -public: - bool static WriteRequest(pkgDepCache &Cache, FILE* output); - bool static WriteScenario(pkgDepCache &Cache, FILE* output); - bool static ReadResponse(FILE* input, pkgDepCache &Cache); - - // ReadScenario is provided by the listparser infrastructure - bool static ReadRequest(FILE* input, std::list &install, - std::list &remove); - bool static ApplyRequest(std::list const &install, - std::list const &remove, - pkgDepCache &Cache); - bool static WriteSolution(pkgDepCache &Cache, FILE* output); - bool static WriteError(std::string const &message, FILE* output); - -}; - /*}}}*/ -#endif diff --git a/apt-pkg/makefile b/apt-pkg/makefile index a7880e81c..e6bcf8524 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -35,7 +35,7 @@ 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 + aptconfiguration.cc cachefilter.cc cacheset.cc edsp.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 \ @@ -43,7 +43,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 + cachefilter.h cacheset.h edsp.h # Source code for the debian specific components # In theory the deb headers do not need to be exported.. @@ -54,9 +54,8 @@ HEADERS+= debversion.h debsrcrecords.h dpkgpm.h debrecords.h \ deblistparser.h debsystem.h debindexfile.h debmetaindex.h # Source code for the APT resolver interface specific components -SOURCE+= edsp/edsplistparser.cc edsp/edspindexfile.cc edsp/edspsystem.cc \ - edsp/edspwriter.cc -HEADERS+= edsplistparser.h edspindexfile.h edspsystem.h edspwriter.h +SOURCE+= edsp/edsplistparser.cc edsp/edspindexfile.cc edsp/edspsystem.cc +HEADERS+= edsplistparser.h edspindexfile.h edspsystem.h HEADERS := $(addprefix apt-pkg/,$(HEADERS)) -- cgit v1.2.3-70-g09d2 From 6d5bd6147e210bfb93e4ce0009d4e71c5995eab1 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 1 Apr 2011 12:04:13 +0200 Subject: Read and apply install/remove requests correctly --- apt-pkg/algorithms.cc | 4 +- apt-pkg/edsp.cc | 101 ++++++++++++++++++++++++++++++++++++++++++++++---- apt-pkg/edsp.h | 4 +- 3 files changed, 97 insertions(+), 12 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 00f558420..aabb511a2 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -743,10 +743,8 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) if (solver != "internal") { FILE* output = fopen("/tmp/scenario.log", "w"); - EDSP::WriteScenario(Cache, output); - fclose(output); - output = fopen("/tmp/request.log", "w"); EDSP::WriteRequest(Cache, output); + EDSP::WriteScenario(Cache, output); fclose(output); if (ResolveInternal(BrokenFix) == false) return false; diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index db0e2466c..6f084ce04 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -115,13 +115,13 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade, req = &inst; else continue; - req->append(", ").append(Pkg.FullName()); + req->append(" ").append(Pkg.FullName()); } fprintf(output, "Request: EDSP 0.2\n"); if (del.empty() == false) - fprintf(output, "Remove: %s\n", del.c_str()+2); + fprintf(output, "Remove: %s\n", del.c_str()+1); if (inst.empty() == false) - fprintf(output, "Install: %s\n", inst.c_str()+2); + fprintf(output, "Install: %s\n", inst.c_str()+1); if (Upgrade == true) fprintf(output, "Upgrade: yes\n"); if (DistUpgrade == true) @@ -132,25 +132,110 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade, fprintf(output, "Strict-Pinning: no\n"); string solverpref("APT::Solver::"); solverpref.append(_config->Find("APT::Solver::Name", "internal")).append("::Preferences"); - if (_config->Exists(solverpref) == false) + if (_config->Exists(solverpref) == true) fprintf(output, "Preferences: %s\n", _config->Find(solverpref,"").c_str()); + fprintf(output, "\n"); return true; } /*}}}*/ bool EDSP::ReadResponse(FILE* input, pkgDepCache &Cache) { return false; } -bool EDSP::ReadRequest(FILE* input, std::list &install, +// EDSP::ReadLine - first line from the given file descriptor /*{{{*/ +// --------------------------------------------------------------------- +/* Little helper method to read a complete line into a string. Similar to + fgets but we need to use the low-level read() here as otherwise the + listparser will be confused later on as mixing of fgets and read isn't + a supported action according to the manpages and result are undefined */ +bool EDSP::ReadLine(int const input, std::string &line) { + char one; + ssize_t data = 0; + line.erase(); + line.reserve(100); + while ((data = read(input, &one, sizeof(one))) != -1) { + if (data != 1) + continue; + if (one == '\n') + return true; + if (one == '\r') + continue; + if (line.empty() == true && isblank(one) != 0) + continue; + line += one; + } + return false; +} + /*}}}*/ +// EDSP::ReadRequest - first stanza from the given file descriptor /*{{{*/ +bool EDSP::ReadRequest(int const input, std::list &install, std::list &remove) -{ return false; } +{ + std::string line; + while (ReadLine(input, line) == true) + { + // Skip empty lines before request + if (line.empty() == true) + continue; + // The first Tag must be a request, so search for it + if (line.compare(0,8, "Request:") != 0) + continue; + + while (ReadLine(input, line) == true) + { + // empty lines are the end of the request + if (line.empty() == true) + return true; + + std::list *request = NULL; + if (line.compare(0,8, "Install:") == 0) + { + line.erase(0,8); + request = &install; + } + if (line.compare(0,7, "Remove:") == 0) + { + line.erase(0,7); + request = &remove; + } + if (request == NULL) + continue; + size_t end = line.length(); + do { + size_t begin = line.rfind(' '); + if (begin == std::string::npos) + { + request->push_back(line.substr(0,end)); + break; + } + else if (begin < end) + request->push_back(line.substr(begin + 1, end)); + line.erase(begin); + end = line.find_last_not_of(' '); + } while (end != std::string::npos); + } + } + return false; +} + /*}}}*/ +// EDSP::ApplyRequest - first stanza from the given file descriptor /*{{{*/ bool EDSP::ApplyRequest(std::list const &install, std::list const &remove, pkgDepCache &Cache) -{ return false; } +{ + for (std::list::const_iterator i = install.begin(); + i != install.end(); ++i) + Cache.MarkInstall(Cache.FindPkg(*i), false); + + for (std::list::const_iterator i = remove.begin(); + i != remove.end(); ++i) + Cache.MarkDelete(Cache.FindPkg(*i)); + return true; +} + /*}}}*/ // EDSP::WriteSolution - to the given file descriptor /*{{{*/ bool EDSP::WriteSolution(pkgDepCache &Cache, FILE* output) { - bool const Debug = _config->FindB("Debug::EDSPWriter::WriteSolution", false); + bool const Debug = _config->FindB("Debug::EDSP::WriteSolution", false); for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) { if (Cache[Pkg].Delete() == true) diff --git a/apt-pkg/edsp.h b/apt-pkg/edsp.h index 04d8c255f..742d89b43 100644 --- a/apt-pkg/edsp.h +++ b/apt-pkg/edsp.h @@ -13,6 +13,8 @@ class EDSP /*{{{*/ { + bool static ReadLine(int const input, std::string &line); + public: bool static WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade = false, @@ -22,7 +24,7 @@ public: bool static ReadResponse(FILE* input, pkgDepCache &Cache); // ReadScenario is provided by the listparser infrastructure - bool static ReadRequest(FILE* input, std::list &install, + bool static ReadRequest(int const input, std::list &install, std::list &remove); bool static ApplyRequest(std::list const &install, std::list const &remove, -- cgit v1.2.3-70-g09d2 From 2029276f0343c96481d0d3cbbc367420b4a5f864 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 2 Apr 2011 15:47:14 +0200 Subject: send the scenario through a pipe to the solver and get the solution back The solution is NOT interpreted so far. --- apt-pkg/algorithms.cc | 42 +++++++++++++++++++++++++++++++++++------- apt-pkg/edsp.cc | 28 ++++++++++++++++++++++++++-- apt-pkg/edsp.h | 2 +- 3 files changed, 62 insertions(+), 10 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index aabb511a2..bbe315ef7 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -740,18 +740,46 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) bool pkgProblemResolver::Resolve(bool BrokenFix) { std::string const solver = _config->Find("APT::Solver::Name", "internal"); + if (solver != "internal") { - FILE* output = fopen("/tmp/scenario.log", "w"); +// std::string const file = _config->FindDir("Dir::Bin::Solvers") + solver; + std::string const file = solver; + if (RealFileExists(file.c_str()) == false) + return _error->Error("Can't call external solver '%s' as it is not available: %s", solver.c_str(), file.c_str()); + int external[4] = {-1, -1, -1, -1}; + if (pipe(external) != 0 || pipe(external + 2) != 0) + return _error->Errno("Resolve", "Can't create needed IPC pipes for EDSP"); + for (int i = 0; i < 4; ++i) + SetCloseExec(external[i], true); + + pid_t Solver = ExecFork(); + if (Solver == 0) + { + dup2(external[0], STDIN_FILENO); + dup2(external[3], STDOUT_FILENO); + const char* calling[2] = { file.c_str(), 0 }; + execv(calling[0], (char**) calling); + std::cerr << "Failed to execute solver '" << solver << "'!" << std::endl; + _exit(100); + } + close(external[0]); + close(external[3]); + + if (WaitFd(external[1], true, 5) == false) + return _error->Errno("Resolve", "Waiting on availability of solver stdin timed out"); + + FILE* output = fdopen(external[1], "w"); + if (output == NULL) + return _error->Errno("Resolve", "fdopen on solver stdin failed"); EDSP::WriteRequest(Cache, output); EDSP::WriteScenario(Cache, output); fclose(output); - if (ResolveInternal(BrokenFix) == false) - return false; - output = fopen("/tmp/solution.log", "w"); - EDSP::WriteSolution(Cache, output); - fclose(output); - return true; + + if (EDSP::ReadResponse(external[2], Cache) == false) + return _error->Error("Reading solver response failed"); + + return ExecWait(Solver, solver.c_str(), false); } return ResolveInternal(BrokenFix); } diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index d93b05411..e6dc16536 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -139,14 +140,37 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade, return true; } /*}}}*/ -bool EDSP::ReadResponse(FILE* input, pkgDepCache &Cache) { return false; } +// EDSP::ReadResponse - from the given file descriptor /*{{{*/ +bool EDSP::ReadResponse(int const input, pkgDepCache &Cache) { + FileFd in; + in.OpenDescriptor(input, FileFd::ReadOnly); + pkgTagFile response(&in); + pkgTagSection section; + while (response.Step(section) == true) { + std::string type; + if (section.Exists("Install") == true) + type = "Install"; + else if (section.Exists("Remove") == true) + type = "Remove"; + //FIXME: handle progress + else + continue; + + int const id = section.FindI(type.c_str(), -1); + if (id == -1) + return _error->Error("Unable to parse %s request!", type.c_str()); + //FIXME: find version by id and mark it correctly + } + return true; +} + /*}}}*/ // EDSP::ReadLine - first line from the given file descriptor /*{{{*/ // --------------------------------------------------------------------- /* Little helper method to read a complete line into a string. Similar to fgets but we need to use the low-level read() here as otherwise the listparser will be confused later on as mixing of fgets and read isn't - a supported action according to the manpages and result are undefined */ + a supported action according to the manpages and results are undefined */ bool EDSP::ReadLine(int const input, std::string &line) { char one; ssize_t data = 0; diff --git a/apt-pkg/edsp.h b/apt-pkg/edsp.h index 75733c2d2..31f8891f3 100644 --- a/apt-pkg/edsp.h +++ b/apt-pkg/edsp.h @@ -22,7 +22,7 @@ public: bool const distUpgrade = false, bool const autoRemove = false); bool static WriteScenario(pkgDepCache &Cache, FILE* output); - bool static ReadResponse(FILE* input, pkgDepCache &Cache); + bool static ReadResponse(int const input, pkgDepCache &Cache); // ReadScenario is provided by the listparser infrastructure bool static ReadRequest(int const input, std::list &install, -- cgit v1.2.3-70-g09d2 From 98d6aaa8fd2e5c3e9671560781ab23c99f66d7a4 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 2 May 2011 13:22:14 +0200 Subject: handle Dir::Bin::Solvers as a list of directories and find the solver in this list of directories --- apt-pkg/algorithms.cc | 16 ++++++++++++---- apt-pkg/init.cc | 2 ++ 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index bbe315ef7..e40f74122 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -743,10 +743,18 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) if (solver != "internal") { -// std::string const file = _config->FindDir("Dir::Bin::Solvers") + solver; - std::string const file = solver; - if (RealFileExists(file.c_str()) == false) - return _error->Error("Can't call external solver '%s' as it is not available: %s", solver.c_str(), file.c_str()); + std::vector const solverDirs = _config->FindVector("Dir::Bin::Solvers"); + std::string file; + for (std::vector::const_iterator dir = solverDirs.begin(); + dir != solverDirs.end(); ++dir) { + file = flCombine(*dir, solver); + if (RealFileExists(file.c_str()) == true) + break; + file.clear(); + } + + if (file.empty() == true) + return _error->Error("Can't call external solver '%s' as it is not in a configured directory!", solver.c_str()); int external[4] = {-1, -1, -1, -1}; if (pipe(external) != 0 || pipe(external + 2) != 0) return _error->Errno("Resolve", "Can't create needed IPC pipes for EDSP"); diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc index a30f27844..aff585e3b 100644 --- a/apt-pkg/init.cc +++ b/apt-pkg/init.cc @@ -72,7 +72,9 @@ bool pkgInitConfig(Configuration &Cnf) Cnf.Set("Dir::Etc::preferencesparts","preferences.d"); Cnf.Set("Dir::Etc::trusted", "trusted.gpg"); Cnf.Set("Dir::Etc::trustedparts","trusted.gpg.d"); + Cnf.Set("Dir::Bin::methods","/usr/lib/apt/methods"); + Cnf.Set("Dir::Bin::solvers::","/usr/lib/apt/solvers"); Cnf.Set("Dir::Media::MountPath","/media/apt"); // State -- cgit v1.2.3-70-g09d2 From ac5fbff8c55db2bd1cde194600115a874d9d0c73 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 2 May 2011 13:55:51 +0200 Subject: refactor: move solver execution into his own EDSP method --- apt-pkg/algorithms.cc | 42 +++++------------------------------------- apt-pkg/edsp.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ apt-pkg/edsp.h | 1 + 3 files changed, 48 insertions(+), 37 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index e40f74122..82b1d608d 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -743,51 +743,19 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) if (solver != "internal") { - std::vector const solverDirs = _config->FindVector("Dir::Bin::Solvers"); - std::string file; - for (std::vector::const_iterator dir = solverDirs.begin(); - dir != solverDirs.end(); ++dir) { - file = flCombine(*dir, solver); - if (RealFileExists(file.c_str()) == true) - break; - file.clear(); - } - - if (file.empty() == true) - return _error->Error("Can't call external solver '%s' as it is not in a configured directory!", solver.c_str()); - int external[4] = {-1, -1, -1, -1}; - if (pipe(external) != 0 || pipe(external + 2) != 0) - return _error->Errno("Resolve", "Can't create needed IPC pipes for EDSP"); - for (int i = 0; i < 4; ++i) - SetCloseExec(external[i], true); - - pid_t Solver = ExecFork(); - if (Solver == 0) - { - dup2(external[0], STDIN_FILENO); - dup2(external[3], STDOUT_FILENO); - const char* calling[2] = { file.c_str(), 0 }; - execv(calling[0], (char**) calling); - std::cerr << "Failed to execute solver '" << solver << "'!" << std::endl; - _exit(100); - } - close(external[0]); - close(external[3]); - - if (WaitFd(external[1], true, 5) == false) - return _error->Errno("Resolve", "Waiting on availability of solver stdin timed out"); + int solver_in, solver_out; + if (EDSP::ExecuteSolver(solver.c_str(), &solver_in, &solver_out) == false) + return false; - FILE* output = fdopen(external[1], "w"); + FILE* output = fdopen(solver_in, "w"); if (output == NULL) return _error->Errno("Resolve", "fdopen on solver stdin failed"); EDSP::WriteRequest(Cache, output); EDSP::WriteScenario(Cache, output); fclose(output); - if (EDSP::ReadResponse(external[2], Cache) == false) + if (EDSP::ReadResponse(solver_out, Cache) == false) return _error->Error("Reading solver response failed"); - - return ExecWait(Solver, solver.c_str(), false); } return ResolveInternal(BrokenFix); } diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index 170e2a4c6..c3e608d17 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -441,3 +441,45 @@ bool EDSP::WriteProgress(unsigned short const percent, const char* const message } /*}}}*/ bool EDSP::WriteError(std::string const &message, FILE* output) { return false; } + +// EDSP::ExecuteSolver - fork requested solver and setup ipc pipes {{{*/ +bool EDSP::ExecuteSolver(const char* const solver, int *solver_in, int *solver_out) { + std::vector const solverDirs = _config->FindVector("Dir::Bin::Solvers"); + std::string file; + for (std::vector::const_iterator dir = solverDirs.begin(); + dir != solverDirs.end(); ++dir) { + file = flCombine(*dir, solver); + if (RealFileExists(file.c_str()) == true) + break; + file.clear(); + } + + if (file.empty() == true) + return _error->Error("Can't call external solver '%s' as it is not in a configured directory!", solver); + int external[4] = {-1, -1, -1, -1}; + if (pipe(external) != 0 || pipe(external + 2) != 0) + return _error->Errno("Resolve", "Can't create needed IPC pipes for EDSP"); + for (int i = 0; i < 4; ++i) + SetCloseExec(external[i], true); + + pid_t Solver = ExecFork(); + if (Solver == 0) + { + dup2(external[0], STDIN_FILENO); + dup2(external[3], STDOUT_FILENO); + const char* calling[2] = { file.c_str(), 0 }; + execv(calling[0], (char**) calling); + std::cerr << "Failed to execute solver '" << solver << "'!" << std::endl; + _exit(100); + } + close(external[0]); + close(external[3]); + + if (WaitFd(external[1], true, 5) == false) + return _error->Errno("Resolve", "Timed out while Waiting on availability of solver stdin"); + + *solver_in = external[1]; + *solver_out = external[2]; + return true; +} + /*}}}*/ diff --git a/apt-pkg/edsp.h b/apt-pkg/edsp.h index a05de9448..df6e1d21c 100644 --- a/apt-pkg/edsp.h +++ b/apt-pkg/edsp.h @@ -52,6 +52,7 @@ public: bool static WriteProgress(unsigned short const percent, const char* const message, FILE* output); bool static WriteError(std::string const &message, FILE* output); + bool static ExecuteSolver(const char* const solver, int *solver_in, int *solver_out); }; /*}}}*/ #endif -- cgit v1.2.3-70-g09d2 From 76d4aab06d3c5edd60362fd14b38eb43416616f0 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 2 May 2011 17:06:47 +0200 Subject: doesn't execute autoremove marker setting if an external solver is called and instead rely on the Autoremove tagging to show us what could be done. (apt-internal-solver doesn't support this currently as it doesn't load the auto-information into the cache) --- apt-pkg/algorithms.cc | 2 ++ apt-pkg/depcache.cc | 3 +++ apt-pkg/edsp.cc | 20 ++++++++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 82b1d608d..fea9e92e1 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -756,6 +756,8 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) if (EDSP::ReadResponse(solver_out, Cache) == false) return _error->Error("Reading solver response failed"); + + return true; } return ResolveInternal(BrokenFix); } diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index ed9e2084c..31410e2a6 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1609,6 +1609,9 @@ bool pkgDepCache::MarkFollowsSuggests() // pkgDepCache::MarkRequired - the main mark algorithm /*{{{*/ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) { + if (_config->Find("APT::Solver::Name", "internal") != "internal") + return true; + bool follow_recommends; bool follow_suggests; bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false); diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index c3e608d17..f35570c12 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -227,9 +227,12 @@ bool EDSP::ReadResponse(int const input, pkgDepCache &Cache) { would be too easy for a (buggy) solver to segfault APT… */ unsigned long long const VersionCount = Cache.Head().VersionCount; unsigned long VerIdx[VersionCount]; - for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; ++P) + for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; ++P) { for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V) VerIdx[V->ID] = V.Index(); + Cache[P].Marked = true; + Cache[P].Garbage = false; + } FileFd in; in.OpenDescriptor(input, FileFd::ReadOnly); @@ -252,7 +255,9 @@ bool EDSP::ReadResponse(int const input, pkgDepCache &Cache) { else std::clog << msg << std::endl; continue; - } else + } else if (section.Exists("Autoremove") == true) + type = "Autoremove"; + else continue; size_t const id = section.FindULL(type.c_str(), VersionCount); @@ -270,6 +275,10 @@ bool EDSP::ReadResponse(int const input, pkgDepCache &Cache) { Cache.MarkInstall(Ver.ParentPkg(), false, false); else if (type == "Remove") Cache.MarkDelete(Ver.ParentPkg(), false); + else if (type == "Autoremove") { + Cache[Ver.ParentPkg()].Marked = false; + Cache[Ver.ParentPkg()].Garbage = true; + } } return true; } @@ -423,6 +432,13 @@ bool EDSP::WriteSolution(pkgDepCache &Cache, FILE* output) if (Debug == true) fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Cache.GetCandidateVer(Pkg).VerStr()); } + else if (Cache[Pkg].Garbage == true) + { + fprintf(output, "Autoremove: %d\n", Pkg.CurrentVer()->ID); + if (Debug == true) + fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Pkg.CurrentVer().VerStr()); + fprintf(stderr, "Autoremove: %s\nVersion: %s\n", Pkg.FullName().c_str(), Pkg.CurrentVer().VerStr()); + } else continue; fprintf(output, "\n"); -- cgit v1.2.3-70-g09d2 From 741b7da9de1d2ab470728f1e7f38b25e0d6a556c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 3 May 2011 10:50:25 +0200 Subject: implement external solver calling for upgrade and dist-upgrade, too --- apt-pkg/algorithms.cc | 40 ++++++++++++----------- apt-pkg/algorithms.h | 1 + apt-pkg/edsp.cc | 88 +++++++++++++++++++++++++++++++-------------------- apt-pkg/edsp.h | 3 ++ 4 files changed, 80 insertions(+), 52 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index fea9e92e1..5d9fefaa6 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -332,6 +332,10 @@ bool pkgFixBroken(pkgDepCache &Cache) */ bool pkgDistUpgrade(pkgDepCache &Cache) { + std::string const solver = _config->Find("APT::Solver::Name", "internal"); + if (solver != "internal") + return EDSP::ResolveExternal(solver.c_str(), Cache, false, true, false); + pkgDepCache::ActionGroup group(Cache); /* Upgrade all installed packages first without autoinst to help the resolver @@ -384,6 +388,10 @@ bool pkgDistUpgrade(pkgDepCache &Cache) to install packages not marked for install */ bool pkgAllUpgrade(pkgDepCache &Cache) { + std::string const solver = _config->Find("APT::Solver::Name", "internal"); + if (solver != "internal") + return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false); + pkgDepCache::ActionGroup group(Cache); pkgProblemResolver Fix(&Cache); @@ -740,25 +748,8 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) bool pkgProblemResolver::Resolve(bool BrokenFix) { std::string const solver = _config->Find("APT::Solver::Name", "internal"); - if (solver != "internal") - { - int solver_in, solver_out; - if (EDSP::ExecuteSolver(solver.c_str(), &solver_in, &solver_out) == false) - return false; - - FILE* output = fdopen(solver_in, "w"); - if (output == NULL) - return _error->Errno("Resolve", "fdopen on solver stdin failed"); - EDSP::WriteRequest(Cache, output); - EDSP::WriteScenario(Cache, output); - fclose(output); - - if (EDSP::ReadResponse(solver_out, Cache) == false) - return _error->Error("Reading solver response failed"); - - return true; - } + return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false); return ResolveInternal(BrokenFix); } /*}}}*/ @@ -1230,6 +1221,19 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) in that it does not install or remove any packages. It is assumed that the system was non-broken previously. */ bool pkgProblemResolver::ResolveByKeep() +{ + std::string const solver = _config->Find("APT::Solver::Name", "internal"); + if (solver != "internal") + return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false); + return ResolveByKeepInternal(); +} + /*}}}*/ +// ProblemResolver::ResolveByKeepInternal - Resolve problems using keep /*{{{*/ +// --------------------------------------------------------------------- +/* This is the work horse of the soft upgrade routine. It is very gental + in that it does not install or remove any packages. It is assumed that the + system was non-broken previously. */ +bool pkgProblemResolver::ResolveByKeepInternal() { pkgDepCache::ActionGroup group(Cache); diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 0778ec722..582cbc527 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -107,6 +107,7 @@ class pkgProblemResolver /*{{{*/ bool DoUpgrade(pkgCache::PkgIterator Pkg); bool ResolveInternal(bool const BrokenFix = false); + bool ResolveByKeepInternal(); public: diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index f35570c12..d72370358 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -197,7 +197,7 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade, continue; req->append(" ").append(Pkg.FullName()); } - fprintf(output, "Request: EDSP 0.2\n"); + fprintf(output, "Request: EDSP 0.4\n"); if (del.empty() == false) fprintf(output, "Remove: %s\n", del.c_str()+1); if (inst.empty() == false) @@ -460,42 +460,62 @@ bool EDSP::WriteError(std::string const &message, FILE* output) { return false; // EDSP::ExecuteSolver - fork requested solver and setup ipc pipes {{{*/ bool EDSP::ExecuteSolver(const char* const solver, int *solver_in, int *solver_out) { - std::vector const solverDirs = _config->FindVector("Dir::Bin::Solvers"); - std::string file; - for (std::vector::const_iterator dir = solverDirs.begin(); - dir != solverDirs.end(); ++dir) { - file = flCombine(*dir, solver); - if (RealFileExists(file.c_str()) == true) - break; - file.clear(); - } + std::vector const solverDirs = _config->FindVector("Dir::Bin::Solvers"); + std::string file; + for (std::vector::const_iterator dir = solverDirs.begin(); + dir != solverDirs.end(); ++dir) { + file = flCombine(*dir, solver); + if (RealFileExists(file.c_str()) == true) + break; + file.clear(); + } - if (file.empty() == true) - return _error->Error("Can't call external solver '%s' as it is not in a configured directory!", solver); - int external[4] = {-1, -1, -1, -1}; - if (pipe(external) != 0 || pipe(external + 2) != 0) - return _error->Errno("Resolve", "Can't create needed IPC pipes for EDSP"); - for (int i = 0; i < 4; ++i) - SetCloseExec(external[i], true); + if (file.empty() == true) + return _error->Error("Can't call external solver '%s' as it is not in a configured directory!", solver); + int external[4] = {-1, -1, -1, -1}; + if (pipe(external) != 0 || pipe(external + 2) != 0) + return _error->Errno("Resolve", "Can't create needed IPC pipes for EDSP"); + for (int i = 0; i < 4; ++i) + SetCloseExec(external[i], true); - pid_t Solver = ExecFork(); - if (Solver == 0) - { - dup2(external[0], STDIN_FILENO); - dup2(external[3], STDOUT_FILENO); - const char* calling[2] = { file.c_str(), 0 }; - execv(calling[0], (char**) calling); - std::cerr << "Failed to execute solver '" << solver << "'!" << std::endl; - _exit(100); - } - close(external[0]); - close(external[3]); + pid_t Solver = ExecFork(); + if (Solver == 0) { + dup2(external[0], STDIN_FILENO); + dup2(external[3], STDOUT_FILENO); + const char* calling[2] = { file.c_str(), 0 }; + execv(calling[0], (char**) calling); + std::cerr << "Failed to execute solver '" << solver << "'!" << std::endl; + _exit(100); + } + close(external[0]); + close(external[3]); - if (WaitFd(external[1], true, 5) == false) - return _error->Errno("Resolve", "Timed out while Waiting on availability of solver stdin"); + if (WaitFd(external[1], true, 5) == false) + return _error->Errno("Resolve", "Timed out while Waiting on availability of solver stdin"); - *solver_in = external[1]; - *solver_out = external[2]; - return true; + *solver_in = external[1]; + *solver_out = external[2]; + return true; +} + /*}}}*/ +// 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) { + int solver_in, solver_out; + if (EDSP::ExecuteSolver(solver, &solver_in, &solver_out) == false) + return false; + + FILE* output = fdopen(solver_in, "w"); + if (output == NULL) + return _error->Errno("Resolve", "fdopen on solver stdin failed"); + EDSP::WriteRequest(Cache, output, upgrade, distUpgrade, autoRemove); + EDSP::WriteScenario(Cache, output); + fclose(output); + + if (EDSP::ReadResponse(solver_out, Cache) == false) + return _error->Error("Reading solver response failed"); + + return true; } /*}}}*/ diff --git a/apt-pkg/edsp.h b/apt-pkg/edsp.h index df6e1d21c..95132ebd0 100644 --- a/apt-pkg/edsp.h +++ b/apt-pkg/edsp.h @@ -53,6 +53,9 @@ public: bool static WriteError(std::string const &message, FILE* output); bool static ExecuteSolver(const char* const solver, int *solver_in, int *solver_out); + bool static ResolveExternal(const char* const solver, pkgDepCache &Cache, + bool const upgrade, bool const distUpgrade, + bool const autoRemove); }; /*}}}*/ #endif -- cgit v1.2.3-70-g09d2 From b57c0e355d7f27a74c860ed73700cf9241cb4e61 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 9 May 2011 18:00:28 +0200 Subject: implement proper progress report with OpProgress --- apt-pkg/algorithms.cc | 24 ++++++++++++------- apt-pkg/edsp.cc | 64 ++++++++++++++++++++++++++++++++++++--------------- apt-pkg/edsp.h | 18 +++++++++++---- 3 files changed, 74 insertions(+), 32 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 5d9fefaa6..31c3e9c28 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -333,8 +333,10 @@ bool pkgFixBroken(pkgDepCache &Cache) bool pkgDistUpgrade(pkgDepCache &Cache) { std::string const solver = _config->Find("APT::Solver::Name", "internal"); - if (solver != "internal") - return EDSP::ResolveExternal(solver.c_str(), Cache, false, true, false); + if (solver != "internal") { + OpTextProgress Prog(*_config); + return EDSP::ResolveExternal(solver.c_str(), Cache, false, true, false, &Prog); + } pkgDepCache::ActionGroup group(Cache); @@ -389,8 +391,10 @@ bool pkgDistUpgrade(pkgDepCache &Cache) bool pkgAllUpgrade(pkgDepCache &Cache) { std::string const solver = _config->Find("APT::Solver::Name", "internal"); - if (solver != "internal") - return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false); + if (solver != "internal") { + OpTextProgress Prog(*_config); + return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog); + } pkgDepCache::ActionGroup group(Cache); @@ -748,8 +752,10 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) bool pkgProblemResolver::Resolve(bool BrokenFix) { std::string const solver = _config->Find("APT::Solver::Name", "internal"); - if (solver != "internal") - return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false); + if (solver != "internal") { + OpTextProgress Prog(*_config); + return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false, &Prog); + } return ResolveInternal(BrokenFix); } /*}}}*/ @@ -1223,8 +1229,10 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) bool pkgProblemResolver::ResolveByKeep() { std::string const solver = _config->Find("APT::Solver::Name", "internal"); - if (solver != "internal") - return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false); + if (solver != "internal") { + OpTextProgress Prog(*_config); + return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog); + } return ResolveByKeepInternal(); } /*}}}*/ diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index 7ece92d2e..489dd2933 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -26,29 +26,42 @@ const char * const EDSP::DepMap[] = {"", "Depends", "Pre-Depends", "Suggests", "Obsoletes", "Breaks", "Enhances"}; // EDSP::WriteScenario - to the given file descriptor /*{{{*/ -bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output) +bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress) { + if (Progress != NULL) + Progress->SubProgress(Cache.Head().VersionCount, _("Send scenario to solver")); + unsigned long p = 0; for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) - for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver) + for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver, ++p) { WriteScenarioVersion(Cache, output, Pkg, Ver); WriteScenarioDependency(Cache, output, Pkg, Ver); fprintf(output, "\n"); + if (Progress != NULL && p % 100 == 0) + Progress->Progress(p); } return true; } /*}}}*/ // EDSP::WriteLimitedScenario - to the given file descriptor /*{{{*/ bool EDSP::WriteLimitedScenario(pkgDepCache &Cache, FILE* output, - APT::PackageSet const &pkgset) + APT::PackageSet const &pkgset, + OpProgress *Progress) { - for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg) + if (Progress != NULL) + Progress->SubProgress(Cache.Head().VersionCount, _("Send scenario to solver")); + unsigned long p = 0; + for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg, ++p) for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver) { WriteScenarioVersion(Cache, output, Pkg, Ver); WriteScenarioLimitedDependency(Cache, output, Pkg, Ver, pkgset); fprintf(output, "\n"); + if (Progress != NULL && p % 100 == 0) + Progress->Progress(p); } + if (Progress != NULL) + Progress->Done(); return true; } /*}}}*/ @@ -184,11 +197,17 @@ void EDSP::WriteScenarioLimitedDependency(pkgDepCache &Cache, FILE* output, /*}}}*/ // EDSP::WriteRequest - to the given file descriptor /*{{{*/ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade, - bool const DistUpgrade, bool const AutoRemove) + bool const DistUpgrade, bool const AutoRemove, + OpProgress *Progress) { + if (Progress != NULL) + Progress->SubProgress(Cache.Head().PackageCount, _("Send request to solver")); + unsigned long p = 0; string del, inst; - for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg, ++p) { + if (Progress != NULL && p % 100 == 0) + Progress->Progress(p); string* req; if (Cache[Pkg].Delete() == true) req = &del; @@ -221,7 +240,7 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade, } /*}}}*/ // EDSP::ReadResponse - from the given file descriptor /*{{{*/ -bool EDSP::ReadResponse(int const input, pkgDepCache &Cache) { +bool EDSP::ReadResponse(int const input, pkgDepCache &Cache, OpProgress *Progress) { /* We build an map id to mmap offset here In theory we could use the offset as ID, but then VersionCount couldn't be used to create other versionmappings anymore and it @@ -247,14 +266,14 @@ bool EDSP::ReadResponse(int const input, pkgDepCache &Cache) { else if (section.Exists("Remove") == true) type = "Remove"; else if (section.Exists("Progress") == true) { - std::clog << TimeRFC1123(time(NULL)) << " "; - ioprintf(std::clog, "[ %3d%% ] ", section.FindI("Percentage", 0)); - std::clog << section.FindS("Progress") << " - "; - string const msg = section.FindS("Message"); - if (msg.empty() == true) - std::clog << "Solver is still working on the solution" << std::endl; - else - std::clog << msg << std::endl; + if (Progress != NULL) { + string const msg = section.FindS("Message"); + if (msg.empty() == true) + Progress->SubProgress(100, _("Prepare for receiving solution")); + else + Progress->SubProgress(100, msg); + Progress->Progress(section.FindI("Percentage", 0)); + } continue; } else if (section.Exists("Error") == true) { std::cerr << "The solver encountered an error of type: " << section.FindS("Error") << std::endl; @@ -512,7 +531,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) { + bool const autoRemove, OpProgress *Progress) { int solver_in, solver_out; if (EDSP::ExecuteSolver(solver, &solver_in, &solver_out) == false) return false; @@ -520,11 +539,18 @@ bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache, FILE* output = fdopen(solver_in, "w"); if (output == NULL) return _error->Errno("Resolve", "fdopen on solver stdin failed"); - EDSP::WriteRequest(Cache, output, upgrade, distUpgrade, autoRemove); - EDSP::WriteScenario(Cache, output); + + if (Progress != NULL) + Progress->OverallProgress(0, 100, 5, _("Execute external solver")); + EDSP::WriteRequest(Cache, output, upgrade, distUpgrade, autoRemove, Progress); + if (Progress != NULL) + Progress->OverallProgress(5, 100, 20, _("Execute external solver")); + EDSP::WriteScenario(Cache, output, Progress); fclose(output); - if (EDSP::ReadResponse(solver_out, Cache) == false) + if (Progress != NULL) + Progress->OverallProgress(25, 100, 75, _("Execute external solver")); + if (EDSP::ReadResponse(solver_out, Cache, Progress) == false) return _error->Error("Reading solver response failed"); return true; diff --git a/apt-pkg/edsp.h b/apt-pkg/edsp.h index 210188d03..743c3f5d1 100644 --- a/apt-pkg/edsp.h +++ b/apt-pkg/edsp.h @@ -11,6 +11,7 @@ #include #include +#include #include @@ -46,13 +47,15 @@ public: * \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 Progress is an instance to report progress to * * \return true if request was composed successfully, otherwise false */ bool static WriteRequest(pkgDepCache &Cache, FILE* output, bool const upgrade = false, bool const distUpgrade = false, - bool const autoRemove = false); + bool const autoRemove = false, + OpProgress *Progress = NULL); /** \brief creates the scenario representing the package universe * @@ -67,10 +70,11 @@ public: * * \param Cache is the known package universe * \param output is written to this "file" + * \param Progress is an instance to report progress to * * \return true if universe was composed successfully, otherwise false */ - bool static WriteScenario(pkgDepCache &Cache, FILE* output); + bool static WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress = NULL); /** \brief creates a limited scenario representing the package universe * @@ -83,11 +87,13 @@ public: * \param Cache is the known package universe * \param output is written to this "file" * \param pkgset is a set of packages the universe should be limited to + * \param Progress is an instance to report progress to * * \return true if universe was composed successfully, otherwise false */ bool static WriteLimitedScenario(pkgDepCache &Cache, FILE* output, - APT::PackageSet const &pkgset); + APT::PackageSet const &pkgset, + OpProgress *Progress = NULL); /** \brief waits and acts on the information returned from the solver * @@ -98,10 +104,11 @@ public: * * \param input file descriptor with the response from the solver * \param Cache the solution should be applied on if any + * \param Progress is an instance to report progress to * * \return true if a solution is found and applied correctly, otherwise false */ - bool static ReadResponse(int const input, pkgDepCache &Cache); + bool static ReadResponse(int const input, pkgDepCache &Cache, OpProgress *Progress = NULL); /** \brief search and read the request stanza for action later * @@ -202,13 +209,14 @@ public: * \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 Progress is an instance to report progress to * * \return true if the solver has successfully solved the problem, * otherwise false */ bool static ResolveExternal(const char* const solver, pkgDepCache &Cache, bool const upgrade, bool const distUpgrade, - bool const autoRemove); + bool const autoRemove, OpProgress *Progress = NULL); }; /*}}}*/ #endif -- cgit v1.2.3-70-g09d2 From 98278a81bf554246b70b97852c9b8b92eac390ea Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 17 May 2011 17:42:01 +0200 Subject: rename option APT::Solver::Name to simply APT::Solver --- apt-pkg/algorithms.cc | 8 ++++---- apt-pkg/depcache.cc | 4 ++-- apt-pkg/edsp.cc | 2 +- cmdline/apt-get.cc | 2 +- cmdline/apt-internal-solver.cc | 2 +- doc/external-dependency-solver-protocol.txt | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) (limited to 'apt-pkg/algorithms.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 6f1f82d50..47bdd4aba 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -330,7 +330,7 @@ bool pkgFixBroken(pkgDepCache &Cache) */ bool pkgDistUpgrade(pkgDepCache &Cache) { - std::string const solver = _config->Find("APT::Solver::Name", "internal"); + 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); @@ -388,7 +388,7 @@ bool pkgDistUpgrade(pkgDepCache &Cache) to install packages not marked for install */ bool pkgAllUpgrade(pkgDepCache &Cache) { - std::string const solver = _config->Find("APT::Solver::Name", "internal"); + 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); @@ -745,7 +745,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) /* */ bool pkgProblemResolver::Resolve(bool BrokenFix) { - std::string const solver = _config->Find("APT::Solver::Name", "internal"); + std::string const solver = _config->Find("APT::Solver", "internal"); if (solver != "internal") { OpTextProgress Prog(*_config); return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false, &Prog); @@ -1211,7 +1211,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) system was non-broken previously. */ bool pkgProblemResolver::ResolveByKeep() { - std::string const solver = _config->Find("APT::Solver::Name", "internal"); + 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); diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 5cb68804d..947435706 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1046,7 +1046,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, Update(Pkg); AddSizes(Pkg); - if (AutoInst == false || _config->Find("APT::Solver::Name", "internal") != "internal") + if (AutoInst == false || _config->Find("APT::Solver", "internal") != "internal") return; if (DebugMarker == true) @@ -1605,7 +1605,7 @@ bool pkgDepCache::MarkFollowsSuggests() // pkgDepCache::MarkRequired - the main mark algorithm /*{{{*/ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) { - if (_config->Find("APT::Solver::Name", "internal") != "internal") + if (_config->Find("APT::Solver", "internal") != "internal") return true; bool follow_recommends; diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index 218ce9f24..02ef7d04b 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -231,7 +231,7 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade, if (_config->FindB("APT::Solver::Strict-Pinning", true) == false) fprintf(output, "Strict-Pinning: no\n"); string solverpref("APT::Solver::"); - solverpref.append(_config->Find("APT::Solver::Name", "internal")).append("::Preferences"); + solverpref.append(_config->Find("APT::Solver", "internal")).append("::Preferences"); if (_config->Exists(solverpref) == true) fprintf(output, "Preferences: %s\n", _config->Find(solverpref,"").c_str()); fprintf(output, "\n"); diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index fdb1033a1..d48ca18f9 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -3270,7 +3270,7 @@ int main(int argc,const char *argv[]) /*{{{*/ {0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean}, {0,"install-suggests","APT::Install-Suggests",CommandLine::Boolean}, {0,"fix-policy","APT::Get::Fix-Policy-Broken",0}, - {0,"solver","APT::Solver::Name",CommandLine::HasArg}, + {0,"solver","APT::Solver",CommandLine::HasArg}, {'c',"config-file",0,CommandLine::ConfigFile}, {'o',"option",0,CommandLine::ArbItem}, {0,0,0,0}}; diff --git a/cmdline/apt-internal-solver.cc b/cmdline/apt-internal-solver.cc index ad00a0e23..ef6c688fe 100644 --- a/cmdline/apt-internal-solver.cc +++ b/cmdline/apt-internal-solver.cc @@ -97,7 +97,7 @@ int main(int argc,const char *argv[]) /*{{{*/ if (_config->FindI("quiet", 0) < 1) _config->Set("Debug::EDSP::WriteSolution", true); - _config->Set("APT::Solver::Name", "internal"); + _config->Set("APT::Solver", "internal"); _config->Set("edsp::scenario", "stdin"); int input = STDIN_FILENO; FILE* output = stdout; diff --git a/doc/external-dependency-solver-protocol.txt b/doc/external-dependency-solver-protocol.txt index ae01fbc35..7a124d8f9 100644 --- a/doc/external-dependency-solver-protocol.txt +++ b/doc/external-dependency-solver-protocol.txt @@ -47,7 +47,7 @@ Several APT options can be used to affect dependency solving in APT. An overview of them is given below. Please refer to proper APT configuration documentation for more, and more up to date, information. -- **APT::Solver::Name**: the name of the solver to be used for +- **APT::Solver**: the name of the solver to be used for dependency solving. Defaults to `internal` - **APT::Solver::Strict-Pinning**: whether pinning must be strictly -- cgit v1.2.3-70-g09d2