Imported Upstream version 17.0.0
[platform/upstream/libzypp.git] / zypp / target / TargetImpl.cc
index ff1b264..b894100 100644 (file)
@@ -54,7 +54,7 @@
 #include "zypp/sat/detail/PoolImpl.h"
 #include "zypp/sat/Transaction.h"
 
-#include "zypp/PluginScript.h"
+#include "zypp/PluginExecutor.h"
 
 using namespace std;
 
@@ -231,149 +231,6 @@ namespace zypp
     } // namespace
     ///////////////////////////////////////////////////////////////////
 
-    /** Helper for commit plugin execution.
-     * \ingroup g_RAII
-     */
-    class CommitPlugins : private base::NonCopyable
-    {
-      public:
-       /** Default ctor: Empty plugin list */
-       CommitPlugins()
-       {}
-
-       /** Dtor: Send PLUGINEND message and close plugins. */
-       ~CommitPlugins()
-       {
-         if ( ! _scripts.empty() )
-           send( PluginFrame( "PLUGINEND" ) );
-         // ~PluginScript will disconnect all remaining plugins!
-       }
-
-       /** Whether no plugins are waiting */
-       bool empty() const
-       { return _scripts.empty(); }
-
-
-       /** Send \ref PluginFrame to all open plugins.
-        * Failed plugins are removed from the execution list.
-        */
-       void send( const PluginFrame & frame_r )
-       {
-         DBG << "+++++++++++++++ send " << frame_r << endl;
-         for ( auto it = _scripts.begin(); it != _scripts.end(); )
-         {
-           doSend( *it, frame_r );
-           if ( it->isOpen() )
-             ++it;
-           else
-             it = _scripts.erase( it );
-         }
-         DBG << "--------------- send " << frame_r << endl;
-       }
-
-       /** Find and launch plugins sending PLUGINSTART message.
-        *
-        * If \a path_r is a directory all executable files whithin are
-        * expected to be plugins. Otherwise \a path_r must point to an
-        * executable plugin.
-        */
-       void load( const Pathname & path_r )
-       {
-         PathInfo pi( path_r );
-         DBG << "+++++++++++++++ load " << pi << endl;
-         if ( pi.isDir() )
-         {
-           std::list<Pathname> entries;
-           if ( filesystem::readdir( entries, pi.path(), false ) != 0 )
-           {
-             WAR << "Plugin dir is not readable: " << pi << endl;
-             return;
-           }
-           for_( it, entries.begin(), entries.end() )
-           {
-             PathInfo pii( *it );
-             if ( pii.isFile() && pii.userMayRX() )
-               doLoad( pii );
-           }
-         }
-         else if ( pi.isFile() )
-         {
-           if ( pi.userMayRX() )
-             doLoad( pi );
-           else
-             WAR << "Plugin file is not executable: " << pi << endl;
-         }
-         else
-         {
-           WAR << "Plugin path is neither dir nor file: " << pi << endl;
-         }
-         DBG << "--------------- load " << pi << endl;
-       }
-
-      private:
-       /** Send \ref PluginFrame and expect valid answer (ACK|_ENOMETHOD).
-        * Upon invalid answer or error, close the plugin. and remove it from the
-        * execution list.
-        * \returns the received \ref PluginFrame (empty Frame upon Exception)
-        */
-       PluginFrame doSend( PluginScript & script_r, const PluginFrame & frame_r )
-       {
-         PluginFrame ret;
-
-         try {
-           script_r.send( frame_r );
-           ret = script_r.receive();
-         }
-         catch( const zypp::Exception & e )
-         { ZYPP_CAUGHT(e); }
-
-         if ( ! ( ret.isAckCommand() || ret.isEnomethodCommand() ) )
-         {
-           WAR << "Bad plugin response from " << script_r << endl;
-           WAR << dump(ret) << endl;
-           script_r.close();
-         }
-
-         return ret;
-       }
-
-       /** Launch a plugin sending PLUGINSTART message. */
-       void doLoad( const PathInfo & pi_r )
-       {
-         MIL << "Load plugin: " << pi_r << endl;
-         try {
-           PluginScript plugin( pi_r.path() );
-           plugin.open();
-
-           PluginFrame frame( "PLUGINBEGIN" );
-           if ( ZConfig::instance().hasUserData() )
-             frame.setHeader( "userdata", ZConfig::instance().userData() );
-
-           doSend( plugin, frame );    // closes on error
-           if ( plugin.isOpen() )
-             _scripts.push_back( plugin );
-         }
-         catch( const zypp::Exception & e )
-         {
-            WAR << "Failed to load plugin " << pi_r << endl;
-         }
-       }
-
-      private:
-       std::list<PluginScript> _scripts;
-    };
-
-    void testCommitPlugins( const Pathname & path_r ) // for testing only
-    {
-      USR << "+++++" << endl;
-      {
-       CommitPlugins pl;
-       pl.load( path_r );
-       USR << "=====" << endl;
-      }
-      USR << "-----" << endl;
-    }
-
     ///////////////////////////////////////////////////////////////////
     namespace
     {
@@ -894,9 +751,11 @@ namespace zypp
 
     void TargetImpl::createAnonymousId() const
     {
+      // bsc#1024741: Omit creating a new uid for chrooted systems (if it already has one, fine)
+      if ( root() != "/" )
+       return;
 
-      // create the anonymous unique id
-      // this value is used for statistics
+      // Create the anonymous unique id, used for download statistics
       Pathname idpath( home() / "AnonymousUniqueId");
 
       try
@@ -1097,27 +956,13 @@ namespace zypp
         guard.resetDispose();
        sat::updateSolvFileIndex( rpmsolv );    // content digest for zypper bash completion
 
-       // Finally send notification to plugins
-       // NOTE: quick hack looking for spacewalk plugin only
+       // system-hook: Finally send notification to plugins
+       if ( root() == "/" )
        {
-         Pathname script( Pathname::assertprefix( _root, ZConfig::instance().pluginsPath()/"system/spacewalk" ) );
-         if ( PathInfo( script ).isX() )
-           try {
-             PluginScript spacewalk( script );
-             spacewalk.open();
-
-             PluginFrame notify( "PACKAGESETCHANGED" );
-             spacewalk.send( notify );
-
-             PluginFrame ret( spacewalk.receive() );
-             MIL << ret << endl;
-             if ( ret.command() == "ERROR" )
-               ret.writeTo( WAR ) << endl;
-           }
-           catch ( const Exception & excpt )
-           {
-             WAR << excpt.asUserHistory() << endl;
-           }
+         PluginExecutor plugins;
+         plugins.load( ZConfig::instance().pluginsPath()/"system" );
+         if ( plugins )
+           plugins.send( PluginFrame( "PACKAGESETCHANGED" ) );
        }
       }
       else
@@ -1298,19 +1143,18 @@ namespace zypp
       ///////////////////////////////////////////////////////////////////
       // Prepare execution of commit plugins:
       ///////////////////////////////////////////////////////////////////
-      CommitPlugins commitPlugins;
+      PluginExecutor commitPlugins;
       if ( root() == "/" && ! policy_r.dryRun() )
       {
-       Pathname plugindir( Pathname::assertprefix( _root, ZConfig::instance().pluginsPath()/"commit" ) );
-       commitPlugins.load( plugindir );
+       commitPlugins.load( ZConfig::instance().pluginsPath()/"commit" );
       }
-      if ( ! commitPlugins.empty() )
+      if ( commitPlugins )
        commitPlugins.send( transactionPluginFrame( "COMMITBEGIN", steps ) );
 
       ///////////////////////////////////////////////////////////////////
       // Write out a testcase if we're in dist upgrade mode.
       ///////////////////////////////////////////////////////////////////
-      if ( getZYpp()->resolver()->upgradeMode() )
+      if ( pool_r.resolver().upgradeMode() || pool_r.resolver().upgradingRepos() )
       {
         if ( ! policy_r.dryRun() )
         {
@@ -1390,7 +1234,7 @@ namespace zypp
       if ( ! policy_r.dryRun() || policy_r.downloadMode() == DownloadOnly )
       {
        // Prepare the package cache. Pass all items requiring download.
-        CommitPackageCache packageCache( root() );
+        CommitPackageCache packageCache;
        packageCache.setCommitList( steps.begin(), steps.end() );
 
         bool miss = false;
@@ -1420,22 +1264,7 @@ namespace zypp
               ManagedFile localfile;
               try
               {
-               // TODO: unify packageCache.get for Package and SrcPackage
-               if ( pi->isKind<Package>() )
-               {
-                 localfile = packageCache.get( pi );
-               }
-               else if ( pi->isKind<SrcPackage>() )
-               {
-                 repo::RepoMediaAccess access;
-                 repo::SrcPackageProvider prov( access );
-                 localfile = prov.provideSrcPackage( pi->asKind<SrcPackage>() );
-               }
-               else
-               {
-                 INT << "Don't know howto cache: Neither Package nor SrcPackage: " << pi << endl;
-                 continue;
-               }
+               localfile = packageCache.get( pi );
                 localfile.resetDispose(); // keep the package file in the cache
               }
               catch ( const AbortRequestException & exp )
@@ -1495,7 +1324,7 @@ namespace zypp
       ///////////////////////////////////////////////////////////////////
       // Send result to commit plugins:
       ///////////////////////////////////////////////////////////////////
-      if ( ! commitPlugins.empty() )
+      if ( commitPlugins )
        commitPlugins.send( transactionPluginFrame( "COMMITEND", steps ) );
 
       ///////////////////////////////////////////////////////////////////
@@ -1867,7 +1696,7 @@ namespace zypp
         }
         return std::string();
       }
-    } // namescpace
+    } // namespace
     ///////////////////////////////////////////////////////////////////
 
     Product::constPtr TargetImpl::baseProduct() const
