///////////////////////////////////////////////////////////////////
namespace zypp
{
+
+ ///////////////////////////////////////////////////////////////////
+ namespace env
+ {
+ /** To trigger appdata refresh unconditionally */
+ inline bool ZYPP_PLUGIN_APPDATA_FORCE_COLLECT()
+ {
+ const char * env = getenv("ZYPP_PLUGIN_APPDATA_FORCE_COLLECT");
+ return( env && str::strToBool( env, true ) );
+ }
+ } // namespace env
+ ///////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////
namespace
{
////////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace
+ {
+ /** Whether repo is not under RM control and provides it's own methadata paths. */
+ inline bool isTmpRepo( const RepoInfo & info_r )
+ { return( info_r.filepath().empty() && info_r.usesAutoMethadataPaths() ); }
+ } // namespace
+ ///////////////////////////////////////////////////////////////////
+
/**
* \short Calculates the raw cache path for a repository, this is usually
* /var/cache/zypp/alias
inline Pathname rawcache_path_for_repoinfo( const RepoManagerOptions &opt, const RepoInfo &info )
{
assert_alias(info);
- return opt.repoRawCachePath / info.escaped_alias();
+ return isTmpRepo( info ) ? info.metadataPath() : opt.repoRawCachePath / info.escaped_alias();
}
/**
* for example /var/cache/zypp/alias/addondir
*/
inline Pathname rawproductdata_path_for_repoinfo( const RepoManagerOptions &opt, const RepoInfo &info )
- {
- assert_alias(info);
- return opt.repoRawCachePath / info.escaped_alias() / info.path();
- }
+ { return rawcache_path_for_repoinfo( opt, info ) / info.path(); }
/**
* \short Calculates the packages cache path for a repository
inline Pathname packagescache_path_for_repoinfo( const RepoManagerOptions &opt, const RepoInfo &info )
{
assert_alias(info);
- return opt.repoPackagesCachePath / info.escaped_alias();
+ return isTmpRepo( info ) ? info.packagesPath() : opt.repoPackagesCachePath / info.escaped_alias();
}
/**
* \short Calculates the solv cache path for a repository
*/
- inline Pathname solv_path_for_repoinfo( const RepoManagerOptions &opt, const RepoInfo &info)
+ inline Pathname solv_path_for_repoinfo( const RepoManagerOptions &opt, const RepoInfo &info )
{
assert_alias(info);
- return opt.repoSolvCachePath / info.escaped_alias();
+ return isTmpRepo( info ) ? info.metadataPath().dirname() / "%SLV%" : opt.repoSolvCachePath / info.escaped_alias();
}
////////////////////////////////////////////////////////////////////////////
~Impl()
{
// trigger appdata refresh if some repos change
- if ( _reposDirty && geteuid() == 0 && ( _options.rootDir.empty() || _options.rootDir == "/" ) )
+ if ( ( _reposDirty || env::ZYPP_PLUGIN_APPDATA_FORCE_COLLECT() )
+ && geteuid() == 0 && ( _options.rootDir.empty() || _options.rootDir == "/" ) )
{
try {
std::list<Pathname> entries;
switch ( repokind.toEnum() )
{
case RepoType::RPMMD_e :
- status = RepoStatus( productdatapath/"repodata/repomd.xml");
+ status = RepoStatus( productdatapath/"repodata/repomd.xml") && RepoStatus( mediarootpath/"media.1/media" );
break;
case RepoType::YAST2_e :
assert_alias(info);
try
{
- MIL << "Going to try to check whether refresh is needed for " << url << endl;
+ MIL << "Going to try to check whether refresh is needed for " << url << " (" << info.type() << ")" << endl;
// first check old (cached) metadata
Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
filesystem::assert_dir( mediarootpath );
RepoStatus oldstatus = metadataStatus( info );
-
if ( oldstatus.empty() )
{
MIL << "No cached metadata, going to refresh" << endl;
return REFRESH_NEEDED;
}
+ if ( url.schemeIsVolatile() )
{
- if ( url.schemeIsVolatile() )
- {
- MIL << "never refresh CD/DVD" << endl;
- return REPO_UP_TO_DATE;
- }
- if ( url.schemeIsLocal() )
- {
- policy = RefreshIfNeededIgnoreDelay;
- }
+ MIL << "Never refresh CD/DVD" << endl;
+ return REPO_UP_TO_DATE;
+ }
+
+ if ( policy == RefreshForced )
+ {
+ MIL << "Forced refresh!" << endl;
+ return REFRESH_NEEDED;
+ }
+
+ if ( url.schemeIsLocal() )
+ {
+ policy = RefreshIfNeededIgnoreDelay;
}
// now we've got the old (cached) status, we can decide repo.refresh.delay
- if (policy != RefreshForced && policy != RefreshIfNeededIgnoreDelay)
+ if ( policy != RefreshIfNeededIgnoreDelay )
{
// difference in seconds
double diff = difftime(
}
// check status
- bool refresh = false;
if ( oldstatus == newstatus )
{
MIL << "repo has not changed" << endl;
- if ( policy == RefreshForced )
- {
- MIL << "refresh set to forced" << endl;
- refresh = true;
- }
+ touchIndexFile( info );
+ return REPO_UP_TO_DATE;
}
- else
+ else // includes newstatus.empty() if e.g. repo format changed
{
MIL << "repo has changed, going to refresh" << endl;
- refresh = true;
+ return REFRESH_NEEDED;
}
-
- if (!refresh)
- touchIndexFile(info);
-
- return refresh ? REFRESH_NEEDED : REPO_UP_TO_DATE;
-
}
catch ( const Exception &e )
{
// Suppress (interactive) media::MediaChangeReport if we in have multiple basurls (>1)
media::ScopedDisableMediaChangeReport guard( info.baseUrlsSize() > 1 );
-
// try urls one by one
for ( RepoInfo::urls_const_iterator it = info.baseUrlsBegin(); it != info.baseUrlsEnd(); ++it )
{
MIL << "Going to refresh metadata from " << url << endl;
+ // bsc#1048315: Always re-probe in case of repo format change.
+ // TODO: Would be sufficient to verify the type and re-probe
+ // if verification failed (or type is RepoType::NONE)
repo::RepoType repokind = info.type();
-
- // if the type is unknown, try probing.
- if ( repokind == RepoType::NONE )
{
- // unknown, probe it
- repokind = probe( *it, info.path() );
-
- if (repokind.toEnum() != RepoType::NONE_e)
+ repo::RepoType probed = probe( *it, info.path() );
+ if ( repokind != probed )
{
+ repokind = probed;
// Adjust the probed type in RepoInfo
info.setProbedType( repokind ); // lazy init!
//save probed type only for repos in system
// ok we have the metadata, now exchange
// the contents
filesystem::exchange( tmpdir.path(), mediarootpath );
- reposManip(); // remember to trigger appdata refresh
+ if ( ! isTmpRepo( info ) )
+ reposManip(); // remember to trigger appdata refresh
// we are done.
return;
if ( repokind == RepoType::RPMPLAINDIR )
{
- forPlainDirs.reset( new MediaMounter( *info.baseUrlsBegin() ) );
+ forPlainDirs.reset( new MediaMounter( info.url() ) );
// recusive for plaindir as 2nd arg!
cmd.push_back( "-R" );
// FIXME this does only work form dir: URLs
if ( _options.probe )
{
DBG << "unknown repository type, probing" << endl;
+ assert_urls(tosave);
- RepoType probedtype;
- probedtype = probe( *tosave.baseUrlsBegin(), info.path() );
- if ( tosave.baseUrlsSize() > 0 )
- {
- if ( probedtype == RepoType::NONE )
- ZYPP_THROW(RepoUnknownTypeException(info));
- else
- tosave.setType(probedtype);
- }
+ RepoType probedtype( probe( tosave.url(), info.path() ) );
+ if ( probedtype == RepoType::NONE )
+ ZYPP_THROW(RepoUnknownTypeException(info));
+ else
+ tosave.setType(probedtype);
}
progress.set(50);
tosave.dumpAsIniOn(file);
tosave.setFilepath(repofile);
- tosave.setMetadataPath( metadataPath( tosave ) );
- tosave.setPackagesPath( packagesPath( tosave ) );
+ tosave.setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ) );
+ tosave.setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ) );
{
- // We chould fix the API as we must injet those paths
+ // We should fix the API as we must inject those paths
// into the repoinfo in order to keep it usable.
RepoInfo & oinfo( const_cast<RepoInfo &>(info) );
- oinfo.setMetadataPath( metadataPath( tosave ) );
- oinfo.setPackagesPath( packagesPath( tosave ) );
+ oinfo.setFilepath(repofile);
+ oinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ) );
+ oinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ) );
}
reposManip().insert(tosave);
++it )
{
MIL << "Saving " << (*it).alias() << endl;
- it->setFilepath(repofile.asString());
it->dumpAsIniOn(file);
+ it->setFilepath(repofile);
+ it->setMetadataPath( rawcache_path_for_repoinfo( _options, *it ) );
+ it->setPackagesPath( packagescache_path_for_repoinfo( _options, *it ) );
reposManip().insert(*it);
HistoryLog(_options.rootDir).addRepository(*it);
}
newinfo.setFilepath(toedit.filepath());
+ newinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, newinfo ) );
+ newinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, newinfo ) );
+ {
+ // We should fix the API as we must inject those paths
+ // into the repoinfo in order to keep it usable.
+ RepoInfo & oinfo( const_cast<RepoInfo &>(newinfo_r) );
+ oinfo.setFilepath(toedit.filepath());
+ oinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, newinfo ) );
+ oinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, newinfo ) );
+ }
reposManip().erase(toedit);
reposManip().insert(newinfo);
// check for credentials in Urls