Imported Upstream version 16.4.1 upstream/16.4.1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 2 Sep 2019 07:11:50 +0000 (16:11 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 2 Sep 2019 07:11:50 +0000 (16:11 +0900)
VERSION.cmake
package/libzypp.changes
zypp/Capability.cc
zypp/Package.cc
zypp/Product.cc
zypp/media/MediaCurl.cc
zypp/media/MediaCurl.h
zypp/media/MediaMultiCurl.cc
zypp/parser/yum/RepomdFileReader.cc
zypp/repo/SrcPackageProvider.cc

index 7164303..04dabd5 100644 (file)
@@ -61,8 +61,8 @@
 SET(LIBZYPP_MAJOR "16")
 SET(LIBZYPP_COMPATMINOR "0")
 SET(LIBZYPP_MINOR "4")
-SET(LIBZYPP_PATCH "0")
+SET(LIBZYPP_PATCH "1")
 #
-# LAST RELEASED: 16.4.0 (0)
+# LAST RELEASED: 16.4.1 (0)
 # (The number in parenthesis is LIBZYPP_COMPATMINOR)
 #=======
index 499e256..bac99fa 100644 (file)
@@ -1,4 +1,11 @@
 -------------------------------------------------------------------
+Fri Feb  3 13:40:04 CET 2017 - ma@suse.de
+
+- MediaMultiCurl: Trigger aliveCallback when downloading metalink
+  files (bsc#1021291)
+- version 16.4.1 (0)
+
+-------------------------------------------------------------------
 Thu Jan 26 13:03:37 CET 2017 - ma@suse.de
 
 - Add API for updating the AutoInstalled db
index 3147c8a..aa4b247 100644 (file)
@@ -313,8 +313,6 @@ namespace zypp
 
   CapMatch Capability::_doMatch( sat::detail::IdType lhs,  sat::detail::IdType rhs )
   {
-#warning MIGRATE TO SAT
-#warning TESTCASE
     if ( lhs == rhs )
       return CapMatch::yes;
 
index 5916f4b..ea2db9c 100644 (file)
@@ -92,6 +92,11 @@ namespace zypp
       case VendorSupportUnsupported:
       case VendorSupportACC:
        return true;
+
+      case VendorSupportLevel1:
+      case VendorSupportLevel2:
+      case VendorSupportLevel3:
+       break;  // intentionally no default:
     }
     return false;
   }
index d5ef49b..80ae25e 100644 (file)
@@ -215,7 +215,7 @@ namespace zypp
   { return Date( lookupNumAttribute( sat::SolvAttr::productEndOfLife ) );}
 
   bool Product::hasEndOfLife() const
-  { return( lookupNumAttribute( sat::SolvAttr::productEndOfLife, -1 ) != -1 ); }
+  { return( lookupNumAttribute( sat::SolvAttr::productEndOfLife, -1 ) != (unsigned long long)(-1) ); }
 
   bool Product::hasEndOfLife( Date & value ) const
   {
index 4859bcf..121cf0f 100644 (file)
@@ -156,25 +156,91 @@ namespace zypp {
   namespace {
     struct ProgressData
     {
-      ProgressData(CURL *_curl, const long _timeout, const zypp::Url &_url = zypp::Url(),
-                   callback::SendReport<DownloadProgressReport> *_report=NULL)
-        : curl(_curl)
-        , timeout(_timeout)
-        , reached(false)
-        , report(_report)
-        , drate_period(-1)
-        , dload_period(0)
-        , secs(0)
-        , drate_avg(-1)
-        , ltime( time(NULL))
-        , dload( 0)
-        , uload( 0)
-        , url(_url)
+      ProgressData( CURL *_curl, time_t _timeout = 0, const Url & _url = Url(),
+                   callback::SendReport<DownloadProgressReport> *_report = nullptr )
+        : curl( _curl )
+       , url( _url )
+       , timeout( _timeout )
+        , reached( false )
+        , report( _report )
       {}
-      CURL                                         *curl;
-      long                                          timeout;
-      bool                                          reached;
+
+      CURL     *curl;
+      Url      url;
+      time_t   timeout;
+      bool     reached;
       callback::SendReport<DownloadProgressReport> *report;
+
+      time_t _timeStart        = 0;    ///< Start total stats
+      time_t _timeLast = 0;    ///< Start last period(~1sec)
+      time_t _timeRcv  = 0;    ///< Start of no-data timeout
+      time_t _timeNow  = 0;    ///< Now
+
+      double _dnlTotal = 0.0;  ///< Bytes to download or 0 if unknown
+      double _dnlLast  = 0.0;  ///< Bytes downloaded at period start
+      double _dnlNow   = 0.0;  ///< Bytes downloaded now
+
+      int    _dnlPercent= 0;   ///< Percent completed or 0 if _dnlTotal is unknown
+
+      double _drateTotal= 0.0; ///< Download rate so far
+      double _drateLast        = 0.0;  ///< Download rate in last period
+
+      void updateStats( double dltotal = 0.0, double dlnow = 0.0 )
+      {
+       time_t now = _timeNow = time(0);
+
+       // If called without args (0.0), recompute based on the last values seen
+       if ( dltotal && dltotal != _dnlTotal )
+         _dnlTotal = dltotal;
+
+       if ( dlnow && dlnow != _dnlNow )
+       {
+         _timeRcv = now;
+         _dnlNow = dlnow;
+       }
+       else if ( !_dnlNow && !_dnlTotal )
+       {
+         // Start time counting as soon as first data arrives.
+         // Skip the connection / redirection time at begin.
+         return;
+       }
+
+       // init or reset if time jumps back
+       if ( !_timeStart || _timeStart > now )
+         _timeStart = _timeLast = _timeRcv = now;
+
+       // timeout condition
+       if ( timeout )
+         reached = ( (now - _timeRcv) > timeout );
+
+       // percentage:
+       if ( _dnlTotal )
+         _dnlPercent = int(_dnlNow * 100 / _dnlTotal);
+
+       // download rates:
+       _drateTotal = _dnlNow / std::max( int(now - _timeStart), 1 );
+
+       if ( _timeLast < now )
+       {
+         _drateLast = (_dnlNow - _dnlLast) / int(now - _timeLast);
+         // start new period
+         _timeLast  = now;
+         _dnlLast   = _dnlNow;
+       }
+       else if ( _timeStart == _timeLast )
+         _drateLast = _drateTotal;
+      }
+
+      int reportProgress() const
+      {
+       if ( reached )
+         return 1;     // no-data timeout
+       if ( report && !(*report)->progress( _dnlPercent, url, _drateTotal, _drateLast ) )
+         return 1;     // user requested abort
+       return 0;
+      }
+
+
       // download rate of the last period (cca 1 sec)
       double                                        drate_period;
       // bytes downloaded at the start of the last period
@@ -189,7 +255,6 @@ namespace zypp {
       double                                        dload;
       // bytes uploaded at the moment the progress was last reported
       double                                        uload;
-      zypp::Url                                     url;
     };
 
     ///////////////////////////////////////////////////////////////////
@@ -1531,97 +1596,33 @@ void MediaCurl::getDirInfo( filesystem::DirContent & retlist,
 }
 
 ///////////////////////////////////////////////////////////////////
+//
+int MediaCurl::aliveCallback( void *clientp, double /*dltotal*/, double dlnow, double /*ultotal*/, double /*ulnow*/ )
+{
+  ProgressData *pdata = reinterpret_cast<ProgressData *>( clientp );
+  if( pdata )
+  {
+    // Do not propagate dltotal in alive callbacks. MultiCurl uses this to
+    // prevent a percentage raise while downloading a metalink file. Download
+    // activity however is indicated by propagating the download rate (via dlnow).
+    pdata->updateStats( 0.0, dlnow );
+    return pdata->reportProgress();
+  }
+  return 0;
+}
 
-int MediaCurl::progressCallback( void *clientp,
-                                 double dltotal, double dlnow,
-                                 double ultotal, double ulnow)
+int MediaCurl::progressCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow )
 {
-  ProgressData *pdata = reinterpret_cast<ProgressData *>(clientp);
-  if( pdata)
+  ProgressData *pdata = reinterpret_cast<ProgressData *>( clientp );
+  if( pdata )
   {
     // work around curl bug that gives us old data
     long httpReturnCode = 0;
-    if (curl_easy_getinfo(pdata->curl, CURLINFO_RESPONSE_CODE, &httpReturnCode) != CURLE_OK || httpReturnCode == 0)
-      return 0;
-
-    time_t now   = time(NULL);
-    if( now > 0)
-    {
-       // reset time of last change in case initial time()
-       // failed or the time was adjusted (goes backward)
-       if( pdata->ltime <= 0 || pdata->ltime > now)
-       {
-         pdata->ltime = now;
-       }
-
-       // start time counting as soon as first data arrives
-       // (skip the connection / redirection time at begin)
-       time_t dif = 0;
-       if (dlnow > 0 || ulnow > 0)
-       {
-         dif = (now - pdata->ltime);
-         dif = dif > 0 ? dif : 0;
-
-         pdata->secs += dif;
-       }
-
-       // update the drate_avg and drate_period only after a second has passed
-       // (this callback is called much more often than a second)
-       // otherwise the values would be far from accurate when measuring
-       // the time in seconds
-       //! \todo more accurate download rate computationn, e.g. compute average value from last 5 seconds, or work with milliseconds instead of seconds
-
-        if ( pdata->secs > 1 && (dif > 0 || dlnow == dltotal ))
-          pdata->drate_avg = (dlnow / pdata->secs);
-
-       if ( dif > 0 )
-       {
-         pdata->drate_period = ((dlnow - pdata->dload_period) / dif);
-         pdata->dload_period = dlnow;
-       }
-    }
-
-    // send progress report first, abort transfer if requested
-    if( pdata->report)
-    {
-      if (!(*(pdata->report))->progress(int( dltotal ? dlnow * 100 / dltotal : 0 ),
-                                       pdata->url,
-                                       pdata->drate_avg,
-                                       pdata->drate_period))
-      {
-        return 1; // abort transfer
-      }
-    }
-
-    // check if we there is a timeout set
-    if( pdata->timeout > 0)
-    {
-      if( now > 0)
-      {
-        bool progress = false;
-
-        // update download data if changed, mark progress
-        if( dlnow != pdata->dload)
-        {
-          progress     = true;
-          pdata->dload = dlnow;
-          pdata->ltime = now;
-        }
-        // update upload data if changed, mark progress
-        if( ulnow != pdata->uload)
-        {
-          progress     = true;
-          pdata->uload = ulnow;
-          pdata->ltime = now;
-        }
+    if ( curl_easy_getinfo( pdata->curl, CURLINFO_RESPONSE_CODE, &httpReturnCode ) != CURLE_OK || httpReturnCode == 0 )
+      return aliveCallback( clientp, dltotal, dlnow, ultotal, ulnow );
 
-        if( !progress && (now >= (pdata->ltime + pdata->timeout)))
-        {
-          pdata->reached = true;
-          return 1; // aborts transfer
-        }
-      }
-    }
+    pdata->updateStats( dltotal, dlnow );
+    return pdata->reportProgress();
   }
   return 0;
 }
index c78c7d9..d7b6100 100644 (file)
@@ -113,9 +113,10 @@ class MediaCurl : public MediaHandler
     };
 
   protected:
-
-    static int progressCallback( void *clientp, double dltotal, double dlnow,
-                                 double ultotal, double ulnow );
+//     /** Callback sending just an alive trigger to the UI, without stats (e.g. during metalink download). */
+    static int aliveCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow );
+    /** Callback reporting download progress. */
+    static int progressCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow );
     static CURL *progressCallback_getcurl( void *clientp );
     /**
      * check the url is supported by the curl library
index 8b2c83b..9f9a65d 100644 (file)
@@ -1236,16 +1236,19 @@ static bool looks_like_metalink(const Pathname & file)
 }
 
 // here we try to suppress all progress coming from a metalink download
+// bsc#1021291: Nevertheless send alive trigger (without stats), so UIs
+// are able to abort a hanging metalink download via callback response.
 int MediaMultiCurl::progressCallback( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
 {
   CURL *_curl = MediaCurl::progressCallback_getcurl(clientp);
   if (!_curl)
-    return 0;
+    return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow);
+
 
   // work around curl bug that gives us old data
   long httpReturnCode = 0;
   if (curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &httpReturnCode ) != CURLE_OK || httpReturnCode == 0)
-    return 0;
+    return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow);
 
   char *ptr = NULL;
   bool ismetalink = false;
@@ -1257,25 +1260,23 @@ int MediaMultiCurl::progressCallback( void *clientp, double dltotal, double dlno
     }    
   if (!ismetalink && dlnow < 256)
     {
-      // can't tell yet, suppress callback
-      return 0;
+      // can't tell yet, ...
+      return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow);
     }
   if (!ismetalink)
     {
       FILE *fp = 0;
-      if (curl_easy_getinfo(_curl, CURLINFO_PRIVATE, &fp) != CURLE_OK)
-       return 0;
-      if (!fp)
-       return 0;       /* hmm */
+      if (curl_easy_getinfo(_curl, CURLINFO_PRIVATE, &fp) != CURLE_OK || !fp)
+       return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow);
       fflush(fp);
       ismetalink = looks_like_metalink_fd(fileno(fp));
       DBG << "looks_like_metalink_fd: " << ismetalink << endl;
     }
   if (ismetalink)
     {
-      // we're downloading the metalink file. no progress please.
-      curl_easy_setopt(_curl, CURLOPT_NOPROGRESS, 1L);
-      return 0;
+      // we're downloading the metalink file. Just trigger aliveCallbacks
+      curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, &MediaCurl::aliveCallback);
+      return MediaCurl::aliveCallback(clientp, dltotal, dlnow, ultotal, ulnow);
     }
   curl_easy_setopt(_curl, CURLOPT_PROGRESSFUNCTION, &MediaCurl::progressCallback);
   return MediaCurl::progressCallback(clientp, dltotal, dlnow, ultotal, ulnow);
