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

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 Files							/*{{{*/
 #include <config.h>
 #include <config.h>
 
 
+#include <apt-pkg/configuration.h>
 #include <apt-pkg/edsplistparser.h>
 #include <apt-pkg/edsplistparser.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/deblistparser.h>
 #include <apt-pkg/deblistparser.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/tagfile.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				/*{{{*/
 // 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		/*{{{*/
 // ListParser::NewVersion - Fill in the version structure		/*{{{*/
 bool edspListParser::NewVersion(pkgCache::VerIterator &Ver)
 bool edspListParser::NewVersion(pkgCache::VerIterator &Ver)
@@ -81,6 +103,23 @@ bool edspListParser::ParseStatus(pkgCache::PkgIterator &Pkg,
       Pkg->CurrentVer = Ver.Index();
       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;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -91,5 +130,8 @@ APT_CONST bool edspListParser::LoadReleaseInfo(pkgCache::RlsFileIterator & /*Fil
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-
-edspListParser::~edspListParser() {}
+edspListParser::~edspListParser()					/*{{{*/
+{
+   delete d;
+}
+									/*}}}*/

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

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

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

@@ -17,15 +17,55 @@
 #include <apt-pkg/edspsystem.h>
 #include <apt-pkg/edspsystem.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/cacheiterators.h>
+#include <apt-pkg/fileutl.h>
 
 
 #include <stddef.h>
 #include <stddef.h>
+#include <unistd.h>
+
 #include <string>
 #include <string>
 #include <vector>
 #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					/*{{{*/
 // 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()
 edspSystem::~edspSystem()
 {
 {
    delete StatusFile;
    delete StatusFile;
+   delete d;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // System::Lock - Get the lock						/*{{{*/
 // System::Lock - Get the lock						/*{{{*/
@@ -59,7 +100,8 @@ pkgPackageManager *edspSystem::CreatePM(pkgDepCache * /*Cache*/) const
 // System::Initialize - Setup the configuration space..			/*{{{*/
 // System::Initialize - Setup the configuration space..			/*{{{*/
 bool edspSystem::Initialize(Configuration &Cnf)
 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::status","/dev/null");
    Cnf.Set("Dir::State::lists","/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 pkgPackageManager;
 class edspIndex;
 class edspIndex;
 
 
+class edspSystemPrivate;
 class APT_HIDDEN edspSystem : public pkgSystem
 class APT_HIDDEN edspSystem : public pkgSystem
 {
 {
    /** \brief dpointer placeholder (for later in case we need it) */
    /** \brief dpointer placeholder (for later in case we need it) */
-   void * const d;
+   edspSystemPrivate * const d;
 
 
    edspIndex *StatusFile;
    edspIndex *StatusFile;
 
 

+ 2 - 1
apt-pkg/policy.cc

@@ -409,7 +409,8 @@ bool ReadPinDir(pkgPolicy &Plcy,string Dir)
 
 
    if (DirectoryExists(Dir) == false)
    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;
       return true;
    }
    }
 
 

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

@@ -8,6 +8,7 @@ configarchitecture 'amd64' 'i386'
 
 
 insertinstalledpackage 'cool' 'all' '1'
 insertinstalledpackage 'cool' 'all' '1'
 insertinstalledpackage 'stuff' 'all' '1'
 insertinstalledpackage 'stuff' 'all' '1'
+insertinstalledpackage 'somestuff' 'all' '1' 'Depends: cool, stuff'
 
 
 insertpackage 'unstable' 'cool' 'all' '2' 'Multi-Arch: foreign'
 insertpackage 'unstable' 'cool' 'all' '2' 'Multi-Arch: foreign'
 insertpackage 'unstable' 'stuff' '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"
 testsuccess test -s "$APT_EDSP_DUMP_FILENAME"
 rm -f "$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...
 testsuccessequal 'Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Execute external solver...
 Execute external solver...
@@ -48,15 +57,39 @@ The following NEW packages will be installed:
   coolstuff
   coolstuff
 0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
 0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
 Inst coolstuff (3 experimental [amd64])
 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...
 testsuccessequal 'Reading package lists...
 Building dependency tree...
 Building dependency tree...
 Execute external solver...
 Execute external solver...
 The following packages will be REMOVED:
 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 awesomecoolstuff:i386 -s
 testsuccess aptget install --solver apt awesomecoolstuff:i386 -s
 testsuccess aptget install --solver apt awesomecoolstuff:i386 -s