Просмотр исходного кода

implement autobit and pinning in EDSP solver 'apt'

The parser creates a preferences as well as an extended states file
based on the EDSP scenario file, which isn't the most efficient way of
dealing with this as thes text files have to be parsed again by another
layer of the code, but it needs the least changes and works good enough
for now. The 'apt' solver is in the end just a test solver like dump.
David Kalnischkies лет назад: 10
Родитель
Сommit
188a6fcf4f

+ 46 - 4
apt-pkg/edsp/edsplistparser.cc

@@ -11,18 +11,40 @@
 // Include Files							/*{{{*/
 #include <config.h>
 
+#include <apt-pkg/configuration.h>
 #include <apt-pkg/edsplistparser.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/deblistparser.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/tagfile.h>
+#include <apt-pkg/fileutl.h>
 
 									/*}}}*/
 
+class edspListParserPrivate						/*{{{*/
+{
+public:
+   FileFd extendedstates;
+   FileFd preferences;
+
+   edspListParserPrivate()
+   {
+      std::string const states = _config->FindFile("Dir::State::extended_states");
+      if (states != "/dev/null")
+	 unlink(states.c_str());
+      extendedstates.Open(states, FileFd::WriteOnly | FileFd::Create | FileFd::Exclusive, 0600);
+      std::string const prefs = _config->FindFile("Dir::Etc::preferences");
+      if (prefs != "/dev/null")
+	 unlink(prefs.c_str());
+      preferences.Open(prefs, FileFd::WriteOnly | FileFd::Create | FileFd::Exclusive, 0600);
+   }
+};
+									/*}}}*/
 // ListParser::edspListParser - Constructor				/*{{{*/
-edspListParser::edspListParser(FileFd *File) : debListParser(File), d(NULL)
-{}
+edspListParser::edspListParser(FileFd *File) : debListParser(File), d(new edspListParserPrivate())
+{
+}
 									/*}}}*/
 // ListParser::NewVersion - Fill in the version structure		/*{{{*/
 bool edspListParser::NewVersion(pkgCache::VerIterator &Ver)
@@ -81,6 +103,23 @@ bool edspListParser::ParseStatus(pkgCache::PkgIterator &Pkg,
       Pkg->CurrentVer = Ver.Index();
    }
 
+   if (Section.FindB("APT-Automatic", false))
+   {
+      std::string out;
+      strprintf(out, "Package: %s\nArchitecture: %s\nAuto-Installed: 1\n\n", Pkg.Name(), Pkg.Arch());
+      if (d->extendedstates.Write(out.c_str(), out.length()) == false)
+	 return false;
+   }
+
+   signed short const pinvalue = Section.FindI("APT-Pin", 500);
+   if (pinvalue != 500)
+   {
+      std::string out;
+      strprintf(out, "Package: %s\nPin: version %s\nPin-Priority: %d\n\n", Pkg.FullName().c_str(), Ver.VerStr(), pinvalue);
+      if (d->preferences.Write(out.c_str(), out.length()) == false)
+	 return false;
+   }
+
    return true;
 }
 									/*}}}*/