index 99908b0..55954b9 100644 (file)
@@ -62,9 +62,9 @@ namespace zypp
   public:
     /** Ctro taking a ProcessResource2 callback */
     Impl(const Pathname &repomd_file, const ProcessResource2 & callback )
-    : _tag( tag_NONE )
+    : _callback( callback )
+    , _tag( tag_NONE )
     , _type( ResourceType::NONE_e )
-    , _callback( callback )
     {
       Reader reader( repomd_file );
       MIL << "Reading " << repomd_file << endl;
index db977e9..6910083 100644 (file)
@@ -21,86 +21,22 @@ using std::endl;
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
-{ /////////////////////////////////////////////////////////////////
+{
   ///////////////////////////////////////////////////////////////////
   namespace repo
-  { /////////////////////////////////////////////////////////////////
+  {
 
-    ///////////////////////////////////////////////////////////////////
-    namespace
-    { /////////////////////////////////////////////////////////////////
-
-      typedef std::string     (SrcPackage::*inlined)() const;
-      typedef OnMediaLocation (SrcPackage::*location)() const;
-
-      /** Provide a SrcPackage in a local file. */
-      ManagedFile doProvideSrcPackage( repo::RepoMediaAccess & access_r,
-                                   const SrcPackage & script_r,
-                                   inlined inlined_r, location location_r )
-      {
-        ManagedFile ret;
-
-        // 1st try inlined
-        std::string inlined( (script_r.*inlined_r)() );
-        if ( ! inlined.empty() )
-        {
-          // Take care the TmpFile goes out of scope BEFORE the
-          // ofstream opens the file again.
-          ret = ManagedFile( filesystem::TmpFile( filesystem::TmpPath::defaultLocation(),
-                                                  "zypp-script-"+script_r.name() ),
-                             filesystem::unlink );
-          std::ofstream str( ret.value().c_str() );
-          str << inlined << endl;
-        }
-        else
-        {
-          // otherwise try download
-          OnMediaLocation location( (script_r.*location_r)() );
-          if ( ! location.filename().empty() )
-          {
-            ret = access_r.provideFile( script_r.repoInfo(), location );
-          }
-          else
-          {
-            // no script
-            return ManagedFile();
-          }
-        }
-
-        // HERE: got the script
-        filesystem::chmod( ret, 0700 );
-        return ret;
-      }
-
-      /////////////////////////////////////////////////////////////////
-    } // namespace
-    ///////////////////////////////////////////////////////////////////
-
-    ///////////////////////////////////////////////////////////////////
-    //
-    // METHOD NAME : SrcPackageProvider::SrcPackageProvider
-    // METHOD TYPE : Ctor
-    //
     SrcPackageProvider::SrcPackageProvider( repo::RepoMediaAccess & access_r )
       : _access( access_r )
     {}
 
-    ///////////////////////////////////////////////////////////////////
-    //
-    // METHOD NAME : SrcPackageProvider::~SrcPackageProvider
-    // METHOD TYPE : Dtor
-    //
     SrcPackageProvider::~SrcPackageProvider()
     {}
 
     ManagedFile SrcPackageProvider::provideSrcPackage( const SrcPackage_constPtr & srcPackage_r ) const
-    {
-      return _access.provideFile( srcPackage_r->repoInfo(), srcPackage_r->location() );
-    }
+    { return _access.provideFile( srcPackage_r->repoInfo(), srcPackage_r->location() ); }
 
-    /////////////////////////////////////////////////////////////////
   } // namespace repo
   ///////////////////////////////////////////////////////////////////
-  /////////////////////////////////////////////////////////////////
 } // namespace zypp
 ///////////////////////////////////////////////////////////////////