Imported Upstream version 14.28.0 09/94609/1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 1 Nov 2016 01:29:30 +0000 (10:29 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 1 Nov 2016 01:29:31 +0000 (10:29 +0900)
Change-Id: I7fd4d15098bd4c5782d755fb7fb3453cfec2854a
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
VERSION.cmake
package/libzypp.changes
po/zypp-po.tar.bz2
tests/zypp/CpeId_test.cc
zypp/CpeId.cc
zypp/Product.cc
zypp/Product.h
zypp/RepoManager.cc
zypp/Repository.cc
zypp/Repository.h
zypp/sat/Transaction.cc

index ba6f58a..d2599ed 100644 (file)
 #   See './mkChangelog -h' for help.
 #
 SET(LIBZYPP_MAJOR "14")
-SET(LIBZYPP_COMPATMINOR "27")
-SET(LIBZYPP_MINOR "27")
-SET(LIBZYPP_PATCH "2")
+SET(LIBZYPP_COMPATMINOR "28")
+SET(LIBZYPP_MINOR "28")
+SET(LIBZYPP_PATCH "0")
 #
-# LAST RELEASED: 14.27.2 (27)
+# LAST RELEASED: 14.28.0 (28)
 # (The number in parenthesis is LIBZYPP_COMPATMINOR)
 #=======
index 53590bc..1754ae6 100644 (file)
@@ -1,4 +1,18 @@
 -------------------------------------------------------------------
+Fri Sep  5 12:46:57 CEST 2014 - ma@suse.de
+
+- Make Repository::isUpdateRepo also check for being referenced
+  by products (bnc#892579)
+- Report repositories skipped as nonroot due to insufficient
+  permission (bnc#893260)
+- version 14.28.0 (28)
+
+-------------------------------------------------------------------
+Thu Sep  4 01:14:34 CEST 2014 - ma@suse.de
+
+- Update zypp-po.tar.bz2
+
+-------------------------------------------------------------------
 Fri Aug 29 14:46:25 CEST 2014 - ma@suse.de
 
 - PackageProvider: consider toplevel cache if --root or --pkg-cachedir
index 3d9df3f..3f63b7e 100644 (file)
Binary files a/po/zypp-po.tar.bz2 and b/po/zypp-po.tar.bz2 differ
index 0456095..bce2adb 100644 (file)
@@ -361,7 +361,7 @@ BOOST_AUTO_TEST_CASE(cpeid_basics)
   CpeId( "", CpeId::noThrow );
   BOOST_CHECK_EQUAL( CpeId::NoThrowType::lastMalformed, "" );
 
-  for ( const auto & c : { CpeId(), CpeId( nullptr ), CpeId( "" ), CpeId( std::string() ) } )
+  for ( const auto & c : { CpeId(), CpeId( nullptr ), CpeId( "" ), CpeId( std::string() ), CpeId( "cpe:2.3:" ), CpeId( "cpe:/" ) } )
   {
     BOOST_CHECK( ! c );                        // evaluate false in boolean context
     BOOST_CHECK_EQUAL( c.asString(), c.asFs() );
index b7e80a3..776b8c5 100644 (file)
@@ -353,7 +353,7 @@ namespace zypp
     field.reserve( Attribute::numAttributes );
     if ( str::splitFields( cpe_r.c_str()+8/* skip magic 'cpe:2.3:' */, std::back_inserter(field), ":" ) > Attribute::numAttributes )
       throw std::invalid_argument( str::Str() << "CpeId:Fs: too many fields (" << field.size() << "); expected 11" /*<< Attribute::numAttributes but g++ currently can't resoolve this as constexpr*/ );
-    if ( field.back().empty() )        // A trailing ':' leads to an empty (illegal) field, but we fillup missing fields with ANY|"*"
+    if ( !field.empty() && field.back().empty() )      // A trailing ':' leads to an empty (illegal) field, but we fillup missing fields with ANY|"*"
       field.back() = "*";
     field.resize( Attribute::numAttributes, "*" );     // fillup with ANY|"*"
 
index 79f54a6..61d3301 100644 (file)
@@ -205,14 +205,28 @@ namespace zypp
   Date Product::endOfLife() const
   { return Date( lookupNumAttribute( sat::SolvAttr::productEndOfLife ) );}
 
-  unsigned Product::updateContentIdentifierSize( std::list<Repository::ContentIdentifier> & ret_r ) const
+  std::vector<Repository::ContentIdentifier> Product::updateContentIdentifier() const
+  {
+    std::vector<Repository::ContentIdentifier> ret;
+    sat::LookupAttr q( sat::SolvAttr::productUpdatesRepoid, sat::SolvAttr::productUpdates, *this );
+    if ( ! q.empty() )
+    {
+      ret.reserve( 2 );
+      for_( it, q.begin(), q.end() )
+       ret.push_back( it.asString() );
+    }
+    return ret;
+  }
+
+  bool Product::hasUpdateContentIdentifier( const Repository::ContentIdentifier & cident_r ) const
   {
     sat::LookupAttr q( sat::SolvAttr::productUpdatesRepoid, sat::SolvAttr::productUpdates, *this );
     for_( it, q.begin(), q.end() )
     {
-      ret_r.push_back( it.asString() );
+      if ( it.asString() == cident_r )
+       return true;
     }
-    return q.size();
+    return false;
   }
 
   bool Product::isTargetDistribution() const
index 108b9f6..3cf5dd1 100644 (file)
@@ -100,10 +100,21 @@ namespace zypp
     /** The date when this Product goes out of support as indicated by it's medadata. */
     Date endOfLife() const;
 
-    /** ContentIdentifier of required update repositories.
-     * \todo remove and provide iterator.
-     */
-    unsigned updateContentIdentifierSize( std::list<Repository::ContentIdentifier> & ret_r ) const;
+    /** ContentIdentifier of required update repositories. */
+    std::vector<Repository::ContentIdentifier> updateContentIdentifier() const;
+
+    /** Whether \a cident_r is listed as required update repository. */
+    bool hasUpdateContentIdentifier( const Repository::ContentIdentifier & cident_r ) const;
+
+    /** Whether one of the ContentIdentifier is listed as required update repository. */
+    template <class _Iterator>
+    bool hasUpdateContentIdentifier( _Iterator begin, _Iterator end ) const
+    {
+      for_( it, begin, end )
+       if ( hasUpdateContentIdentifier( *it ) )
+         return true;
+      return false;
+    }
 
   public:
     /** This is the \b installed product that is also targeted by the
index f04694c..5c8e16e 100644 (file)
@@ -203,7 +203,7 @@ namespace zypp
       MIL << "repo file: " << file << endl;
       RepoCollector collector;
       parser::RepoFileReader parser( file, bind( &RepoCollector::collect, &collector, _1 ) );
-      return collector.repos;
+      return std::move(collector.repos);
     }
 
     ////////////////////////////////////////////////////////////////////////////
@@ -220,23 +220,35 @@ namespace zypp
     {
       MIL << "directory " << dir << endl;
       std::list<RepoInfo> repos;
-      std::list<Pathname> entries;
-      if ( filesystem::readdir( entries, dir, false ) != 0 )
+      bool nonroot( geteuid() != 0 );
+      if ( nonroot && ! PathInfo(dir).userMayRX() )
       {
-       // TranslatorExplanation '%s' is a pathname
-       ZYPP_THROW(Exception(str::form(_("Failed to read directory '%s'"), dir.c_str())));
+       JobReport::warning( formatNAC(_("Cannot read repo directory ‘%1%’: Permission denied")) % dir );
       }
-
-      str::regex allowedRepoExt("^\\.repo(_[0-9]+)?$");
-      for ( std::list<Pathname>::const_iterator it = entries.begin(); it != entries.end(); ++it )
+      else
       {
-       if (str::regex_match(it->extension(), allowedRepoExt))
+       std::list<Pathname> entries;
+       if ( filesystem::readdir( entries, dir, false ) != 0 )
        {
-         std::list<RepoInfo> tmp = repositories_in_file( *it );
-         repos.insert( repos.end(), tmp.begin(), tmp.end() );
+         // TranslatorExplanation '%s' is a pathname
+         ZYPP_THROW(Exception(str::form(_("Failed to read directory '%s'"), dir.c_str())));
+       }
 
-         //std::copy( collector.repos.begin(), collector.repos.end(), std::back_inserter(repos));
-         //MIL << "ok" << endl;
+       str::regex allowedRepoExt("^\\.repo(_[0-9]+)?$");
+       for ( std::list<Pathname>::const_iterator it = entries.begin(); it != entries.end(); ++it )
+       {
+         if ( str::regex_match(it->extension(), allowedRepoExt) )
+         {
+           if ( nonroot && ! PathInfo(*it).userMayR() )
+           {
+             JobReport::warning( formatNAC(_("Cannot read repo file ‘%1%’: Permission denied")) % *it );
+           }
+           else
+           {
+             const std::list<RepoInfo> & tmp( repositories_in_file( *it ) );
+             repos.insert( repos.end(), tmp.begin(), tmp.end() );
+           }
+         }
        }
       }
       return repos;
index d5f0776..ae31925 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "zypp/sat/detail/PoolImpl.h"
 #include "zypp/Repository.h"
+#include "zypp/ResPool.h"
+#include "zypp/Product.h"
 #include "zypp/sat/Pool.h"
 
 using std::endl;
@@ -158,18 +160,60 @@ namespace zypp
     bool Repository::providesUpdatesFor( const CpeId & cpeid_r ) const
     {
       NO_REPOSITORY_RETURN( false );
+      if ( ! cpeid_r )
+       return false;   // filter queries/products without CpeId, as an empty CpeId matches ANYthing.
+
+      // check in repository metadata
       for_( it, updatesProductBegin(), updatesProductEnd() )
       {
        if ( compare( cpeid_r, it.cpeId(), SetRelation::subset ) )
          return true;
       }
+
+      // check whether known products refer to this as update repo
+      sat::LookupRepoAttr myIds( sat::SolvAttr::repositoryRepoid, *this );     // usually just one, but...
+      if ( ! myIds.empty() )
+      {
+       const ResPool & pool( ResPool::instance() );
+       for_( it, pool.byKindBegin<Product>(), pool.byKindEnd<Product>() )
+       {
+         Product::constPtr prod( (*it)->asKind<Product>() );
+         if ( compare( cpeid_r, prod->cpeId(), SetRelation::superset ) )
+         {
+           for_( myId, myIds.begin(), myIds.end() )
+           {
+             if ( prod->hasUpdateContentIdentifier( myId.asString() ) )
+               return true;
+           }
+         }
+       }
+      }
       return false;
     }
 
     bool Repository::isUpdateRepo() const
     {
       NO_REPOSITORY_RETURN( false );
-      return ( updatesProductBegin() != updatesProductEnd() );
+
+      // check in repository metadata
+      if ( updatesProductBegin() != updatesProductEnd() )
+       return true;
+
+      // check whether known products refer to this as update repo
+      sat::LookupRepoAttr myIds( sat::SolvAttr::repositoryRepoid, *this );     // usually just one, but...
+      if ( ! myIds.empty() )
+      {
+       const ResPool & pool( ResPool::instance() );
+       for_( it, pool.byKindBegin<Product>(), pool.byKindEnd<Product>() )
+       {
+         for_( myId, myIds.begin(), myIds.end() )
+         {
+           if ( (*it)->asKind<Product>()->hasUpdateContentIdentifier( myId.asString() ) )
+             return true;
+         }
+       }
+      }
+      return false;
     }
 
     bool Repository::solvablesEmpty() const
index 4103965..6ed1725 100644 (file)
@@ -168,17 +168,20 @@ namespace zypp
          */
         bool maybeOutdated() const;
 
-        /**
-         * if the repository claims to update something then
-         * it is an update repository
-         *
-         * This is implemented by looking at the repository updates
-         * tag.
-         * \see http://en.opensuse.org/Standards/Rpm_Metadata#SUSE_repository_info_.28suseinfo.xml.29.2C_extensions_to_repomd.xml
+        /** Hint whether the Repo may provide updates for a product.
+        *
+         * Either the repository claims to update a product via a repository updates
+         * tag in it's metadata or a known product lists the repositories ContentIdentifier
+        * as required update repo.
          */
         bool isUpdateRepo() const;
 
-        /** Whether the repository claims to provide updates for product identified by it's \ref CpeId */
+        /** Hint whether the Repo may provide updates for a product identified by it's \ref CpeId
+        *
+         * Either the repository claims to update a product via a repository updates
+         * tag in it's metadata or a known product lists the repositories ContentIdentifier
+        * as required update repo.
+        */
         bool providesUpdatesFor( const CpeId & cpeid_r ) const;
 
         /** Whether \ref Repository contains solvables. */
@@ -195,7 +198,7 @@ namespace zypp
 
     public:
 
-      /** Query class for Repository */
+      /** Query class for Repository related products */
       class ProductInfoIterator;
 
       /**
@@ -215,15 +218,18 @@ namespace zypp
       ProductInfoIterator compatibleWithProductEnd() const;
 
       /**
-       * Get an iterator to the beginning of the repository
-       * compatible distros.
+       * Get an iterator to the beginning of distos the repository
+       * provides upadates for.
+       * \note This is only a hint within the repositories metadata.
+       * The same realation might be expressed by a product listing
+       * this repositories ContentIdentifier as required update repo.
        * \see Repository::ProductInfoIterator
        */
       ProductInfoIterator updatesProductBegin() const;
 
       /**
-       * Get an iterator to the end of the repository
-       * compatible distros.
+       * Get an iterator to the end of distos the repository
+       * provides upadates for.
        * \see Repository::ProductInfoIterator
        */
       ProductInfoIterator updatesProductEnd() const;
@@ -327,6 +333,9 @@ namespace zypp
     /**
      * Query class for Repository related products
      *
+     * Products are identified by CpeIds within the repositories metadata.
+     * \see http://en.opensuse.org/Standards/Rpm_Metadata#SUSE_repository_info_.28suseinfo.xml.29.2C_extensions_to_repomd.xml
+     *
      * The iterator does not provide a dereference
      * operator so you can do * on it, but you can
      * access the attributes of each related product
@@ -335,7 +344,7 @@ namespace zypp
      * \code
      * for_( it, repo.compatibleWithProductBegin(), repo.compatibleWithProductEnd() )
      * {
-     *   cout << it.cpeid() << endl;
+     *   cout << it.label() << ": " << it.cpeid() << endl;
      * }
      * \endcode
      *
index 537a8f3..560c7b1 100644 (file)
@@ -72,7 +72,7 @@ namespace zypp
       public:
        Impl()
          : _trans( ::transaction_create( nullptr ) )
-       { memset( _trans, 0, sizeof(_trans) ); }
+       { memset( _trans, 0, sizeof(*_trans) ); }
 
        Impl( LoadFromPoolType )
          : _watcher( myPool().serial() )