Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / target / TargetImpl.cc
index 275f93a..baffb9b 100644 (file)
 #include "zypp/target/RpmPostTransCollector.h"
 
 #include "zypp/parser/ProductFileReader.h"
-
-#include "zypp/solver/detail/Testcase.h"
-
 #include "zypp/repo/SrcPackageProvider.h"
 
 #include "zypp/sat/Pool.h"
+#include "zypp/sat/detail/PoolImpl.h"
 #include "zypp/sat/Transaction.h"
 
 #include "zypp/PluginExecutor.h"
@@ -62,7 +60,20 @@ using namespace std;
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
-{ /////////////////////////////////////////////////////////////////
+{
+  /////////////////////////////////////////////////////////////////
+  namespace
+  {
+    // HACK for bnc#906096: let pool re-evaluate multiversion spec
+    // if target root changes. ZConfig returns data sensitive to
+    // current target root.
+    inline void sigMultiversionSpecChanged()
+    {
+      sat::detail::PoolMember::myPool().multiversionSpecChanged();
+    }
+  } //namespace
+  /////////////////////////////////////////////////////////////////
+
   ///////////////////////////////////////////////////////////////////
   namespace json
   {
@@ -664,16 +675,6 @@ namespace zypp
 
     IMPL_PTR_TYPE(TargetImpl);
 
-    TargetImpl_Ptr TargetImpl::_nullimpl;
-
-    /** Null implementation */
-    TargetImpl_Ptr TargetImpl::nullimpl()
-    {
-      if (_nullimpl == 0)
-        _nullimpl = new TargetImpl;
-      return _nullimpl;
-    }
-
     ///////////////////////////////////////////////////////////////////
     //
     // METHOD NAME : TargetImpl::TargetImpl
@@ -690,7 +691,7 @@ namespace zypp
       HistoryLog::setRoot(_root);
 
       createAnonymousId();
-
+      sigMultiversionSpecChanged();    // HACK: see sigMultiversionSpecChanged
       MIL << "Initialized target on " << _root << endl;
     }
 
@@ -807,6 +808,7 @@ namespace zypp
     TargetImpl::~TargetImpl()
     {
       _rpm.closeDatabase();
+      sigMultiversionSpecChanged();    // HACK: see sigMultiversionSpecChanged
       MIL << "Targets closed" << endl;
     }
 
@@ -903,33 +905,40 @@ namespace zypp
         // Take care we unlink the solvfile on exception
         ManagedFile guard( base, filesystem::recursive_rmdir );
 
-        std::ostringstream cmd;
-        cmd << "rpmdb2solv";
-        if ( ! _root.empty() )
-          cmd << " -r '" << _root << "'";
-       cmd << " -X";   // autogenerate pattern/product/... from -package
-       cmd << " -A";   // autogenerate application pseudo packages
-        cmd << " -p '" << Pathname::assertprefix( _root, "/etc/products.d" ) << "'";
+        ExternalProgram::Arguments cmd;
+        cmd.push_back( "rpmdb2solv" );
+        if ( ! _root.empty() ) {
+          cmd.push_back( "-r" );
+          cmd.push_back( _root.asString() );
+        }
+        cmd.push_back( "-X" ); // autogenerate pattern/product/... from -package
+        cmd.push_back( "-A" ); // autogenerate application pseudo packages
+        cmd.push_back( "-p" );
+        cmd.push_back( Pathname::assertprefix( _root, "/etc/products.d" ).asString() );
 
         if ( ! oldSolvFile.empty() )
-          cmd << " '" << oldSolvFile << "'";
+          cmd.push_back( oldSolvFile.asString() );
 
-        cmd << "  > '" << tmpsolv.path() << "'";
+        cmd.push_back( "-o" );
+        cmd.push_back( tmpsolv.path().asString() );
 
-        MIL << "Executing: " << cmd << endl;
-        ExternalProgram prog( cmd.str(), ExternalProgram::Stderr_To_Stdout );
+        ExternalProgram prog( cmd, ExternalProgram::Stderr_To_Stdout );
+       std::string errdetail;
 
-        cmd << endl;
         for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) {
           WAR << "  " << output;
-          cmd << "     " << output;
+          if ( errdetail.empty() ) {
+            errdetail = prog.command();
+            errdetail += '\n';
+          }
+          errdetail += output;
         }
 
         int ret = prog.close();
         if ( ret != 0 )
         {
           Exception ex(str::form("Failed to cache rpm database (%d).", ret));
-          ex.remember( cmd.str() );
+          ex.remember( errdetail );
           ZYPP_THROW(ex);
         }
 
@@ -943,6 +952,7 @@ namespace zypp
 
         // We keep it.
         guard.resetDispose();
+       sat::updateSolvFileIndex( rpmsolv );    // content digest for zypper bash completion
 
        // system-hook: Finally send notification to plugins
        if ( root() == "/" )
@@ -953,6 +963,12 @@ namespace zypp
            plugins.send( PluginFrame( "PACKAGESETCHANGED" ) );
        }
       }
