#include <map>
#include <algorithm>
+#include <solv/solvversion.h>
+
#include "zypp/base/InputStream.h"
#include "zypp/base/LogTools.h"
#include "zypp/base/Gettext.h"
// Cleanup orphanded service repos:
if ( ! orphanedRepos.empty() )
{
- for ( auto & repoInfo : orphanedRepos )
+ for ( const auto & repoInfo : orphanedRepos )
{
MIL << "Delete orphaned service repo " << repoInfo.alias() << endl;
// translators: Cleanup a repository previously owned by a meanwhile unknown (deleted) service.
assert_alias(info);
try
{
- MIL << "Going to try to check whether refresh is needed for " << url << " (" << info.type() << ")" << endl;
+ MIL << "Going to try to check whether refresh is needed for " << url << endl;
// first check old (cached) metadata
Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
refresh = true;
}
}
- else // includes newstatus.empty() if e.g. repo format changed
+ else
{
MIL << "repo has changed, going to refresh" << endl;
refresh = true;
assert_urls(info);
// we will throw this later if no URL checks out fine
- RepoException rexception( info, _PL("Valid metadata not found at specified URL",
+ RepoException rexception( info, PL_("Valid metadata not found at specified URL",
"Valid metadata not found at specified URLs",
info.baseUrlsSize() ) );
// 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 )
{
- repo::RepoType probed = probe( *it, info.path() );
- if ( repokind != probed )
+ // unknown, probe it
+ repokind = probe( *it, info.path() );
+
+ if (repokind.toEnum() != RepoType::NONE_e)
{
- repokind = probed;
// Adjust the probed type in RepoInfo
info.setProbedType( repokind ); // lazy init!
//save probed type only for repos in system
if ( cache_status == raw_metadata_status )
{
MIL << info.alias() << " cache is up to date with metadata." << endl;
- if ( policy == BuildIfNeeded ) {
- return;
+ if ( policy == BuildIfNeeded )
+ {
+ // On the fly add missing solv.idx files for bash completion.
+ const Pathname & base = solv_path_for_repoinfo( _options, info);
+ if ( ! PathInfo(base/"solv.idx").isExist() )
+ sat::updateSolvFileIndex( base/"solv" );
+
+ return;
}
else {
MIL << info.alias() << " cache rebuild is forced" << endl;
scoped_ptr<MediaMounter> forPlainDirs;
ExternalProgram::Arguments cmd;
- cmd.push_back( PathInfo( "/usr/bin/repo2solv" ).isFile() ? "repo2solv" : "repo2solv.sh" );
+ cmd.push_back( "repo2solv.sh" );
// repo2solv expects -o as 1st arg!
cmd.push_back( "-o" );
cmd.push_back( solvfile.asString() );
cmd.push_back( "-X" ); // autogenerate pattern from pattern-package
- cmd.push_back( "-A" ); // autogenerate application pseudo packages
if ( repokind == RepoType::RPMPLAINDIR )
{
- forPlainDirs.reset( new MediaMounter( info.url() ) );
+ forPlainDirs.reset( new MediaMounter( *info.baseUrlsBegin() ) );
// recusive for plaindir as 2nd arg!
cmd.push_back( "-R" );
// FIXME this does only work form dir: URLs
// We keep it.
guard.resetDispose();
+ sat::updateSolvFileIndex( solvfile ); // content digest for zypper bash completion
}
break;
default:
{
Repository repo = sat::Pool::instance().addRepoSolv( solvfile, info );
// test toolversion in order to rebuild solv file in case
- // it was written by an old libsolv-tool parser.
- //
- // Known version strings used:
- // - <no string>
- // - "1.0"
- //
- sat::LookupRepoAttr toolversion( sat::SolvAttr::repositoryToolVersion, repo );
- if ( toolversion.begin().asString().empty() )
+ // it was written by a different libsolv-tool parser.
+ const std::string & toolversion( sat::LookupRepoAttr( sat::SolvAttr::repositoryToolVersion, repo ).begin().asString() );
+ if ( toolversion != LIBSOLV_TOOLVERSION )
{
repo.eraseFromPool();
- ZYPP_THROW(Exception("Solv-file was created by old parser."));
+ ZYPP_THROW(Exception(str::Str() << "Solv-file was created by '"<<toolversion<<"'-parser (want "<<LIBSOLV_TOOLVERSION<<")."));
}
- // else: up-to-date (or even newer).
}
catch ( const Exception & exp )
{
if ( _options.probe )
{
DBG << "unknown repository type, probing" << endl;
- assert_urls(tosave);
- RepoType probedtype( probe( tosave.url(), info.path() ) );
- if ( probedtype == RepoType::NONE )
- ZYPP_THROW(RepoUnknownTypeException(info));
- else
- tosave.setType(probedtype);
+ RepoType probedtype;
+ probedtype = probe( *tosave.baseUrlsBegin(), info.path() );
+ if ( tosave.baseUrlsSize() > 0 )
+ {
+ if ( probedtype == RepoType::NONE )
+ ZYPP_THROW(RepoUnknownTypeException(info));
+ else
+ tosave.setType(probedtype);
+ }
}
progress.set(50);
newinfo.dumpAsIniOn(file);
}
+ if ( toedit.enabled() && !newinfo.enabled() )
+ {
+ // On the fly remove solv.idx files for bash completion if a repo gets disabled.
+ const Pathname & solvidx = solv_path_for_repoinfo(_options, newinfo)/"solv.idx";
+ if ( PathInfo(solvidx).isExist() )
+ filesystem::unlink( solvidx );
+ }
+
newinfo.setFilepath(toedit.filepath());
reposManip().erase(toedit);
reposManip().insert(newinfo);
ServiceInfo service( getService( alias ) );
assert_alias( service );
assert_url( service );
+ MIL << "Going to refresh service '" << service.alias() << "', url: " << service.url() << ", opts: " << options_r << endl;
+
+ if ( service.ttl() && !( options_r.testFlag( RefreshService_forceRefresh) || options_r.testFlag( RefreshService_restoreStatus ) ) )
+ {
+ // Service defines a TTL; maybe we can re-use existing data without refresh.
+ Date lrf = service.lrf();
+ if ( lrf )
+ {
+ Date now( Date::now() );
+ if ( lrf <= now )
+ {
+ if ( (lrf+=service.ttl()) > now ) // lrf+= !
+ {
+ MIL << "Skip: '" << service.alias() << "' metadata valid until " << lrf << endl;
+ return;
+ }
+ }
+ else
+ WAR << "Force: '" << service.alias() << "' metadata last refresh in the future: " << lrf << endl;
+ }
+ }
+
// NOTE: It might be necessary to modify and rewrite the service info.
// Either when probing the type, or when adjusting the repositories
// enable/disable state.:
bool serviceModified = false;
- MIL << "Going to refresh service '" << service.alias() << "', url: "<< service.url() << ", opts: " << options_r << endl;
- //! \todo add callbacks for apps (start, end, repo removed, repo added, repo changed)
+ //! \todo add callbacks for apps (start, end, repo removed, repo added, repo changed)?
// if the type is unknown, try probing.
if ( service.type() == repo::ServiceType::NONE )
DBG << "ServicesTargetDistro: " << servicesTargetDistro << endl;
// parse it
+ Date::Duration origTtl = service.ttl(); // FIXME Ugly hack: const service.ttl modified when parsing
RepoCollector collector(servicesTargetDistro);
// FIXME Ugly hack: ServiceRepos may throw ServicePluginInformalException
// which is actually a notification. Using an exception for this
// and in zypper.
std::pair<DefaultIntegral<bool,false>, repo::ServicePluginInformalException> uglyHack;
try {
- ServiceRepos repos(service, bind( &RepoCollector::collect, &collector, _1 ));
+ ServiceRepos( service, bind( &RepoCollector::collect, &collector, _1 ) );
}
catch ( const repo::ServicePluginInformalException & e )
{
uglyHack.first = true;
uglyHack.second = e;
}
-
+ if ( service.ttl() != origTtl ) // repoindex.xml changed ttl
+ {
+ if ( !service.ttl() )
+ service.setLrf( Date() ); // don't need lrf when zero ttl
+ serviceModified = true;
+ }
////////////////////////////////////////////////////////////////////////////
// On the fly remember the new repo states as defined the reopoindex.xml.
// Move into ServiceInfo later.
////////////////////////////////////////////////////////////////////////////
// save service if modified: (unless a plugin service)
- if ( serviceModified && service.type() != ServiceType::PLUGIN )
+ if ( service.type() != ServiceType::PLUGIN )
{
- // write out modified service file.
- modifyService( service.alias(), service );
+ if ( service.ttl() )
+ {
+ service.setLrf( Date::now() ); // remember last refresh
+ serviceModified = true; // or use a cookie file
+ }
+
+ if ( serviceModified )
+ {
+ // write out modified service file.
+ modifyService( service.alias(), service );
+ }
}
if ( uglyHack.first )