@@ -1891,6 +1720,15 @@ namespace zypp
       return RequestedLocalesFile( home(needroot) / "RequestedLocales" ).locales();
     }
 
+    void TargetImpl::updateAutoInstalled()
+    {
+      MIL << "updateAutoInstalled if changed..." << endl;
+      SolvIdentFile::Data newdata;
+      for ( auto id : sat::Pool::instance().autoInstalled() )
+       newdata.insert( IdString(id) ); // explicit ctor!
+      _autoInstalledFile.setData( std::move(newdata) );
+    }
+
     std::string TargetImpl::targetDistribution() const
     { return baseproductdata( _root ).registerTarget(); }
     // static version:
@@ -1979,15 +1817,29 @@ namespace zypp
     }
 
     ///////////////////////////////////////////////////////////////////
+    namespace
+    {
+      std::string guessAnonymousUniqueId( const Pathname & root_r )
+      {
+       // bsc#1024741: Omit creating a new uid for chrooted systems (if it already has one, fine)
+       std::string ret( firstNonEmptyLineIn( root_r / "/var/lib/zypp/AnonymousUniqueId" ) );
+       if ( ret.empty() && root_r != "/" )
+       {
+         // if it has nonoe, use the outer systems one
+         ret = firstNonEmptyLineIn( "/var/lib/zypp/AnonymousUniqueId" );
+       }
+       return ret;
+      }
+    }
 
     std::string TargetImpl::anonymousUniqueId() const
     {
-      return firstNonEmptyLineIn( home() / "AnonymousUniqueId" );
+      return guessAnonymousUniqueId( root() );
     }
     // static version:
     std::string TargetImpl::anonymousUniqueId( const Pathname & root_r )
     {
-      return firstNonEmptyLineIn( staticGuessRoot(root_r) / "/var/lib/zypp/AnonymousUniqueId" );
+      return guessAnonymousUniqueId( staticGuessRoot(root_r) );
     }
 
     ///////////////////////////////////////////////////////////////////
@@ -1996,6 +1848,9 @@ namespace zypp
     {
       // provide on local disk
       ManagedFile localfile = provideSrcPackage(srcPackage_r);
+      // create a installation progress report proxy
+      RpmInstallPackageReceiver progress( srcPackage_r );
+      progress.connect(); // disconnected on destruction.
       // install it
       rpm().installPackage ( localfile );
     }