+      else
+      {
+       // On the fly add missing solv.idx files for bash completion.
+       if ( ! PathInfo(base/"solv.idx").isExist() )
+         sat::updateSolvFileIndex( rpmsolv );
+      }
       return build_rpm_solv;
     }
 
@@ -1013,7 +1029,7 @@ namespace zypp
 
         system.addSolv( rpmsolv );
       }
-      sat::Pool::instance().rootDir( _root );
+      satpool.rootDir( _root );
 
       // (Re)Load the requested locales et al.
       // If the requested locales are empty, we leave the pool untouched
@@ -1024,7 +1040,7 @@ namespace zypp
         const LocaleSet & requestedLocales( _requestedLocalesFile.locales() );
         if ( ! requestedLocales.empty() )
         {
-          satpool.setRequestedLocales( requestedLocales );
+          satpool.initRequestedLocales( requestedLocales );
         }
       }
       {
@@ -1077,7 +1093,6 @@ namespace zypp
     {
       // ----------------------------------------------------------------- //
       ZYppCommitPolicy policy_r( policy_rX );
-      bool explicitDryRun = policy_r.dryRun(); // explicit dry run will trigger a fileconflict check, implicit (download-only) not.
 
       // Fake outstanding YCP fix: Honour restriction to media 1
       // at installation, but install all remaining packages if post-boot.
@@ -1247,7 +1262,22 @@ namespace zypp
               ManagedFile localfile;
               try
               {
-               localfile = packageCache.get( pi );
+               // 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.resetDispose(); // keep the package file in the cache
               }
               catch ( const AbortRequestException & exp )
@@ -1296,20 +1326,12 @@ namespace zypp
          else
          {
            DBG << "dryRun/downloadOnly: Not installing/deleting anything." << endl;
-           if ( explicitDryRun ) {
-             // if cache is preloaded, check for file conflicts
-             commitFindFileConflicts( policy_r, result );
-           }
          }
        }
       }
       else
       {
         DBG << "dryRun: Not downloading/installing/deleting anything." << endl;
-       if ( explicitDryRun ) {
-         // if cache is preloaded, check for file conflicts
-         commitFindFileConflicts( policy_r, result );
-       }
       }
 
       ///////////////////////////////////////////////////////////////////
@@ -1357,6 +1379,8 @@ namespace zypp
       ZYppCommitResult::TransactionStepList & steps( result_r.rTransactionStepList() );
       MIL << "TargetImpl::commit(<list>" << policy_r << ")" << steps.size() << endl;
 
+      HistoryLog().stampCommand();
+
       // Send notification once upon 1st call to rpm
       NotifyAttemptToModify attemptToModify( result_r );
 
@@ -1814,6 +1838,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 );
     }