@@ -91,5 +130,8 @@ APT_CONST bool edspListParser::LoadReleaseInfo(pkgCache::RlsFileIterator & /*Fil
    return true;
 }
 									/*}}}*/
-
-edspListParser::~edspListParser() {}
+edspListParser::~edspListParser()					/*{{{*/
+{
+   delete d;
+}
+									/*}}}*/

+ 2 - 1
apt-pkg/edsp/edsplistparser.h

@@ -24,10 +24,11 @@
 #endif
 
 class FileFd;
+class edspListParserPrivate;
 
 class APT_HIDDEN edspListParser : public debListParser
 {
-   void * const d;
+   edspListParserPrivate * const d;
    public:
    virtual bool NewVersion(pkgCache::VerIterator &Ver) APT_OVERRIDE;
    virtual std::string Description();

+ 44 - 2
apt-pkg/edsp/edspsystem.cc

@@ -17,15 +17,55 @@
 #include <apt-pkg/edspsystem.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/cacheiterators.h>
+#include <apt-pkg/fileutl.h>
 
 #include <stddef.h>
+#include <unistd.h>
+
 #include <string>
 #include <vector>
 
 									/*}}}*/
 
+class edspSystemPrivate {
+   std::string tempDir;
+   std::string tempStatesFile;
+   std::string tempPrefsFile;
+
+public:
+   edspSystemPrivate() {}
+
+   void Initialize(Configuration &Cnf)
+   {
+      DeInitialize();
+      Cnf.Set("Dir::State::extended_states", "/dev/null");
+      Cnf.Set("Dir::Etc::preferences", "/dev/null");
+      std::string const tmp = GetTempDir();
+      char tmpname[100];
+      snprintf(tmpname, sizeof(tmpname), "%s/apt-edsp-solver-XXXXXX", tmp.c_str());
+      if (NULL == mkdtemp(tmpname))
+	 return;
+      tempDir = tmpname;
+      tempStatesFile = flCombine(tempDir, "extended_states");
+      Cnf.Set("Dir::State::extended_states", tempStatesFile);
+      tempPrefsFile = flCombine(tempDir, "apt_preferences");
+      Cnf.Set("Dir::Etc::preferences", tempPrefsFile);
+   }
+
+   void DeInitialize()
+   {
+      if (tempDir.empty())
+	 return;
+
+      unlink(tempStatesFile.c_str());
+      unlink(tempPrefsFile.c_str());
+      rmdir(tempDir.c_str());
+   }
+
+   ~edspSystemPrivate() { DeInitialize(); }
+};
 // System::edspSystem - Constructor					/*{{{*/
-edspSystem::edspSystem() : pkgSystem("Debian APT solver interface", &debVS), d(NULL), StatusFile(NULL)
+edspSystem::edspSystem() : pkgSystem("Debian APT solver interface", &debVS), d(new edspSystemPrivate()), StatusFile(NULL)
 {
 }
 									/*}}}*/
@@ -33,6 +73,7 @@ edspSystem::edspSystem() : pkgSystem("Debian APT solver interface", &debVS), d(N
 edspSystem::~edspSystem()
 {
    delete StatusFile;
+   delete d;
 }
 									/*}}}*/
 // System::Lock - Get the lock						/*{{{*/
@@ -59,7 +100,8 @@ pkgPackageManager *edspSystem::CreatePM(pkgDepCache * /*Cache*/) const
 // System::Initialize - Setup the configuration space..			/*{{{*/
 bool edspSystem::Initialize(Configuration &Cnf)
 {
-   Cnf.Set("Dir::State::extended_states", "/dev/null");
+   d->Initialize(Cnf);
+   Cnf.Set("Dir::Etc::preferencesparts", "/dev/null");
    Cnf.Set("Dir::State::status","/dev/null");
    Cnf.Set("Dir::State::lists","/dev/null");
 

+ 2 - 1
apt-pkg/edsp/edspsystem.h

@@ -24,10 +24,11 @@ class pkgIndexFile;
 class pkgPackageManager;
 class edspIndex;
 
+class edspSystemPrivate;
 class APT_HIDDEN edspSystem : public pkgSystem
 {
    /** \brief dpointer placeholder (for later in case we need it) */
-   void * const d;
+   edspSystemPrivate * const d;
 
    edspIndex *StatusFile;
 

+ 2 - 1
apt-pkg/policy.cc

@@ -409,7 +409,8 @@ bool ReadPinDir(pkgPolicy &Plcy,string Dir)
 
    if (DirectoryExists(Dir) == false)
    {
-      _error->WarningE("DirectoryExists",_("Unable to read %s"),Dir.c_str());
+      if (Dir != "/dev/null")
+	 _error->WarningE("DirectoryExists",_("Unable to read %s"),Dir.c_str());
       return true;
    }
 

+ 38 - 5
test/integration/test-external-dependency-solver-protocol

@@ -8,6 +8,7 @@ configarchitecture 'amd64' 'i386'
 
 insertinstalledpackage 'cool' 'all' '1'
 insertinstalledpackage 'stuff' 'all' '1'
+insertinstalledpackage 'somestuff' 'all' '1' 'Depends: cool, stuff'
 
 insertpackage 'unstable' 'cool' 'all' '2' 'Multi-Arch: foreign'
 insertpackage 'unstable' 'stuff' 'all' '2' 'Multi-Arch: foreign'
@@ -40,7 +41,15 @@ E: External solver failed with: I am too dumb, i can just dump!' aptget install
 testsuccess test -s "$APT_EDSP_DUMP_FILENAME"
 rm -f "$APT_EDSP_DUMP_FILENAME"
 
-#FIXME: this should be unstable, but we don't support pinning yet
+testsuccessequal 'Reading package lists...
+Building dependency tree...
+Execute external solver...
+The following NEW packages will be installed:
+  coolstuff
+0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
+Inst coolstuff (2 unstable [amd64])
+Conf coolstuff (2 unstable [amd64])' aptget install --solver apt coolstuff -s
+
 testsuccessequal 'Reading package lists...
 Building dependency tree...
 Execute external solver...
@@ -48,15 +57,39 @@ The following NEW packages will be installed:
   coolstuff
 0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
 Inst coolstuff (3 experimental [amd64])
-Conf coolstuff (3 experimental [amd64])' aptget install --solver apt coolstuff -s
+Conf coolstuff (3 experimental [amd64])' aptget install --solver apt coolstuff -s -t experimental
 
 testsuccessequal 'Reading package lists...
 Building dependency tree...
 Execute external solver...
 The following packages will be REMOVED:
-  cool*
-0 upgraded, 0 newly installed, 1 to remove and 1 not upgraded.
-Purg cool [1]' aptget purge --solver apt cool -s
+  somestuff
+0 upgraded, 0 newly installed, 1 to remove and 2 not upgraded.
+Remv somestuff [1]' aptget autoremove --solver apt somestuff -s
+testsuccess aptmark auto cool stuff
+testsuccessequal 'Reading package lists...
+Building dependency tree...
+Reading state information...
+Execute external solver...
+The following packages will be REMOVED:
+  cool somestuff stuff
+0 upgraded, 0 newly installed, 3 to remove and 0 not upgraded.
+Remv somestuff [1]
+Remv cool [1]
+Remv stuff [1]' aptget autoremove --solver apt somestuff -s
+
+testsuccessequal "Reading package lists...
+Building dependency tree...
+Reading state information...
+Execute external solver...
+The following package was automatically installed and is no longer required:
+  stuff
+Use 'apt-get autoremove' to remove it.
+The following packages will be REMOVED:
+  cool* somestuff*
+0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded.
+Purg somestuff [1]
+Purg cool [1]" aptget purge --solver apt cool -s
 
 testsuccess aptget install awesomecoolstuff:i386 -s
 testsuccess aptget install --solver apt awesomecoolstuff:i386 -s