From 6e08c82c840eba3bf48dd9da2ed5889942c36c54 Mon Sep 17 00:00:00 2001 From: Jan Kupec Date: Wed, 15 Aug 2007 07:15:44 +0000 Subject: [PATCH] - decision to do refresh moved to a public checkIfToRefreshMetadata() method - create progress data for build cache only when it actually is going to build, not before. --- zypp/RepoManager.cc | 185 +++++++++++++++++++++++++++++++++++----------------- zypp/RepoManager.h | 56 +++++++++++++++- 2 files changed, 179 insertions(+), 62 deletions(-) diff --git a/zypp/RepoManager.cc b/zypp/RepoManager.cc index 25cbbe8..1fcd695 100644 --- a/zypp/RepoManager.cc +++ b/zypp/RepoManager.cc @@ -347,6 +347,105 @@ namespace zypp return status; } + bool RepoManager::checkIfToRefreshMetadata( const RepoInfo &info, + const Url &url, + RawMetadataRefreshPolicy policy ) + { + assert_alias(info); + + RepoStatus oldstatus; + RepoStatus newstatus; + + try + { + MIL << "Going to try to check whether refresh is needed for " << url << endl; + + repo::RepoType repokind = info.type(); + + // if the type is unknown, try probing. + switch ( repokind.toEnum() ) + { + case RepoType::NONE_e: + // unknown, probe it + repokind = probe(url); + break; + default: + break; + } + + Pathname rawpath = rawcache_path_for_repoinfo( _pimpl->options, info ); + filesystem::assert_dir(rawpath); + oldstatus = metadataStatus(info); + + // create temp dir as sibling of rawpath + filesystem::TmpDir tmpdir( filesystem::TmpDir::makeSibling( rawpath ) ); + + if ( ( repokind.toEnum() == RepoType::RPMMD_e ) || + ( repokind.toEnum() == RepoType::YAST2_e ) ) + { + MediaSetAccess media(url); + shared_ptr downloader_ptr; + + if ( repokind.toEnum() == RepoType::RPMMD_e ) + downloader_ptr.reset(new yum::Downloader(info.path())); + else + downloader_ptr.reset( new susetags::Downloader(info.path())); + + RepoStatus newstatus = downloader_ptr->status(media); + bool refresh = false; + if ( oldstatus.checksum() == newstatus.checksum() ) + { + MIL << "repo has not changed" << endl; + if ( policy == RefreshForced ) + { + MIL << "refresh set to forced" << endl; + refresh = true; + } + } + else + { + MIL << "repo has changed, going to refresh" << endl; + refresh = true; + } + + return refresh; + } + else if ( repokind.toEnum() == RepoType::RPMPLAINDIR_e ) + { + RepoStatus newstatus = parser::plaindir::dirStatus(url.getPathName()); + bool refresh = false; + if ( oldstatus.checksum() == newstatus.checksum() ) + { + MIL << "repo has not changed" << endl; + if ( policy == RefreshForced ) + { + MIL << "refresh set to forced" << endl; + refresh = true; + } + } + else + { + MIL << "repo has changed, going to refresh" << endl; + refresh = true; + } + + return refresh; + } + else + { + ZYPP_THROW(RepoUnknownTypeException()); + } + } + catch ( const Exception &e ) + { + ZYPP_CAUGHT(e); + ERR << "refresh check failed for " << url << endl; + ZYPP_RETHROW(e); + } + + return true; // default + } + void RepoManager::refreshMetadata( const RepoInfo &info, RawMetadataRefreshPolicy policy, const ProgressData::ReceiverFnc & progress ) @@ -354,8 +453,6 @@ namespace zypp assert_alias(info); assert_urls(info); - RepoStatus oldstatus; - RepoStatus newstatus; // try urls one by one for ( RepoInfo::urls_const_iterator it = info.baseUrlsBegin(); it != info.baseUrlsEnd(); ++it ) { @@ -363,7 +460,12 @@ namespace zypp { Url url(*it); - MIL << "Going to try to check and refresh metadata from " << url << endl; + // check whether to refresh metadata + // if the check fails for this url, it throws, so another url will be checked + if (!checkIfToRefreshMetadata(info, url, policy)) + return; + + MIL << "Going to refresh metadata from " << url << endl; repo::RepoType repokind = info.type(); @@ -380,7 +482,6 @@ namespace zypp Pathname rawpath = rawcache_path_for_repoinfo( _pimpl->options, info ); filesystem::assert_dir(rawpath); - oldstatus = metadataStatus(info); // create temp dir as sibling of rawpath filesystem::TmpDir tmpdir( filesystem::TmpDir::makeSibling( rawpath ) ); @@ -410,61 +511,20 @@ namespace zypp downloader_ptr->addCachePath(rawcache_path_for_repoinfo( _pimpl->options, *it )); } - RepoStatus newstatus = downloader_ptr->status(media); - bool refresh = false; - if ( oldstatus.checksum() == newstatus.checksum() ) - { - MIL << "repo has not changed" << endl; - if ( policy == RefreshForced ) - { - MIL << "refresh set to forced" << endl; - refresh = true; - } - } - else - { - MIL << "repo has changed, going to refresh" << endl; - refresh = true; - } - if ( refresh ) - downloader_ptr->download( media, tmpdir.path()); - else - return; - // no error + downloader_ptr->download( media, tmpdir.path()); } else if ( repokind.toEnum() == RepoType::RPMPLAINDIR_e ) { RepoStatus newstatus = parser::plaindir::dirStatus(url.getPathName()); - bool refresh = false; - if ( oldstatus.checksum() == newstatus.checksum() ) - { - MIL << "repo has not changed" << endl; - if ( policy == RefreshForced ) - { - MIL << "refresh set to forced" << endl; - refresh = true; - } - } - else - { - MIL << "repo has changed, going to refresh" << endl; - refresh = true; - } - if ( refresh ) - { - std::ofstream file(( tmpdir.path() + "/cookie").c_str()); - if (!file) { - ZYPP_THROW (Exception( "Can't open " + tmpdir.path().asString() + "/cookie" ) ); - } - file << url << endl; - file << newstatus.checksum() << endl; - - file.close(); + std::ofstream file(( tmpdir.path() + "/cookie").c_str()); + if (!file) { + ZYPP_THROW (Exception( "Can't open " + tmpdir.path().asString() + "/cookie" ) ); } - else - return; - // no error + file << url << endl; + file << newstatus.checksum() << endl; + + file.close(); } else { @@ -502,12 +562,6 @@ namespace zypp CacheBuildPolicy policy, const ProgressData::ReceiverFnc & progressrcv ) { - ProgressData progress(100); - callback::SendReport report; - progress.sendTo( ProgressReportAdaptor( progressrcv, report ) ); - progress.name(str::form(_("Building repository '%s' cache"), info.name().c_str())); - progress.toMin(); - assert_alias(info); Pathname rawpath = rawcache_path_for_repoinfo(_pimpl->options, info); @@ -519,6 +573,7 @@ namespace zypp ZYPP_THROW(RepoMetadataException(info)); } + bool needs_cleaning = false; if ( store.isCached( info.alias() ) ) { MIL << info.alias() << " is already cached." << endl; @@ -529,7 +584,6 @@ namespace zypp { MIL << info.alias() << " cache is up to date with metadata." << endl; if ( policy == BuildIfNeeded ) { - progress.toMax(); return; } else { @@ -537,9 +591,18 @@ namespace zypp } } - cleanCacheInternal( store, info); + needs_cleaning = true; } + ProgressData progress(100); + callback::SendReport report; + progress.sendTo( ProgressReportAdaptor( progressrcv, report ) ); + progress.name(str::form(_("Building repository '%s' cache"), info.name().c_str())); + progress.toMin(); + + if (needs_cleaning) + cleanCacheInternal( store, info); + MIL << info.alias() << " building cache..." << endl; data::RecordId id = store.lookupOrAppendRepository(info.alias()); // do we have type? diff --git a/zypp/RepoManager.h b/zypp/RepoManager.h index ab1dfcf..e05763b 100644 --- a/zypp/RepoManager.h +++ b/zypp/RepoManager.h @@ -106,6 +106,61 @@ namespace zypp */ RepoStatus metadataStatus( const RepoInfo &info ) const; + /** + * Checks whether to refresh metadata for specified repository and url. + *

+ * The need for refresh is evaluated according to the following conditions, + * in that order: + *

    + *
  • the refresh policy (refresh may be forced) + *
  • the repo.refresh.delay ZConfig value compared to the difference between + * cached index file timestamp and actual time + *
  • the timestamp of cached repo index file compared to the remote + * index file timestamp. + *
+ *

+ * This method checks the status against the specified url only. If more + * baseurls are defined for in the RepoInfo, each one must be check + * individually. Example: + * + * + * + * RepoInfo info; + * // try urls one by one + * for ( RepoInfo::urls_const_iterator it = info.baseUrlsBegin(); + * it != info.baseUrlsEnd(); ++it ) + * { + * try + * { + * // check whether to refresh metadata + * // if the check fails for this url, it throws, so another url will be checked + * if (!checkIfToRefreshMetadata(info, *it, policy)) + * return; + * + * // do the actual refresh + * } + * catch (const Exception & e) + * { + * ZYPP_CAUGHT(e); + * ERR << *it << " doesn't look good. Trying another url." << endl; + * } + * } // for all urls + * + * handle("No more URLs."); + * + * + * + * \param info + * \param url + * \param policy + * \throws RepoUnknownTypeException + * \throws repo::RepoNoAliasException if can't figure an alias + * \throws Exception on unknown error + * + */ + bool checkIfToRefreshMetadata( const RepoInfo &info, + const Url &url, + RawMetadataRefreshPolicy policy ); /** * \short Refresh local raw cache * @@ -119,7 +174,6 @@ namespace zypp * \throws repo::RepoUnknownTypeException if the metadata is unknown * \throws repo::RepoException if the repository is invalid * (no valid metadata found at any of baseurls) - * \throws Exception on unknown error. */ void refreshMetadata( const RepoInfo &info, RawMetadataRefreshPolicy policy = RefreshIfNeeded, -- 2.7.4