Imported Upstream version 14.29.4 14/94614/1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 1 Nov 2016 01:30:23 +0000 (10:30 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 1 Nov 2016 01:30:23 +0000 (10:30 +0900)
Change-Id: I2cd89cb098c6992751cd29f15fd4c85030f5bd9f
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
VERSION.cmake
doc/autoinclude/Plugins.doc
libzypp.spec.cmake
package/libzypp.changes
po/zypp-po.tar.bz2
zypp/ExternalProgram.cc
zypp/ExternalProgram.h
zypp/RepoManager.cc
zypp/repo/RepoType.cc

index 4d5250a..17c5727 100644 (file)
@@ -61,8 +61,8 @@
 SET(LIBZYPP_MAJOR "14")
 SET(LIBZYPP_COMPATMINOR "29")
 SET(LIBZYPP_MINOR "29")
-SET(LIBZYPP_PATCH "3")
+SET(LIBZYPP_PATCH "4")
 #
-# LAST RELEASED: 14.29.3 (29)
+# LAST RELEASED: 14.29.4 (29)
 # (The number in parenthesis is LIBZYPP_COMPATMINOR)
 #=======
index 7f4fdfa..040b8b1 100644 (file)
@@ -83,6 +83,19 @@ Plugin closes \c stdin and exits when receiving a \c _DISCONNECT message. Upon a
 \endverbatim
 
 <HR><!-- ====================================================================== -->
+\section plugins-impl Developers: Implementation
+
+Plugins are implemented in the following classes:
+
+- \ref zypp::PluginScript (Plugin as an external program)
+- \ref zypp::PluginScriptException
+- \ref zypp::PluginFrame (Message for the stateful protocol)
+- \ref zypp::PluginFrameException
+- \ref zypp::repo::PluginServices (Finds Service plugins)
+
+The plugins default location is obtained from \ref zypp::ZConfig::pluginsPath()
+
+<HR><!-- ====================================================================== -->
 \section plugin-toc Supported plugins
 
 \subpage plugin-commit Escort installation of packages
@@ -91,6 +104,7 @@ Plugin closes \c stdin and exits when receiving a \c _DISCONNECT message. Upon a
 
 \ref plugin-url-resolver
 
+\ref plugin-appdata
 
 <HR><!-- ====================================================================== -->
 \section plugin-services Service plugins
@@ -141,7 +155,7 @@ ZYpp sees a repository whose url has the format:
 plugin:foo?param1=val1&param2=val2
 \endverbatim
 
-ZYpp tries to executa a plugin named foo (in /usr/lib/zypp/plugins/urlresolver) and calla it with the following protocol:
+ZYpp tries to executa a plugin named foo (in /usr/lib/zypp/plugins/urlresolver) and call it with the following protocol:
 
 \verbatim
    RESOLVEURL
@@ -187,16 +201,17 @@ This type of plugin can be combined with service plugins, because a local servic
 In this example, the service plugin could have inmediately resolved the urls and returned http://realurl, but the url resolver allows also to add HTTP headers to the request.
 
 <HR><!-- ====================================================================== -->
-\section plugins-impl Developers: Implementation
+\section plugin-appdata Appdata refresh plugins (repo change)
 
-Plugins are implemented in the following classes:
+Stateless plugins found in /usr/lib/zypp/plugins/appdata are called whenever any of the system repos has changed (added/removed/renamed/modified) or has been refreshed. Detailed information \b what exactly has changed is not available. (scripts are executed IFF euid is '0' and --root is not used). For every enabled system repo we pass alias type and metadata path on the commandline like this:
 
-- \ref zypp::PluginScript (Plugin as an external program)
-- \ref zypp::PluginScriptException
-- \ref zypp::PluginFrame (Message for the stateful protocol)
-- \ref zypp::PluginFrameException
-- \ref zypp::repo::PluginServices (Finds Service plugins)
+\verbatim
+  -R REPO_ALIAS -t REPO_TYPE -p REPO_METADATA_PATH   -R NEXT_REPO....
+\endverbatim
 
-The plugins default location is obtained from \ref zypp::ZConfig::pluginsPath()
+\note REPO_TYPE can be e.g. "rpm-md", "yast2", "plaindir" or "NONE" indicating the repo was not yet probed.
+
+\note REPO_METADATA_PATH can be empty or a not existing directory, indicating valid metadata for the repo are not yet available.
 
+Scripts are executed 'fire and forget' whenever a RepoManager instance that performed changes goes out of scope. So it's up to the script to protect against concurrency.
 */
\ No newline at end of file
index 2ccb787..1045507 100644 (file)
@@ -32,6 +32,7 @@ Obsoletes:      yast2-packagemanager
 
 # Features we provide (update doc/autoinclude/FeatureTest.doc):
 Provides:       libzypp(plugin) = 0
+Provides:       libzypp(plugin:appdata) = 0
 Provides:       libzypp(plugin:commit) = 1
 Provides:       libzypp(plugin:services) = 0
 Provides:       libzypp(plugin:system) = 0
@@ -75,6 +76,7 @@ BuildRequires:  pkg-config
 
 BuildRequires:  libsolv-devel >= 0.6.5
 %if 0%{?suse_version} >= 1100
+BuildRequires:  libsolv-tools
 %requires_eq    libsolv-tools
 %else
 Requires:       libsolv-tools
@@ -209,10 +211,10 @@ export CFLAGS="$RPM_OPT_FLAGS"
 export CXXFLAGS="$RPM_OPT_FLAGS"
 unset TRANSLATION_SET
 unset EXTRA_CMAKE_OPTIONS
-+# Same codebase, but SLES may use it's own translation set.
-+#     suse_version
-+#     1110            SLES11
-+#     1315            SLES12
+# Same codebase, but SLES may use it's own translation set.
+#     suse_version
+     1110            SLES11
+     1315            SLES12
 %if 0%{?suse_version} == 1110 || 0%{?suse_version} == 1315
 if [ -f ../po/sle-zypp-po.tar.bz ]; then
   export TRANSLATION_SET=sle-zypp
@@ -259,6 +261,7 @@ mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/zypp/vendors.d
 mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/zypp/multiversion.d
 mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/zypp
 mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/zypp/plugins
+mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/zypp/plugins/appdata
 mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/zypp/plugins/commit
 mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/zypp/plugins/services
 mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/zypp/plugins/system
index 68ed068..f6c7b81 100644 (file)
@@ -1,4 +1,17 @@
 -------------------------------------------------------------------
+Thu Sep 25 17:59:06 CEST 2014 - ma@suse.de
+
+- Trigger appdata plugin when system repos have changed (bnc#866257)
+- Protect against race when destructing globals
+- BuildRequire libsolv-tools as libsolv-devel no longer does
+- version 14.29.4 (29)
+
+-------------------------------------------------------------------
+Thu Sep 25 01:15:42 CEST 2014 - ma@suse.de
+
+- Update zypp-po.tar.bz2
+
+-------------------------------------------------------------------
 Tue Sep 23 17:07:45 CEST 2014 - ma@suse.de
 
 - Fix computation of userinstalled items (bnc#897404)
index 4623a78..e11fc88 100644 (file)
Binary files a/po/zypp-po.tar.bz2 and b/po/zypp-po.tar.bz2 differ
index 4607c92..d415298 100644 (file)
@@ -182,6 +182,7 @@ namespace zypp {
 
       // retrieve options at beginning of arglist
       const char * redirectStdin = nullptr;    // <[file]
+      const char * redirectStdout = nullptr;   // >[file]
       const char * chdirTo = nullptr;          // #/[path]
 
       if ( root )
@@ -211,6 +212,13 @@ namespace zypp {
              redirectStdin = "/dev/null";
            break;
 
+         case '>':
+           strip = true;
+           redirectStdout = argv[0]+1;
+           if ( *redirectStdout == '\0' )
+             redirectStdout = "/dev/null";
+           break;
+
          case '#':
            strip = true;
            if ( argv[0][1] == '/' )    // #/[path]
@@ -234,6 +242,8 @@ namespace zypp {
         }
         if ( redirectStdin )
           cmdstr << " < '" << redirectStdin << "'";
+        if ( redirectStdout )
+          cmdstr << " > '" << redirectStdout << "'";
         _command = cmdstr.str();
       }
       DBG << "Executing " << _command << endl;
@@ -301,6 +311,13 @@ namespace zypp {
           dup2( inp_fd, 0 );
         }
 
+        if ( redirectStdout )
+        {
+          ::close( 1 );
+          int inp_fd = open( redirectStdout, O_WRONLY|O_CREAT|O_APPEND, 0600 );
+          dup2( inp_fd, 1 );
+        }
+
        // Handle stderr
        if (stderr_disp == Discard_Stderr)
        {
index e1172cf..bc62a4c 100644 (file)
@@ -108,6 +108,10 @@ namespace zypp {
        *   const char* argv[] = { "</tmp/x", "cat", NULL };
        *   ExternalProgram prog( argv );
        * \endcode
+       *
+       * Stdout redirection: If the \b 1st argument starts with a \b '>', the remaining
+       * part is treated as file opened for writing on standard output (or \c /dev/null
+       * if empty).
        */
 
       ExternalProgram();
index ea75ae7..cf7470a 100644 (file)
@@ -21,6 +21,7 @@
 #include "zypp/base/InputStream.h"
 #include "zypp/base/LogTools.h"
 #include "zypp/base/Gettext.h"
+#include "zypp/base/DefaultIntegral.h"
 #include "zypp/base/Function.h"
 #include "zypp/base/Regex.h"
 #include "zypp/PathInfo.h"
@@ -441,19 +442,62 @@ namespace zypp
       init_knownRepositories();
     }
 
+    ~Impl()
+    {
+      // trigger appdata refresh if some repos change
+      if ( _reposDirty && geteuid() == 0 && ( _options.rootDir.empty() || _options.rootDir == "/" ) )
+      {
+       try {
+         std::list<Pathname> entries;
+         filesystem::readdir( entries, _options.pluginsPath/"appdata", false );
+         if ( ! entries.empty() )
+         {
+           ExternalProgram::Arguments cmd;
+           cmd.push_back( "<" );               // discard stdin
+           cmd.push_back( ">" );               // discard stdout
+           cmd.push_back( "PROGRAM" );         // [2] - fix index below if changing!
+           for ( const auto & rinfo : repos() )
+           {
+             if ( ! rinfo.enabled() )
+               continue;
+             cmd.push_back( "-R" );
+             cmd.push_back( rinfo.alias() );
+             cmd.push_back( "-t" );
+             cmd.push_back( rinfo.type().asString() );
+             cmd.push_back( "-p" );
+             cmd.push_back( rinfo.metadataPath().asString() );
+           }
+
+           for_( it, entries.begin(), entries.end() )
+           {
+             PathInfo pi( *it );
+             //DBG << "/tmp/xx ->" << pi << endl;
+             if ( pi.isFile() && pi.userMayRX() )
+             {
+               // trigger plugin
+               cmd[2] = pi.asString();         // [2] - PROGRAM
+               ExternalProgram prog( cmd, ExternalProgram::Stderr_To_Stdout );
+             }
+           }
+         }
+       }
+       catch (...) {}  // no throw in dtor
+      }
+    }
+
   public:
-    bool repoEmpty() const             { return _repos.empty(); }
-    RepoSizeType repoSize() const      { return _repos.size(); }
-    RepoConstIterator repoBegin() const        { return _repos.begin(); }
-    RepoConstIterator repoEnd() const  { return _repos.end(); }
+    bool repoEmpty() const             { return repos().empty(); }
+    RepoSizeType repoSize() const      { return repos().size(); }
+    RepoConstIterator repoBegin() const        { return repos().begin(); }
+    RepoConstIterator repoEnd() const  { return repos().end(); }
 
     bool hasRepo( const std::string & alias ) const
-    { return foundAliasIn( alias, _repos ); }
+    { return foundAliasIn( alias, repos() ); }
 
     RepoInfo getRepo( const std::string & alias ) const
     {
-      RepoConstIterator it( findAlias( alias, _repos ) );
-      return it == _repos.end() ? RepoInfo::noRepo : *it;
+      RepoConstIterator it( findAlias( alias, repos() ) );
+      return it == repos().end() ? RepoInfo::noRepo : *it;
     }
 
   public:
@@ -558,8 +602,8 @@ namespace zypp
     void getRepositoriesInService( const std::string & alias, OutputIterator out ) const
     {
       MatchServiceAlias filter( alias );
-      std::copy( boost::make_filter_iterator( filter, _repos.begin(), _repos.end() ),
-                 boost::make_filter_iterator( filter, _repos.end(), _repos.end() ),
+      std::copy( boost::make_filter_iterator( filter, repos().begin(), repos().end() ),
+                 boost::make_filter_iterator( filter, repos().end(), repos().end() ),
                  out);
     }
 
@@ -567,11 +611,16 @@ namespace zypp
     void init_knownServices();
     void init_knownRepositories();
 
+    const RepoSet & repos() const { return _reposX; }
+    RepoSet & reposManip()        { if ( ! _reposDirty ) _reposDirty = true; return _reposX; }
+
   private:
     RepoManagerOptions _options;
-    RepoSet            _repos;
+    RepoSet            _reposX;
     ServiceSet         _services;
 
+    DefaultIntegral<bool,false> _reposDirty;
+
   private:
     friend Impl * rwcowClone<Impl>( const Impl * rhs );
     /** clone for RWCOW_pointer */
@@ -703,7 +752,7 @@ namespace zypp
        // set the downloaded packages path for the repo
        repoInfo.setPackagesPath( packagescache_path_for_repoinfo(_options, repoInfo) );
        // remember it
-        _repos.insert( repoInfo );
+        _reposX.insert( repoInfo );    // direct access via _reposX in ctor! no reposManip.
 
        // detect orphaned repos belonging to a deleted service
        const std::string & serviceAlias( repoInfo.service() );
@@ -1063,6 +1112,7 @@ namespace zypp
         // ok we have the metadata, now exchange
         // the contents
        filesystem::exchange( tmpdir.path(), mediarootpath );
+       reposManip();   // remember to trigger appdata refresh
 
         // we are done.
         return;
@@ -1454,7 +1504,7 @@ namespace zypp
     MIL << "Try adding repo " << info << endl;
 
     RepoInfo tosave = info;
-    if ( _repos.find(tosave) != _repos.end() )
+    if ( repos().find(tosave) != repos().end() )
       ZYPP_THROW(RepoAlreadyExistsException(info));
 
     // check the first url for now
@@ -1501,7 +1551,7 @@ namespace zypp
       oinfo.setMetadataPath( metadataPath( tosave ) );
       oinfo.setPackagesPath( packagesPath( tosave ) );
     }
-    _repos.insert(tosave);
+    reposManip().insert(tosave);
 
     progress.set(90);
 
@@ -1579,7 +1629,7 @@ namespace zypp
       MIL << "Saving " << (*it).alias() << endl;
       it->setFilepath(repofile.asString());
       it->dumpAsIniOn(file);
-      _repos.insert(*it);
+      reposManip().insert(*it);
 
       HistoryLog(_options.rootDir).addRepository(*it);
     }
@@ -1663,7 +1713,7 @@ namespace zypp
         // now delete metadata (#301037)
         cleanMetadata( todelete, mSubprogrcv );
        cleanPackages( todelete, pSubprogrcv );
-        _repos.erase(todelete);
+        reposManip().erase(todelete);
         MIL << todelete.alias() << " sucessfully deleted." << endl;
         HistoryLog(_options.rootDir).removeRepository(todelete);
         return;
@@ -1723,8 +1773,8 @@ namespace zypp
       }
 
       newinfo.setFilepath(toedit.filepath());
-      _repos.erase(toedit);
-      _repos.insert(newinfo);
+      reposManip().erase(toedit);
+      reposManip().insert(newinfo);
       HistoryLog(_options.rootDir).modifyRepository(toedit, newinfo);
       MIL << "repo " << alias << " modified" << endl;
     }
@@ -1734,8 +1784,8 @@ namespace zypp
 
   RepoInfo RepoManager::Impl::getRepositoryInfo( const std::string & alias, const ProgressData::ReceiverFnc & progressrcv )
   {
-    RepoConstIterator it( findAlias( alias, _repos ) );
-    if ( it != _repos.end() )
+    RepoConstIterator it( findAlias( alias, repos() ) );
+    if ( it != repos().end() )
       return *it;
     RepoInfo info;
     info.setAlias( alias );
index 936f848..390e406 100644 (file)
@@ -21,7 +21,7 @@ namespace repo
   {
     static NamedValue<RepoType::Type> & table()
     {
-      static NamedValue<RepoType::Type> _t;
+      static NamedValue<RepoType::Type> & _t( *new NamedValue<RepoType::Type> );
       if ( _t.empty() )
       {
        _t( RepoType::RPMMD_e )         | "rpm-md"      | "rpmmd"|"repomd"|"yum"|"up2date";