From 5caf35a7e4bd573a22ff7ed0c686c1cf516eeaf0 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 14 May 2016 18:07:12 +0200 Subject: [PATCH] refactor EDSP code into EDSP and EDSP-like parts No real code change, just moving code around heavily to decouple the EDSP specific parts from those we can reuse for EDSP-like protocols. Git-Dch: Ignore --- apt-pkg/edsp.cc | 112 ++++++++++-------- .../test-external-dependency-solver-protocol | 18 +-- 2 files changed, 74 insertions(+), 56 deletions(-) diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index 5e03cecaa..2aaffcfc7 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -114,51 +114,21 @@ static void WriteScenarioVersion(pkgDepCache &Cache, FILE* output, pkgCache::Pkg if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) fprintf(output, "APT-Automatic: yes\n"); } -static bool WriteScenarioVersion(pkgDepCache &Cache, FileFd &output, pkgCache::PkgIterator const &Pkg, +static bool WriteScenarioVersion(FileFd &output, pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const &Ver) { bool Okay = WriteOkay(output, "Package: ", Pkg.Name(), - "\nSource: ", Ver.SourcePkgName(), "\nArchitecture: ", Ver.Arch(), - "\nVersion: ", Ver.VerStr(), - "\nSource-Version: ", Ver.SourceVerStr()); - if (Pkg.CurrentVer() == Ver) - WriteOkay(Okay, output, "\nInstalled: yes"); - if (Pkg->SelectedState == pkgCache::State::Hold || - (Cache[Pkg].Keep() == true && Cache[Pkg].Protect() == true)) - WriteOkay(Okay, output, "\nHold: yes"); + "\nVersion: ", Ver.VerStr()); WriteOkay(Okay, output, "\nAPT-ID: ", Ver->ID); - if (PrioMap[Ver->Priority] != nullptr) - WriteOkay(Okay, output, "\nPriority: ", PrioMap[Ver->Priority]); if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) WriteOkay(Okay, output, "\nEssential: yes"); - if (Ver->Section != 0) - WriteOkay(Okay, output, "\nSection: ", Ver.Section()); if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed) WriteOkay(Okay, output, "\nMulti-Arch: allowed"); else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) WriteOkay(Okay, output, "\nMulti-Arch: foreign"); else if ((Ver->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same) WriteOkay(Okay, output, "\nMulti-Arch: same"); - std::set Releases; - for (pkgCache::VerFileIterator I = Ver.FileList(); I.end() == false; ++I) { - pkgCache::PkgFileIterator File = I.File(); - if (File.Flagged(pkgCache::Flag::NotSource) == false) { - string Release = File.RelStr(); - if (!Release.empty()) - Releases.insert(Release); - } - } - if (!Releases.empty()) { - WriteOkay(Okay, output, "\nAPT-Release:"); - for (std::set::iterator R = Releases.begin(); R != Releases.end(); ++R) - WriteOkay(Okay, output, "\n ", *R); - } - WriteOkay(Okay, output, "\nAPT-Pin: ", Cache.GetPolicy().GetPriority(Ver)); - if (Cache.GetCandidateVersion(Pkg) == Ver) - WriteOkay(Okay, output, "\nAPT-Candidate: yes"); - if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) - WriteOkay(Okay, output, "\nAPT-Automatic: yes"); return Okay; } /*}}}*/ @@ -201,7 +171,7 @@ static void WriteScenarioDependency( FILE* output, pkgCache::VerIterator const & if (provides.empty() == false) fprintf(output, "Provides: %s\n", provides.c_str()); } -static bool WriteScenarioDependency(FileFd &output, pkgCache::VerIterator const &Ver) +static bool WriteScenarioDependency(FileFd &output, pkgCache::VerIterator const &Ver, bool const OnlyCritical) { std::array dependencies; bool orGroup = false; @@ -209,6 +179,8 @@ static bool WriteScenarioDependency(FileFd &output, pkgCache::VerIterator const { if (Dep.IsImplicit() == true) continue; + if (OnlyCritical && Dep.IsCritical() == false) + continue; if (orGroup == false && dependencies[Dep->Type].empty() == false) dependencies[Dep->Type].append(", "); dependencies[Dep->Type].append(Dep.TargetPkg().Name()); @@ -300,7 +272,8 @@ static void WriteScenarioLimitedDependency(FILE* output, } static bool WriteScenarioLimitedDependency(FileFd &output, pkgCache::VerIterator const &Ver, - std::vector const &pkgset) + std::vector const &pkgset, + bool const OnlyCritical) { std::array dependencies; bool orGroup = false; @@ -308,6 +281,8 @@ static bool WriteScenarioLimitedDependency(FileFd &output, { if (Dep.IsImplicit() == true) continue; + if (OnlyCritical && Dep.IsCritical() == false) + continue; if (orGroup == false) { if (pkgset[Dep.TargetPkg()->ID] == false) @@ -374,6 +349,42 @@ static bool SkipUnavailableVersions(pkgDepCache &Cache, pkgCache::PkgIterator co return true; } /*}}}*/ +static bool WriteScenarioEDSPVersion(pkgDepCache &Cache, FileFd &output, pkgCache::PkgIterator const &Pkg,/*{{{*/ + pkgCache::VerIterator const &Ver) +{ + bool Okay = WriteOkay(output, "\nSource: ", Ver.SourcePkgName(), + "\nSource-Version: ", Ver.SourceVerStr()); + if (PrioMap[Ver->Priority] != nullptr) + WriteOkay(Okay, output, "\nPriority: ", PrioMap[Ver->Priority]); + if (Ver->Section != 0) + WriteOkay(Okay, output, "\nSection: ", Ver.Section()); + if (Pkg.CurrentVer() == Ver) + WriteOkay(Okay, output, "\nInstalled: yes"); + if (Pkg->SelectedState == pkgCache::State::Hold || + (Cache[Pkg].Keep() == true && Cache[Pkg].Protect() == true)) + WriteOkay(Okay, output, "\nHold: yes"); + std::set Releases; + for (pkgCache::VerFileIterator I = Ver.FileList(); I.end() == false; ++I) { + pkgCache::PkgFileIterator File = I.File(); + if (File.Flagged(pkgCache::Flag::NotSource) == false) { + string Release = File.RelStr(); + if (!Release.empty()) + Releases.insert(Release); + } + } + if (!Releases.empty()) { + WriteOkay(Okay, output, "\nAPT-Release:"); + for (std::set::iterator R = Releases.begin(); R != Releases.end(); ++R) + WriteOkay(Okay, output, "\n ", *R); + } + WriteOkay(Okay, output, "\nAPT-Pin: ", Cache.GetPolicy().GetPriority(Ver)); + if (Cache.GetCandidateVersion(Pkg) == Ver) + WriteOkay(Okay, output, "\nAPT-Candidate: yes"); + if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) + WriteOkay(Okay, output, "\nAPT-Automatic: yes"); + return Okay; +} + /*}}}*/ // EDSP::WriteScenario - to the given file descriptor /*{{{*/ bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress) { @@ -415,8 +426,9 @@ bool EDSP::WriteScenario(pkgDepCache &Cache, FileFd &output, OpProgress *Progres { if (SkipUnavailableVersions(Cache, Pkg, Ver)) continue; - Okay &= WriteScenarioVersion(Cache, output, Pkg, Ver); - Okay &= WriteScenarioDependency(output, Ver); + Okay &= WriteScenarioVersion(output, Pkg, Ver); + Okay &= WriteScenarioEDSPVersion(Cache, output, Pkg, Ver); + Okay &= WriteScenarioDependency(output, Ver, false); WriteOkay(Okay, output, "\n"); if (Progress != NULL && p % 100 == 0) Progress->Progress(p); @@ -464,8 +476,9 @@ bool EDSP::WriteLimitedScenario(pkgDepCache &Cache, FileFd &output, { if (SkipUnavailableVersions(Cache, Pkg, Ver)) continue; - Okay &= WriteScenarioVersion(Cache, output, Pkg, Ver); - Okay &= WriteScenarioLimitedDependency(output, Ver, pkgset); + Okay &= WriteScenarioVersion(output, Pkg, Ver); + Okay &= WriteScenarioEDSPVersion(Cache, output, Pkg, Ver); + Okay &= WriteScenarioLimitedDependency(output, Ver, pkgset, false); WriteOkay(Okay, output, "\n"); if (Progress != NULL && p % 100 == 0) Progress->Progress(p); @@ -722,8 +735,7 @@ static bool StringToBool(char const *answer, bool const defValue) { return 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) +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; @@ -734,6 +746,8 @@ static bool ReadFlag(unsigned int &flags, std::string const &line, APT::StringVi flags &= ~setflag; return true; } + /*}}}*/ +// EDSP::ReadRequest - first stanza from the given file descriptor /*{{{*/ bool EDSP::ReadRequest(int const input, std::list &install, std::list &remove, unsigned int &flags) { @@ -944,13 +958,12 @@ bool EDSP::WriteError(char const * const uuid, std::string const &message, FileF "\n\n"); } /*}}}*/ -// EDSP::ExecuteSolver - fork requested solver and setup ipc pipes {{{*/ -pid_t EDSP::ExecuteSolver(const char* const solver, int * const solver_in, int * const solver_out, bool) { - std::vector const solverDirs = _config->FindVector("Dir::Bin::Solvers"); +static pid_t ExecuteExternal(char const* const type, char const * const binary, char const * const configdir, int * const solver_in, int * const solver_out) {/*{{{*/ + std::vector const solverDirs = _config->FindVector(configdir); std::string file; for (std::vector::const_iterator dir = solverDirs.begin(); dir != solverDirs.end(); ++dir) { - file = flCombine(*dir, solver); + file = flCombine(*dir, binary); if (RealFileExists(file.c_str()) == true) break; file.clear(); @@ -958,7 +971,7 @@ pid_t EDSP::ExecuteSolver(const char* const solver, int * const solver_in, int * if (file.empty() == true) { - _error->Error("Can't call external solver '%s' as it is not in a configured directory!", solver); + _error->Error("Can't call external %s '%s' as it is not in a configured directory!", type, binary); return 0; } int external[4] = {-1, -1, -1, -1}; @@ -976,7 +989,7 @@ pid_t EDSP::ExecuteSolver(const char* const solver, int * const solver_in, int * 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; + std::cerr << "Failed to execute " << type << " '" << binary << "'!" << std::endl; _exit(100); } close(external[0]); @@ -984,13 +997,18 @@ pid_t EDSP::ExecuteSolver(const char* const solver, int * const solver_in, int * if (WaitFd(external[1], true, 5) == false) { - _error->Errno("Resolve", "Timed out while Waiting on availability of solver stdin"); + _error->Errno("Resolve", "Timed out while Waiting on availability of %s stdin", type); return 0; } *solver_in = external[1]; *solver_out = external[2]; return Solver; +} + /*}}}*/ +// EDSP::ExecuteSolver - fork requested solver and setup ipc pipes {{{*/ +pid_t EDSP::ExecuteSolver(const char* const solver, int * const solver_in, int * const solver_out, bool) { + return ExecuteExternal("solver", solver, "Dir::Bin::Solvers", solver_in, solver_out); } bool EDSP::ExecuteSolver(const char* const solver, int *solver_in, int *solver_out) { if (ExecuteSolver(solver, solver_in, solver_out, true) == 0) diff --git a/test/integration/test-external-dependency-solver-protocol b/test/integration/test-external-dependency-solver-protocol index e22684ec5..6b76fd55c 100755 --- a/test/integration/test-external-dependency-solver-protocol +++ b/test/integration/test-external-dependency-solver-protocol @@ -157,41 +157,41 @@ rm -f "$APT_EDSP_DUMP_FILENAME" testsuccess aptinternalsolver scenario testsuccessequal 'Package: stuff -Source: stuff Architecture: all Version: 3 -Source-Version: 3 APT-ID: 1 +Multi-Arch: foreign +Source: stuff +Source-Version: 3 Priority: optional Section: other -Multi-Arch: foreign APT-Release: a=experimental,n=experimental,c=main,b=all APT-Pin: 1 Package: stuff -Source: stuff Architecture: all Version: 2 -Source-Version: 2 APT-ID: 3 +Multi-Arch: foreign +Source: stuff +Source-Version: 2 Priority: optional Section: other -Multi-Arch: foreign APT-Release: a=unstable,n=sid,c=main,b=all APT-Pin: 500 APT-Candidate: yes Package: stuff -Source: stuff Architecture: all Version: 1 -Source-Version: 1 -Installed: yes APT-ID: 8 +Source: stuff +Source-Version: 1 Priority: optional Section: other +Installed: yes APT-Pin: 100 ' aptinternalsolver scenario stuff -- 2.45.2