22 #include <solv/solvversion.h> 24 #include <zypp-core/base/InputStream> 25 #include <zypp/base/LogTools.h> 26 #include <zypp/base/Gettext.h> 27 #include <zypp-core/base/DefaultIntegral> 28 #include <zypp/base/Function.h> 29 #include <zypp/base/Regex.h> 30 #include <zypp/PathInfo.h> 31 #include <zypp/TmpPath.h> 38 #include <zypp-media/auth/CredentialManager> 39 #include <zypp-media/MediaException> 41 #include <zypp/ExternalProgram.h> 42 #include <zypp/ManagedFile.h> 48 #include <zypp/repo/yum/Downloader.h> 49 #include <zypp/repo/susetags/Downloader.h> 66 #define OPT_PROGRESS const ProgressData::ReceiverFnc & = ProgressData::ReceiverFnc() 71 namespace zypp_readonly_hack {
81 const char * env = getenv(
"ZYPP_PLUGIN_APPDATA_FORCE_COLLECT");
111 class UrlCredentialExtractor
114 UrlCredentialExtractor( Pathname & root_r )
118 ~UrlCredentialExtractor()
122 bool collect(
const Url & url_r )
124 bool ret = url_r.hasCredentialsInAuthority();
128 _cmPtr->addUserCred( url_r );
133 template<
class TContainer>
134 bool collect(
const TContainer & urls_r )
135 {
bool ret =
false;
for (
const Url & url : urls_r ) {
if ( collect( url ) && !ret ) ret =
true; }
return ret; }
138 bool extract( Url & url_r )
140 bool ret = collect( url_r );
142 url_r.setPassword( std::string() );
146 template<
class TContainer>
147 bool extract( TContainer & urls_r )
148 {
bool ret =
false;
for ( Url & url : urls_r ) {
if ( extract( url ) && !ret ) ret =
true; }
return ret; }
152 scoped_ptr<media::CredentialManager>
_cmPtr;
167 MediaMounter(
const Url & url_r )
169 media::MediaManager mediamanager;
170 _mid = mediamanager.open( url_r );
171 mediamanager.attach(
_mid );
177 media::MediaManager mediamanager;
178 mediamanager.release(
_mid );
179 mediamanager.close(
_mid );
186 Pathname getPathName(
const Pathname & path_r = Pathname() )
const 188 media::MediaManager mediamanager;
189 return mediamanager.localPath(
_mid, path_r );
198 template <
class Iterator>
199 inline bool foundAliasIn(
const std::string & alias_r, Iterator begin_r, Iterator end_r )
201 for_( it, begin_r, end_r )
202 if ( it->alias() == alias_r )
207 template <
class Container>
208 inline bool foundAliasIn(
const std::string & alias_r,
const Container & cont_r )
209 {
return foundAliasIn( alias_r, cont_r.begin(), cont_r.end() ); }
212 template <
class Iterator>
213 inline Iterator findAlias(
const std::string & alias_r, Iterator begin_r, Iterator end_r )
215 for_( it, begin_r, end_r )
216 if ( it->alias() == alias_r )
221 template <
class Container>
222 inline typename Container::iterator findAlias(
const std::string & alias_r, Container & cont_r )
223 {
return findAlias( alias_r, cont_r.begin(), cont_r.end() ); }
225 template <
class Container>
226 inline typename Container::const_iterator findAlias(
const std::string & alias_r,
const Container & cont_r )
227 {
return findAlias( alias_r, cont_r.begin(), cont_r.end() ); }
231 inline std::string filenameFromAlias(
const std::string & alias_r,
const std::string & stem_r )
233 std::string filename( alias_r );
237 filename = Pathname(filename).extend(
"."+stem_r).asString();
238 MIL <<
"generating filename for " << stem_r <<
" [" << alias_r <<
"] : '" << filename <<
"'" << endl;
262 RepoCollector(
const std::string & targetDistro_)
266 bool collect(
const RepoInfo &repo )
270 && !repo.targetDistribution().empty()
274 <<
"Skipping repository meant for '" << repo.targetDistribution()
275 <<
"' distribution (current distro is '" 281 repos.push_back(repo);
295 std::list<RepoInfo> repositories_in_file(
const Pathname & file )
297 MIL <<
"repo file: " << file << endl;
298 RepoCollector collector;
299 parser::RepoFileReader parser( file, bind( &RepoCollector::collect, &collector, _1 ) );
300 return std::move(collector.repos);
313 std::list<RepoInfo> repositories_in_dir(
const Pathname &dir )
315 MIL <<
"directory " << dir << endl;
316 std::list<RepoInfo>
repos;
317 bool nonroot( geteuid() != 0 );
318 if ( nonroot && ! PathInfo(dir).userMayRX() )
320 JobReport::warning( str::Format(
_(
"Cannot read repo directory '%1%': Permission denied")) % dir );
324 std::list<Pathname> entries;
331 str::regex allowedRepoExt(
"^\\.repo(_[0-9]+)?$");
332 for ( std::list<Pathname>::const_iterator it = entries.begin(); it != entries.end(); ++it )
336 if ( nonroot && ! PathInfo(*it).userMayR() )
338 JobReport::warning( str::Format(
_(
"Cannot read repo file '%1%': Permission denied")) % *it );
342 const std::list<RepoInfo> & tmp( repositories_in_file( *it ) );
343 repos.insert(
repos.end(), tmp.begin(), tmp.end() );
353 inline void assert_alias(
const RepoInfo & info )
355 if ( info.alias().empty() )
359 if ( info.alias()[0] ==
'.')
361 info,
_(
"Repository alias cannot start with dot.")));
364 inline void assert_alias(
const ServiceInfo & info )
366 if ( info.alias().empty() )
370 if ( info.alias()[0] ==
'.')
372 info,
_(
"Service alias cannot start with dot.")));
377 inline void assert_urls(
const RepoInfo & info )
379 if ( info.baseUrlsEmpty() )
383 inline void assert_url(
const ServiceInfo & info )
385 if ( ! info.url().isValid() )
395 inline bool isTmpRepo(
const RepoInfo & info_r )
396 {
return( info_r.filepath().empty() && info_r.usesAutoMethadataPaths() ); }
404 inline Pathname rawcache_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
407 return isTmpRepo( info ) ? info.metadataPath() : opt.repoRawCachePath / info.escaped_alias();
418 inline Pathname rawproductdata_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
419 {
return rawcache_path_for_repoinfo( opt, info ) / info.path(); }
424 inline Pathname packagescache_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
427 return isTmpRepo( info ) ? info.packagesPath() : opt.repoPackagesCachePath / info.escaped_alias();
433 inline Pathname solv_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
436 return isTmpRepo( info ) ? info.metadataPath().dirname() /
"%SLV%" : opt.repoSolvCachePath / info.escaped_alias();
442 class ServiceCollector
445 typedef std::set<ServiceInfo> ServiceSet;
447 ServiceCollector( ServiceSet & services_r )
451 bool operator()(
const ServiceInfo & service_r )
const 463 inline bool autoPruneInDir(
const Pathname & path_r )
464 {
return not PathInfo(path_r/
".no_auto_prune").isExist(); }
472 Url repoFileUrl { replaceVars(repo_file) };
475 DBG <<
"reading repo file " << repoFileUrl <<
", local path: " << local << endl;
477 return repositories_in_file(local);
516 #define OUTS(X) str << " " #X "\t" << obj.X << endl 517 str <<
"RepoManagerOptions (" << obj.
rootDir <<
") {" << endl;
518 OUTS( repoRawCachePath );
519 OUTS( repoSolvCachePath );
520 OUTS( repoPackagesCachePath );
521 OUTS( knownReposPath );
522 OUTS( knownServicesPath );
539 , _pluginRepoverification( _options.pluginsPath/
"repoverification", _options.rootDir )
541 init_knownServices();
542 init_knownRepositories();
549 && geteuid() == 0 && ( _options.rootDir.empty() || _options.rootDir ==
"/" ) )
552 std::list<Pathname> entries;
554 if ( ! entries.empty() )
557 cmd.push_back(
"<" );
558 cmd.push_back(
">" );
559 cmd.push_back(
"PROGRAM" );
560 for (
const auto & rinfo :
repos() )
562 if ( ! rinfo.enabled() )
564 cmd.push_back(
"-R" );
565 cmd.push_back( rinfo.alias() );
566 cmd.push_back(
"-t" );
567 cmd.push_back( rinfo.type().asString() );
568 cmd.push_back(
"-p" );
569 cmd.push_back( (rinfo.metadataPath()/rinfo.path()).
asString() );
572 for_( it, entries.begin(), entries.end() )
595 bool hasRepo(
const std::string & alias )
const 596 {
return foundAliasIn( alias,
repos() ); }
606 {
return rawcache_path_for_repoinfo( _options, info ); }
609 {
return packagescache_path_for_repoinfo( _options, info ); }
613 RefreshCheckStatus checkIfToRefreshMetadata(
const RepoInfo & info,
const Url & url, RawMetadataRefreshPolicy policy );
631 {
return PathInfo(solv_path_for_repoinfo( _options, info ) /
"solv").
isExist(); }
656 {
return foundAliasIn( alias,
_services ); }
669 void removeService(
const std::string & alias );
671 { removeService( service.
alias() ); }
673 void refreshServices(
const RefreshServiceOptions & options_r );
675 void refreshService(
const std::string & alias,
const RefreshServiceOptions & options_r );
677 { refreshService( service.
alias(), options_r ); }
679 void modifyService(
const std::string & oldAlias,
const ServiceInfo & newService );
688 Pathname generateNonExistingName(
const Pathname & dir,
const std::string & basefilename )
const;
691 {
return filenameFromAlias( info.
alias(),
"repo" ); }
694 {
return filenameFromAlias( info.
alias(),
"service" ); }
698 Pathname base = solv_path_for_repoinfo( _options, info );
703 void touchIndexFile(
const RepoInfo & info );
705 template<
typename OutputIterator>
710 boost::make_filter_iterator( filter,
repos().end(),
repos().end() ),
715 void init_knownServices();
716 void init_knownRepositories();
731 friend Impl * rwcowClone<Impl>(
const Impl * rhs );
734 {
return new Impl( *
this ); }
740 {
return str <<
"RepoManager::Impl"; }
744 void RepoManager::Impl::saveService( ServiceInfo & service )
const 747 Pathname servfile = generateNonExistingName( _options.knownServicesPath,
748 generateFilename( service ) );
749 service.setFilepath( servfile );
751 MIL <<
"saving service in " << servfile << endl;
753 std::ofstream file( servfile.c_str() );
759 service.dumpAsIniOn( file );
760 MIL <<
"done" << endl;
778 Pathname RepoManager::Impl::generateNonExistingName(
const Pathname & dir,
779 const std::string & basefilename )
const 781 std::string final_filename = basefilename;
783 while ( PathInfo(dir + final_filename).isExist() )
788 return dir + Pathname(final_filename);
793 void RepoManager::Impl::init_knownServices()
795 Pathname dir = _options.knownServicesPath;
796 std::list<Pathname> entries;
797 if (PathInfo(dir).isExist())
806 for_(it, entries.begin(), entries.end() )
808 parser::ServiceFileReader(*it, ServiceCollector(
_services));
812 repo::PluginServices(_options.pluginsPath/
"services", ServiceCollector(
_services));
823 inline void cleanupNonRepoMetadtaFolders(
const Pathname & cachePath_r,
824 const Pathname & defaultCachePath_r,
825 const std::list<std::string> & repoEscAliases_r )
830 if ( cachePath_r != defaultCachePath_r )
833 std::list<std::string> entries;
837 std::set<std::string> oldfiles;
838 set_difference( entries.begin(), entries.end(), repoEscAliases_r.begin(), repoEscAliases_r.end(),
839 std::inserter( oldfiles, oldfiles.end() ) );
845 for (
const std::string & old : oldfiles )
849 pi( cachePath_r/old );
859 void RepoManager::Impl::init_knownRepositories()
861 MIL <<
"start construct known repos" << endl;
863 if ( PathInfo(_options.knownReposPath).isExist() )
865 std::list<std::string> repoEscAliases;
866 std::list<RepoInfo> orphanedRepos;
867 for ( RepoInfo & repoInfo : repositories_in_dir(_options.knownReposPath) )
870 repoInfo.setMetadataPath( rawcache_path_for_repoinfo(_options, repoInfo) );
872 repoInfo.setPackagesPath( packagescache_path_for_repoinfo(_options, repoInfo) );
874 _reposX.insert( repoInfo );
877 const std::string & serviceAlias( repoInfo.service() );
878 if ( ! ( serviceAlias.empty() || hasService( serviceAlias ) ) )
880 WAR <<
"Schedule orphaned service repo for deletion: " << repoInfo << endl;
881 orphanedRepos.push_back( repoInfo );
885 repoEscAliases.push_back(repoInfo.escaped_alias());
889 if ( ! orphanedRepos.empty() )
891 for (
const auto & repoInfo : orphanedRepos )
893 MIL <<
"Delete orphaned service repo " << repoInfo.alias() << endl;
897 JobReport::warning( str::Format(
_(
"Unknown service '%1%': Removing orphaned service repository '%2%'"))
899 % repoInfo.alias() );
901 removeRepository( repoInfo );
903 catch (
const Exception & caugth )
917 repoEscAliases.sort();
918 cleanupNonRepoMetadtaFolders( _options.repoRawCachePath,
921 cleanupNonRepoMetadtaFolders( _options.repoSolvCachePath,
925 if ( autoPruneInDir( _options.repoPackagesCachePath ) )
926 cleanupNonRepoMetadtaFolders( _options.repoPackagesCachePath,
931 MIL <<
"end construct known repos" << endl;
936 RepoStatus RepoManager::Impl::metadataStatus(
const RepoInfo & info )
const 938 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
939 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
944 repokind = probeCache( productdatapath );
951 switch ( repokind.
toEnum() )
954 status = RepoStatus( productdatapath/
"repodata/repomd.xml");
955 if ( info.requireStatusWithMediaFile() )
956 status = status && RepoStatus( mediarootpath/
"media.1/media" );
960 status = RepoStatus( productdatapath/
"content" ) && RepoStatus( mediarootpath/
"media.1/media" );
974 if ( ! status.empty() )
975 status = status && RepoStatus( info );
981 void RepoManager::Impl::touchIndexFile(
const RepoInfo & info )
983 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
988 repokind = probeCache( productdatapath );
994 switch ( repokind.
toEnum() )
997 p = Pathname(productdatapath +
"/repodata/repomd.xml");
1001 p = Pathname(productdatapath +
"/content");
1005 p = Pathname(productdatapath +
"/cookie");
1018 RepoManager::RefreshCheckStatus RepoManager::Impl::checkIfToRefreshMetadata(
const RepoInfo & info,
const Url & url, RawMetadataRefreshPolicy policy )
1023 MIL <<
"Check if to refresh repo " << info.alias() <<
" at " << url <<
" (" << info.type() <<
")" << endl;
1025 refreshGeoIPData( { url } );
1028 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1030 RepoStatus oldstatus = metadataStatus( info );
1032 if ( oldstatus.empty() )
1034 MIL <<
"No cached metadata, going to refresh" << endl;
1035 return REFRESH_NEEDED;
1038 if ( url.schemeIsVolatile() )
1040 MIL <<
"Never refresh CD/DVD" << endl;
1041 return REPO_UP_TO_DATE;
1044 if ( policy == RefreshForced )
1046 MIL <<
"Forced refresh!" << endl;
1047 return REFRESH_NEEDED;
1050 if ( url.schemeIsLocal() )
1052 policy = RefreshIfNeededIgnoreDelay;
1056 if ( policy != RefreshIfNeededIgnoreDelay )
1061 RepoStatus cachestatus = cacheStatus( info );
1063 if ( oldstatus == cachestatus )
1071 WAR <<
"Repository '" << info.alias() <<
"' was refreshed in the future!" << endl;
1075 MIL <<
"Repository '" << info.alias()
1076 <<
"' has been refreshed less than repo.refresh.delay (" 1078 <<
") minutes ago. Advising to skip refresh" << endl;
1079 return REPO_CHECK_DELAYED;
1084 MIL <<
"Metadata and solv cache don't match. Check data on server..." << endl;
1088 repo::RepoType repokind = info.type();
1091 repokind = probe( url, info.path() );
1094 RepoStatus newstatus;
1095 switch ( repokind.toEnum() )
1112 newstatus = RepoStatus( info ) && RepoStatus( MediaMounter(url).getPathName(info.path()) );
1122 if ( oldstatus == newstatus )
1124 MIL <<
"repo has not changed" << endl;
1125 touchIndexFile( info );
1126 return REPO_UP_TO_DATE;
1130 MIL <<
"repo has changed, going to refresh" << endl;
1131 return REFRESH_NEEDED;
1134 catch (
const Exception &e )
1137 ERR <<
"refresh check failed for " << url << endl;
1141 return REFRESH_NEEDED;
1145 void RepoManager::Impl::refreshMetadata(
const RepoInfo & info, RawMetadataRefreshPolicy policy,
const ProgressData::ReceiverFnc & progress )
1151 refreshGeoIPData( info.baseUrls() );
1154 RepoException rexception( info,
PL_(
"Valid metadata not found at specified URL",
1155 "Valid metadata not found at specified URLs",
1156 info.baseUrlsSize() ) );
1159 media::ScopedDisableMediaChangeReport guard( info.baseUrlsSize() > 1 );
1169 if (checkIfToRefreshMetadata(info, url, policy)!=REFRESH_NEEDED)
1172 MIL <<
"Going to refresh metadata from " << url << endl;
1177 repo::RepoType repokind = info.type();
1179 repo::RepoType probed = probe( *it, info.path() );
1180 if ( repokind != probed )
1184 for_( it, repoBegin(), repoEnd() )
1186 if ( info.alias() == (*it).alias() )
1188 RepoInfo modifiedrepo = *it;
1189 modifiedrepo.setType( repokind );
1196 info.setProbedType( repokind );
1203 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1206 Exception ex(
str::form(
_(
"Can't create %s"), mediarootpath.c_str()) );
1212 if( tmpdir.path().empty() )
1214 Exception ex(
_(
"Can't create metadata cache directory."));
1222 shared_ptr<repo::Downloader> downloader_ptr;
1224 MIL <<
"Creating downloader for [ " << info.alias() <<
" ]" << endl;
1228 if ( _pluginRepoverification.checkIfNeeded() )
1229 downloader_ptr->setPluginRepoverification( _pluginRepoverification );
1240 for_( it, repoBegin(), repoEnd() )
1242 Pathname cachepath(rawcache_path_for_repoinfo( _options, *it ));
1243 if ( PathInfo(cachepath).isExist() )
1244 downloader_ptr->addCachePath(cachepath);
1247 downloader_ptr->download( media, tmpdir.path() );
1252 MediaMounter media( url );
1253 RepoStatus newstatus = RepoStatus( media.getPathName( info.path() ) );
1255 Pathname productpath( tmpdir.path() / info.path() );
1257 newstatus.saveToCookieFile( productpath/
"cookie" );
1267 if ( ! isTmpRepo( info ) )
1273 catch (
const Exception &e )
1276 ERR <<
"Trying another url..." << endl;
1281 if (it == info.baseUrlsBegin())
1282 rexception.remember(e);
1284 rexception.addHistory( e.asUserString() );
1288 ERR <<
"No more urls..." << endl;
1296 ProgressData progress(100);
1297 progress.sendTo(progressfnc);
1304 void RepoManager::Impl::cleanPackages(
const RepoInfo & info,
const ProgressData::ReceiverFnc & progressfnc,
bool isAutoClean_r )
1306 ProgressData progress(100);
1307 progress.sendTo(progressfnc);
1310 const Pathname & rpc { packagescache_path_for_repoinfo(_options, info) };
1311 if ( not isAutoClean_r || autoPruneInDir( rpc.dirname() ) )
1317 void RepoManager::Impl::buildCache(
const RepoInfo & info, CacheBuildPolicy policy,
const ProgressData::ReceiverFnc & progressrcv )
1320 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1321 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
1325 Exception ex(
str::form(
_(
"Can't create %s"), _options.repoCachePath.c_str()) );
1328 RepoStatus raw_metadata_status = metadataStatus(info);
1329 if ( raw_metadata_status.empty() )
1334 refreshMetadata(info, RefreshIfNeeded, progressrcv );
1335 raw_metadata_status = metadataStatus(info);
1338 bool needs_cleaning =
false;
1339 if ( isCached( info ) )
1341 MIL << info.alias() <<
" is already cached." << endl;
1342 RepoStatus cache_status = cacheStatus(info);
1344 if ( cache_status == raw_metadata_status )
1346 MIL << info.alias() <<
" cache is up to date with metadata." << endl;
1347 if ( policy == BuildIfNeeded )
1350 const Pathname & base = solv_path_for_repoinfo( _options, info);
1351 if ( ! PathInfo(base/
"solv.idx").isExist() )
1357 MIL << info.alias() <<
" cache rebuild is forced" << endl;
1361 needs_cleaning =
true;
1364 ProgressData progress(100);
1365 callback::SendReport<ProgressReport> report;
1366 progress.sendTo( ProgressReportAdaptor( progressrcv, report ) );
1367 progress.name(
str::form(
_(
"Building repository '%s' cache"), info.label().c_str()));
1375 MIL << info.alias() <<
" building cache..." << info.type() << endl;
1377 Pathname base = solv_path_for_repoinfo( _options, info);
1381 Exception ex(
str::form(
_(
"Can't create %s"), base.c_str()) );
1385 if( ! PathInfo(base).userMayW() )
1387 Exception ex(
str::form(
_(
"Can't create cache at %s - no writing permissions."), base.c_str()) );
1390 Pathname solvfile = base /
"solv";
1393 repo::RepoType repokind = info.type();
1396 switch ( repokind.toEnum() )
1400 repokind = probeCache( productdatapath );
1406 MIL <<
"repo type is " << repokind << endl;
1408 switch ( repokind.toEnum() )
1416 scoped_ptr<MediaMounter> forPlainDirs;
1419 cmd.push_back( PathInfo(
"/usr/bin/repo2solv" ).isFile() ?
"repo2solv" :
"repo2solv.sh" );
1421 cmd.push_back(
"-o" );
1422 cmd.push_back( solvfile.asString() );
1423 cmd.push_back(
"-X" );
1428 forPlainDirs.reset(
new MediaMounter( info.url() ) );
1430 cmd.push_back(
"-R" );
1432 cmd.push_back( forPlainDirs->getPathName( info.path() ).c_str() );
1435 cmd.push_back( productdatapath.asString() );
1438 std::string errdetail;
1440 for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) {
1441 WAR <<
" " << output;
1442 errdetail += output;
1445 int ret = prog.close();
1449 ex.addHistory( str::Str() << prog.command() << endl << errdetail << prog.execError() );
1454 guard.resetDispose();
1463 setCacheStatus(info, raw_metadata_status);
1464 MIL <<
"Commit cache.." << endl;
1477 repo::RepoType RepoManager::Impl::probe(
const Url & url,
const Pathname & path )
const 1479 MIL <<
"going to probe the repo type at " << url <<
" (" << path <<
")" << endl;
1481 if ( url.getScheme() ==
"dir" && ! PathInfo( url.getPathName()/path ).isDir() )
1485 MIL <<
"Probed type NONE (not exists) at " << url <<
" (" << path <<
")" << endl;
1497 bool gotMediaException =
false;
1503 if ( access.doesFileExist(path/
"/repodata/repomd.xml") )
1505 MIL <<
"Probed type RPMMD at " << url <<
" (" << path <<
")" << endl;
1509 catch (
const media::MediaException &e )
1512 DBG <<
"problem checking for repodata/repomd.xml file" << endl;
1514 gotMediaException =
true;
1519 if ( access.doesFileExist(path/
"/content") )
1521 MIL <<
"Probed type YAST2 at " << url <<
" (" << path <<
")" << endl;
1525 catch (
const media::MediaException &e )
1528 DBG <<
"problem checking for content file" << endl;
1530 gotMediaException =
true;
1534 if ( ! ( url.schemeIsDownloading() || url.schemeIsPlugin() ) )
1536 MediaMounter media( url );
1537 if ( PathInfo(media.getPathName()/path).isDir() )
1540 MIL <<
"Probed type RPMPLAINDIR at " << url <<
" (" << path <<
")" << endl;
1545 catch (
const Exception &e )
1549 Exception enew(
str::form(
_(
"Unknown error reading from '%s'"), url.asString().c_str() ));
1554 if (gotMediaException)
1557 MIL <<
"Probed type NONE at " << url <<
" (" << path <<
")" << endl;
1566 repo::RepoType RepoManager::Impl::probeCache(
const Pathname & path_r )
const 1568 MIL <<
"going to probe the cached repo at " << path_r << endl;
1572 if ( PathInfo(path_r/
"/repodata/repomd.xml").isFile() )
1574 else if ( PathInfo(path_r/
"/content").isFile() )
1576 else if ( PathInfo(path_r).isDir() )
1579 MIL <<
"Probed cached type " << ret <<
" at " << path_r << endl;
1587 MIL <<
"Going to clean up garbage in cache dirs" << endl;
1589 ProgressData progress(300);
1590 progress.sendTo(progressrcv);
1593 std::list<Pathname> cachedirs;
1594 cachedirs.push_back(_options.repoRawCachePath);
1595 cachedirs.push_back(_options.repoPackagesCachePath);
1596 cachedirs.push_back(_options.repoSolvCachePath);
1598 for_( dir, cachedirs.begin(), cachedirs.end() )
1600 if ( PathInfo(*dir).isExist() )
1602 std::list<Pathname> entries;
1607 unsigned sdircount = entries.size();
1608 unsigned sdircurrent = 1;
1609 for_( subdir, entries.begin(), entries.end() )
1613 for_( r, repoBegin(), repoEnd() )
1614 if ( subdir->basename() == r->escaped_alias() )
1615 { found =
true;
break; }
1620 progress.set( progress.val() + sdircurrent * 100 / sdircount );
1625 progress.set( progress.val() + 100 );
1634 ProgressData progress(100);
1635 progress.sendTo(progressrcv);
1638 MIL <<
"Removing raw metadata cache for " << info.alias() << endl;
1649 Pathname solvfile = solv_path_for_repoinfo(_options, info) /
"solv";
1651 if ( ! PathInfo(solvfile).isExist() )
1661 if ( toolversion != LIBSOLV_TOOLVERSION )
1663 repo.eraseFromPool();
1664 ZYPP_THROW(Exception(str::Str() <<
"Solv-file was created by '"<<toolversion<<
"'-parser (want "<<LIBSOLV_TOOLVERSION<<
")."));
1667 catch (
const Exception & exp )
1670 MIL <<
"Try to handle exception by rebuilding the solv-file" << endl;
1671 cleanCache( info, progressrcv );
1672 buildCache( info, BuildIfNeeded, progressrcv );
1684 ProgressData progress(100);
1685 callback::SendReport<ProgressReport> report;
1686 progress.sendTo( ProgressReportAdaptor( progressrcv, report ) );
1687 progress.name(
str::form(
_(
"Adding repository '%s'"), info.label().c_str()));
1690 MIL <<
"Try adding repo " << info << endl;
1692 RepoInfo tosave = info;
1697 if ( _options.probe )
1699 DBG <<
"unknown repository type, probing" << endl;
1700 assert_urls(tosave);
1702 RepoType probedtype( probe( tosave.url(), info.path() ) );
1706 tosave.setType(probedtype);
1714 Pathname repofile = generateNonExistingName(
1715 _options.knownReposPath, generateFilename(tosave));
1717 MIL <<
"Saving repo in " << repofile << endl;
1719 std::ofstream file(repofile.c_str());
1726 tosave.dumpAsIniOn(file);
1727 tosave.setFilepath(repofile);
1728 tosave.setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ) );
1729 tosave.setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ) );
1733 RepoInfo & oinfo( const_cast<RepoInfo &>(info) );
1734 oinfo.setFilepath(repofile);
1735 oinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ) );
1736 oinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ) );
1738 reposManip().insert(tosave);
1743 UrlCredentialExtractor( _options.rootDir ).collect( tosave.baseUrls() );
1745 HistoryLog(_options.rootDir).addRepository(tosave);
1748 MIL <<
"done" << endl;
1755 for ( std::list<RepoInfo>::const_iterator it =
repos.begin();
1760 for_ ( kit, repoBegin(), repoEnd() )
1762 if ( (*it).alias() == (*kit).alias() )
1764 ERR <<
"To be added repo " << (*it).alias() <<
" conflicts with existing repo " << (*kit).alias() << endl;
1770 std::string filename = Pathname(url.getPathName()).basename();
1772 if ( filename == Pathname() )
1781 Pathname repofile = generateNonExistingName(_options.knownReposPath, filename);
1783 MIL <<
"Saving " <<
repos.size() <<
" repo" << (
repos.size() ?
"s" :
"" ) <<
" in " << repofile << endl;
1785 std::ofstream file(repofile.c_str());
1792 for ( std::list<RepoInfo>::iterator it =
repos.begin();
1796 MIL <<
"Saving " << (*it).alias() << endl;
1797 it->dumpAsIniOn(file);
1798 it->setFilepath(repofile);
1799 it->setMetadataPath( rawcache_path_for_repoinfo( _options, *it ) );
1800 it->setPackagesPath( packagescache_path_for_repoinfo( _options, *it ) );
1801 reposManip().insert(*it);
1803 HistoryLog(_options.rootDir).addRepository(*it);
1806 MIL <<
"done" << endl;
1813 ProgressData progress;
1814 callback::SendReport<ProgressReport> report;
1815 progress.sendTo( ProgressReportAdaptor( progressrcv, report ) );
1816 progress.name(
str::form(
_(
"Removing repository '%s'"), info.label().c_str()));
1818 MIL <<
"Going to delete repo " << info.alias() << endl;
1820 for_( it, repoBegin(), repoEnd() )
1825 if ( (!info.alias().empty()) && ( info.alias() != (*it).alias() ) )
1832 RepoInfo todelete = *it;
1833 if (todelete.filepath().empty())
1840 std::list<RepoInfo> filerepos = repositories_in_file(todelete.filepath());
1841 if ( filerepos.size() == 0
1842 ||(filerepos.size() == 1 && filerepos.front().alias() == todelete.alias() ) )
1846 if ( ! ( ret == 0 || ret == ENOENT ) )
1851 MIL << todelete.alias() <<
" successfully deleted." << endl;
1863 std::ofstream file(todelete.filepath().c_str());
1867 ZYPP_THROW( Exception(
str::form(
_(
"Can't open file '%s' for writing."), todelete.filepath().c_str() )));
1869 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1870 fit != filerepos.end();
1873 if ( (*fit).alias() != todelete.alias() )
1874 (*fit).dumpAsIniOn(file);
1878 CombinedProgressData cSubprogrcv(progress, 20);
1879 CombinedProgressData mSubprogrcv(progress, 40);
1880 CombinedProgressData pSubprogrcv(progress, 40);
1882 if ( isCached(todelete) )
1883 cleanCache( todelete, cSubprogrcv);
1885 cleanMetadata( todelete, mSubprogrcv );
1886 cleanPackages( todelete, pSubprogrcv,
true );
1887 reposManip().erase(todelete);
1888 MIL << todelete.alias() <<
" successfully deleted." << endl;
1889 HistoryLog(_options.rootDir).removeRepository(todelete);
1900 void RepoManager::Impl::modifyRepository(
const std::string & alias,
const RepoInfo & newinfo_r,
const ProgressData::ReceiverFnc & progressrcv )
1902 RepoInfo toedit = getRepositoryInfo(alias);
1903 RepoInfo newinfo( newinfo_r );
1906 if ( alias != newinfo.alias() && hasRepo( newinfo.alias() ) )
1911 if (toedit.filepath().empty())
1918 std::list<RepoInfo> filerepos = repositories_in_file(toedit.filepath());
1928 std::ofstream file(toedit.filepath().c_str());
1932 ZYPP_THROW( Exception(
str::form(
_(
"Can't open file '%s' for writing."), toedit.filepath().c_str() )));
1934 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1935 fit != filerepos.end();
1940 if ( (*fit).alias() != toedit.alias() )
1941 (*fit).dumpAsIniOn(file);
1943 newinfo.dumpAsIniOn(file);
1946 if ( toedit.enabled() && !newinfo.enabled() )
1949 const Pathname & solvidx = solv_path_for_repoinfo(_options, newinfo)/
"solv.idx";
1950 if ( PathInfo(solvidx).isExist() )
1954 newinfo.setFilepath(toedit.filepath());
1955 newinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, newinfo ) );
1956 newinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, newinfo ) );
1960 RepoInfo & oinfo( const_cast<RepoInfo &>(newinfo_r) );
1961 oinfo.setFilepath(toedit.filepath());
1962 oinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, newinfo ) );
1963 oinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, newinfo ) );
1965 reposManip().erase(toedit);
1966 reposManip().insert(newinfo);
1968 UrlCredentialExtractor( _options.rootDir ).collect( newinfo.baseUrls() );
1969 HistoryLog(_options.rootDir).modifyRepository(toedit, newinfo);
1970 MIL <<
"repo " << alias <<
" modified" << endl;
1976 RepoInfo RepoManager::Impl::getRepositoryInfo(
const std::string & alias,
const ProgressData::ReceiverFnc & progressrcv )
1978 RepoConstIterator it( findAlias( alias,
repos() ) );
1979 if ( it !=
repos().end() )
1982 info.setAlias( alias );
1987 RepoInfo RepoManager::Impl::getRepositoryInfo(
const Url & url,
const url::ViewOption & urlview,
const ProgressData::ReceiverFnc & progressrcv )
1989 for_( it, repoBegin(), repoEnd() )
1991 for_( urlit, (*it).baseUrlsBegin(), (*it).baseUrlsEnd() )
1993 if ( (*urlit).asString(urlview) == url.asString(urlview) )
1998 info.setBaseUrl( url );
2008 void RepoManager::Impl::addService(
const ServiceInfo & service )
2010 assert_alias( service );
2013 if ( hasService( service.alias() ) )
2018 ServiceInfo toSave( service );
2019 saveService( toSave );
2023 UrlCredentialExtractor( _options.rootDir ).collect( toSave.url() );
2025 MIL <<
"added service " << toSave.alias() << endl;
2030 void RepoManager::Impl::removeService(
const std::string & alias )
2032 MIL <<
"Going to delete service " << alias << endl;
2034 const ServiceInfo & service = getService( alias );
2036 Pathname location = service.filepath();
2037 if( location.empty() )
2043 parser::ServiceFileReader( location, ServiceCollector(tmpSet) );
2046 if ( tmpSet.size() == 1 )
2053 MIL << alias <<
" successfully deleted." << endl;
2059 std::ofstream file(location.c_str());
2066 for_(it, tmpSet.begin(), tmpSet.end())
2068 if( it->alias() != alias )
2069 it->dumpAsIniOn(file);
2072 MIL << alias <<
" successfully deleted from file " << location << endl;
2076 RepoCollector rcollector;
2077 getRepositoriesInService( alias,
2078 boost::make_function_output_iterator( bind( &RepoCollector::collect, &rcollector, _1 ) ) );
2080 for_(rit, rcollector.repos.begin(), rcollector.repos.end())
2081 removeRepository(*rit);
2086 void RepoManager::Impl::refreshServices(
const RefreshServiceOptions & options_r )
2090 ServiceSet services( serviceBegin(), serviceEnd() );
2091 for_( it, services.begin(), services.end() )
2093 if ( !it->enabled() )
2097 refreshService(*it, options_r);
2099 catch (
const repo::ServicePluginInformalException & e )
2104 void RepoManager::Impl::refreshService(
const std::string & alias,
const RefreshServiceOptions & options_r )
2106 ServiceInfo service( getService( alias ) );
2107 assert_alias( service );
2108 assert_url( service );
2109 MIL <<
"Going to refresh service '" << service.alias() <<
"', url: " << service.url() <<
", opts: " << options_r << endl;
2111 if ( service.ttl() && !( options_r.testFlag( RefreshService_forceRefresh) || options_r.testFlag( RefreshService_restoreStatus ) ) )
2114 Date lrf = service.lrf();
2120 if ( (lrf+=service.ttl()) > now )
2122 MIL <<
"Skip: '" << service.alias() <<
"' metadata valid until " << lrf << endl;
2127 WAR <<
"Force: '" << service.alias() <<
"' metadata last refresh in the future: " << lrf << endl;
2134 bool serviceModified =
false;
2141 repo::ServiceType type = probeService( service.url() );
2144 service.setProbedType( type );
2145 serviceModified =
true;
2150 std::string servicesTargetDistro = _options.servicesTargetDistro;
2151 if ( servicesTargetDistro.empty() )
2155 DBG <<
"ServicesTargetDistro: " << servicesTargetDistro << endl;
2159 RepoCollector collector(servicesTargetDistro);
2164 std::pair<DefaultIntegral<bool,false>, repo::ServicePluginInformalException> uglyHack;
2172 ServiceRepos( _options.rootDir, service, bind( &RepoCollector::collect, &collector, _1 ) );
2174 catch (
const repo::ServicePluginInformalException & e )
2177 uglyHack.first =
true;
2178 uglyHack.second = e;
2180 if ( service.ttl() != origTtl )
2182 if ( !service.ttl() )
2183 service.setLrf( Date() );
2184 serviceModified =
true;
2192 for_( it, collector.repos.begin(), collector.repos.end() )
2195 it->setAlias(
str::form(
"%s:%s", service.alias().c_str(), it->alias().c_str() ) );
2197 it->setService( service.alias() );
2200 newRepoStates[it->alias()] = *it;
2208 if ( !it->path().empty() )
2210 if ( it->path() !=
"/" )
2215 if ( it->baseUrlsEmpty() )
2217 Url url( service.rawUrl() );
2218 if ( !path.empty() )
2219 url.setPathName( url.getPathName() / path );
2220 it->setBaseUrl( std::move(url) );
2222 else if ( !path.empty() )
2225 for ( Url & url : urls )
2227 url.setPathName( url.getPathName() / path );
2229 it->setBaseUrls( std::move(urls) );
2236 RepoInfoList oldRepos;
2237 getRepositoriesInService( service.alias(), std::back_inserter( oldRepos ) );
2241 for_( oldRepo, oldRepos.begin(), oldRepos.end() )
2243 if ( ! foundAliasIn( oldRepo->alias(), collector.repos ) )
2245 if ( oldRepo->enabled() )
2248 const auto & last = service.repoStates().find( oldRepo->alias() );
2249 if ( last != service.repoStates().end() && ! last->second.enabled )
2251 DBG <<
"Service removes user enabled repo " << oldRepo->alias() << endl;
2252 service.addRepoToEnable( oldRepo->alias() );
2253 serviceModified =
true;
2256 DBG <<
"Service removes enabled repo " << oldRepo->alias() << endl;
2259 DBG <<
"Service removes disabled repo " << oldRepo->alias() << endl;
2261 removeRepository( *oldRepo );
2267 UrlCredentialExtractor urlCredentialExtractor( _options.rootDir );
2268 for_( it, collector.repos.begin(), collector.repos.end() )
2274 TriBool toBeEnabled( indeterminate );
2275 DBG <<
"Service request to " << (it->enabled()?
"enable":
"disable") <<
" service repo " << it->alias() << endl;
2277 if ( options_r.testFlag( RefreshService_restoreStatus ) )
2279 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() << endl;
2284 service.delRepoToEnable( it->alias() );
2289 if ( service.repoToEnableFind( it->alias() ) )
2291 DBG <<
"User request to enable service repo " << it->alias() << endl;
2296 service.delRepoToEnable( it->alias() );
2297 serviceModified =
true;
2299 else if ( service.repoToDisableFind( it->alias() ) )
2301 DBG <<
"User request to disable service repo " << it->alias() << endl;
2302 toBeEnabled =
false;
2306 RepoInfoList::iterator oldRepo( findAlias( it->alias(), oldRepos ) );
2307 if ( oldRepo == oldRepos.end() )
2312 if ( ! indeterminate(toBeEnabled) )
2313 it->setEnabled( (
bool ) toBeEnabled );
2315 DBG <<
"Service adds repo " << it->alias() <<
" " << (it->enabled()?
"enabled":
"disabled") << endl;
2316 addRepository( *it );
2321 bool oldRepoModified =
false;
2323 if ( indeterminate(toBeEnabled) )
2327 if ( oldRepo->enabled() == it->enabled() )
2328 toBeEnabled = it->enabled();
2329 else if (options_r.testFlag( RefreshService_restoreStatus ) )
2331 toBeEnabled = it->enabled();
2332 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() <<
" forces " << (toBeEnabled?
"enabled":
"disabled") << endl;
2336 const auto & last = service.repoStates().find( oldRepo->alias() );
2337 if ( last == service.repoStates().end() || last->second.enabled != it->enabled() )
2338 toBeEnabled = it->enabled();
2341 toBeEnabled = oldRepo->enabled();
2342 DBG <<
"User modified service repo " << it->alias() <<
" may stay " << (toBeEnabled?
"enabled":
"disabled") << endl;
2348 if ( toBeEnabled == oldRepo->enabled() )
2350 DBG <<
"Service repo " << it->alias() <<
" stays " << (oldRepo->enabled()?
"enabled":
"disabled") << endl;
2352 else if ( toBeEnabled )
2354 DBG <<
"Service repo " << it->alias() <<
" gets enabled" << endl;
2355 oldRepo->setEnabled(
true );
2356 oldRepoModified =
true;
2360 DBG <<
"Service repo " << it->alias() <<
" gets disabled" << endl;
2361 oldRepo->setEnabled(
false );
2362 oldRepoModified =
true;
2368 if ( oldRepo->rawName() != it->rawName() )
2370 DBG <<
"Service repo " << it->alias() <<
" gets new NAME " << it->rawName() << endl;
2371 oldRepo->setName( it->rawName() );
2372 oldRepoModified =
true;
2376 if ( oldRepo->autorefresh() != it->autorefresh() )
2378 DBG <<
"Service repo " << it->alias() <<
" gets new AUTOREFRESH " << it->autorefresh() << endl;
2379 oldRepo->setAutorefresh( it->autorefresh() );
2380 oldRepoModified =
true;
2384 if ( oldRepo->priority() != it->priority() )
2386 DBG <<
"Service repo " << it->alias() <<
" gets new PRIORITY " << it->priority() << endl;
2387 oldRepo->setPriority( it->priority() );
2388 oldRepoModified =
true;
2394 urlCredentialExtractor.extract( newUrls );
2395 if ( oldRepo->rawBaseUrls() != newUrls )
2397 DBG <<
"Service repo " << it->alias() <<
" gets new URLs " << newUrls << endl;
2398 oldRepo->setBaseUrls( std::move(newUrls) );
2399 oldRepoModified =
true;
2409 oldRepo->getRawGpgChecks( ogpg[0], ogpg[1], ogpg[2] );
2410 it-> getRawGpgChecks( ngpg[0], ngpg[1], ngpg[2] );
2411 #define Z_CHKGPG(I,N) \ 2412 if ( ! sameTriboolState( ogpg[I], ngpg[I] ) ) \ 2414 DBG << "Service repo " << it->alias() << " gets new "#N"Check " << ngpg[I] << endl; \ 2415 oldRepo->set##N##Check( ngpg[I] ); \ 2416 oldRepoModified = true; \ 2425 if ( oldRepoModified )
2427 modifyRepository( oldRepo->alias(), *oldRepo );
2433 if ( ! service.reposToDisableEmpty() )
2435 service.clearReposToDisable();
2436 serviceModified =
true;
2440 if ( service.repoStates() != newRepoStates )
2442 service.setRepoStates( std::move(newRepoStates) );
2443 serviceModified =
true;
2450 if ( service.ttl() )
2453 serviceModified =
true;
2456 if ( serviceModified )
2459 modifyService( service.alias(), service );
2463 if ( uglyHack.first )
2465 throw( uglyHack.second );
2471 void RepoManager::Impl::modifyService(
const std::string & oldAlias,
const ServiceInfo & newService )
2473 MIL <<
"Going to modify service " << oldAlias << endl;
2477 ServiceInfo service(newService);
2484 const ServiceInfo & oldService = getService(oldAlias);
2486 Pathname location = oldService.filepath();
2487 if( location.empty() )
2494 parser::ServiceFileReader( location, ServiceCollector(tmpSet) );
2497 std::ofstream file(location.c_str());
2498 for_(it, tmpSet.begin(), tmpSet.end())
2500 if( *it != oldAlias )
2501 it->dumpAsIniOn(file);
2503 service.dumpAsIniOn(file);
2505 service.setFilepath(location);
2510 UrlCredentialExtractor( _options.rootDir ).collect( service.url() );
2514 if ( oldAlias != service.alias()
2515 || oldService.enabled() != service.enabled() )
2517 std::vector<RepoInfo> toModify;
2518 getRepositoriesInService(oldAlias, std::back_inserter(toModify));
2519 for_( it, toModify.begin(), toModify.end() )
2521 if ( oldService.enabled() != service.enabled() )
2523 if ( service.enabled() )
2526 const auto & last = service.repoStates().find( it->alias() );
2527 if ( last != service.repoStates().end() )
2528 it->setEnabled( last->second.enabled );
2531 it->setEnabled(
false );
2534 if ( oldAlias != service.alias() )
2535 it->setService(service.alias());
2537 modifyRepository(it->alias(), *it);
2546 repo::ServiceType RepoManager::Impl::probeService(
const Url & url )
const 2551 if ( access.doesFileExist(
"/repo/repoindex.xml") )
2554 catch (
const media::MediaException &e )
2562 catch (
const Exception &e )
2566 Exception enew(
str::form(
_(
"Unknown error reading from '%s'"), url.asString().c_str() ));
2579 MIL <<
"GeoIp disabled via ZConfig, not refreshing the GeoIP information." << std::endl;
2583 std::vector<std::string> hosts;
2584 for (
const auto &baseUrl : urls ) {
2585 const auto &host = baseUrl.getHost();
2587 hosts.push_back( host );
2592 if ( hosts.empty() ) {
2593 MIL <<
"No configured geoip URL found, not updating geoip data" << std::endl;
2600 MIL <<
"Unable to create cache directory for GeoIP." << std::endl;
2604 if ( !PathInfo(geoIPCache).userMayRWX() ) {
2605 MIL <<
"No access rights for the GeoIP cache directory." << std::endl;
2614 PathInfo pi( dir/entry.name );
2615 auto age = std::chrono::system_clock::now() - std::chrono::system_clock::from_time_t( pi.mtime() );
2616 if ( age < std::chrono::hours(24) )
2619 MIL <<
"Removing GeoIP file for " << entry.name <<
" since it's older than 24hrs." << std::endl;
2625 std::for_each( hosts.begin(), hosts.end(), [ & ](
const std::string &hostname ) {
2629 MIL <<
"Skipping GeoIP request for " << hostname <<
" since a valid cache entry exists." << std::endl;
2633 MIL <<
"Query GeoIP for " << hostname << std::endl;
2644 MIL <<
"Ignoring invalid GeoIP hostname: " << hostname << std::endl;
2656 MIL <<
"Failed to query GeoIP from hostname: " << hostname << std::endl;
2659 if ( !file->
empty() ) {
2661 constexpr
auto writeHostToFile = [](
const Pathname &fName,
const std::string &host ){
2663 out.open( fName.asString(), std::ios_base::trunc );
2664 if ( out.is_open() ) {
2665 out << host << std::endl;
2667 MIL <<
"Failed to create/open GeoIP cache file " << fName << std::endl;
2671 std::string geoipMirror;
2674 if ( reader.seekToNode( 1,
"host" ) ) {
2675 const auto &
str = reader.nodeText().asString();
2683 MIL <<
"Storing geoIP redirection: " << hostname <<
" -> " <<
str << std::endl;
2688 MIL <<
"No host entry or empty file returned for GeoIP, remembering for 24hrs" << std::endl;
2692 MIL <<
"Empty or invalid GeoIP file, not requesting again for 24hrs" << std::endl;
2695 writeHostToFile( geoIPCache / hostname, geoipMirror );
2701 MIL <<
"Failed to query GeoIP data." << std::endl;
2712 : _pimpl( new
Impl(opt) )
2719 {
return _pimpl->repoEmpty(); }
2722 {
return _pimpl->repoSize(); }
2725 {
return _pimpl->repoBegin(); }
2728 {
return _pimpl->repoEnd(); }
2731 {
return _pimpl->getRepo( alias ); }
2734 {
return _pimpl->hasRepo( alias ); }
2744 std::string host( url_r.
getHost() );
2745 if ( ! host.empty() )
2757 {
return _pimpl->metadataStatus( info ); }
2760 {
return _pimpl->checkIfToRefreshMetadata( info, url, policy ); }
2763 {
return _pimpl->metadataPath( info ); }
2766 {
return _pimpl->packagesPath( info ); }
2769 {
return _pimpl->refreshMetadata( info, policy, progressrcv ); }
2772 {
return _pimpl->cleanMetadata( info, progressrcv ); }
2775 {
return _pimpl->cleanPackages( info, progressrcv ); }
2778 {
return _pimpl->cacheStatus( info ); }
2781 {
return _pimpl->buildCache( info, policy, progressrcv ); }
2784 {
return _pimpl->cleanCache( info, progressrcv ); }
2787 {
return _pimpl->isCached( info ); }
2790 {
return _pimpl->loadFromCache( info, progressrcv ); }
2793 {
return _pimpl->cleanCacheDirGarbage( progressrcv ); }
2796 {
return _pimpl->probe( url, path ); }
2799 {
return _pimpl->probe( url ); }
2802 {
return _pimpl->addRepository( info, progressrcv ); }
2805 {
return _pimpl->addRepositories( url, progressrcv ); }
2808 {
return _pimpl->removeRepository( info, progressrcv ); }
2811 {
return _pimpl->modifyRepository( alias, newinfo, progressrcv ); }
2814 {
return _pimpl->getRepositoryInfo( alias, progressrcv ); }
2817 {
return _pimpl->getRepositoryInfo( url, urlview, progressrcv ); }
2820 {
return _pimpl->serviceEmpty(); }
2823 {
return _pimpl->serviceSize(); }
2826 {
return _pimpl->serviceBegin(); }
2829 {
return _pimpl->serviceEnd(); }
2832 {
return _pimpl->getService( alias ); }
2835 {
return _pimpl->hasService( alias ); }
2838 {
return _pimpl->probeService( url ); }
2841 {
return _pimpl->addService( alias, url ); }
2844 {
return _pimpl->addService( service ); }
2847 {
return _pimpl->removeService( alias ); }
2850 {
return _pimpl->removeService( service ); }
2853 {
return _pimpl->refreshServices( options_r ); }
2856 {
return _pimpl->refreshService( alias, options_r ); }
2859 {
return _pimpl->refreshService( service, options_r ); }
2862 {
return _pimpl->modifyService( oldAlias, service ); }
2865 {
return _pimpl->refreshGeoIPData( urls ); }
RefreshCheckStatus checkIfToRefreshMetadata(const RepoInfo &info, const Url &url, RawMetadataRefreshPolicy policy)
std::string getScheme() const
Returns the scheme name of the URL.
std::string asString(const Patch::Category &obj)
static const ValueType day
RefreshCheckStatus
Possibly return state of checkIfRefreshMEtadata function.
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
thrown when it was impossible to match a repository
Thrown when the repo alias is found to be invalid.
std::string targetDistribution() const
This is register.target attribute of the installed base product.
RepoManagerOptions(const Pathname &root_r=Pathname())
Default ctor following ZConfig global settings.
Pathname builtinRepoPackagesPath() const
The builtin config file value.
constexpr std::string_view Url("url")
static const std::string & sha1()
sha1
void getRepositoriesInService(const std::string &alias, OutputIterator out) const
int exchange(const Pathname &lpath, const Pathname &rpath)
Exchanges two files or directories.
static bool error(const std::string &msg_r, const UserData &userData_r=UserData())
send error text
bool hasRepo(const std::string &alias) const
thrown when it was impossible to determine this repo type.
std::string digest()
get hex string representation of the digest
Retrieval of repository list for a service.
Pathname repoRawCachePath
Repository metadata verification beyond GPG.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
static ZConfig & instance()
Singleton ctor.
static TmpDir makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
scoped_ptr< media::CredentialManager > _cmPtr
Impl * clone() const
clone for RWCOW_pointer
void removeService(const std::string &alias)
Service plugin is immutable.
ServiceInfo getService(const std::string &alias) const
RepoSizeType repoSize() const
void refreshServices(const RefreshServiceOptions &options_r)
Pathname builtinRepoMetadataPath() const
The builtin config file value.
Pathname metadataPath(const RepoInfo &info) const
bool repo_add_probe() const
Whether repository urls should be probed.
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
String related utilities and Regular expression matching.
RefreshServiceFlags RefreshServiceOptions
Options tuning RefreshService.
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
What is known about a repository.
ServiceSet::size_type ServiceSizeType
static bool warning(const std::string &msg_r, const UserData &userData_r=UserData())
send warning text
RepoInfo getRepositoryInfo(const std::string &alias, OPT_PROGRESS)
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
Pathname knownServicesPath
void setHost(const std::string &host)
Set the hostname or IP in the URL authority.
void addRepositories(const Url &url, OPT_PROGRESS)
RepoInfo getRepo(const std::string &alias) const
void reposErase(const std::string &alias_r)
Remove a Repository named alias_r.
Service already exists and some unique attribute can't be duplicated.
void cleanPackages(const RepoInfo &info, OPT_PROGRESS, bool isAutoClean=false)
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
static RepoStatus fromCookieFile(const Pathname &path)
Reads the status from a cookie file.
Service without alias was used in an operation.
repo::ServiceType probeService(const Url &url) const
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
void buildCache(const RepoInfo &info, CacheBuildPolicy policy, OPT_PROGRESS)
Url::asString() view options.
void modifyService(const std::string &oldAlias, const ServiceInfo &newService)
Pathname repoSolvCachePath
std::vector< std::string > Arguments
PluginRepoverification _pluginRepoverification
repo::RepoType probe(const Url &url, const Pathname &path=Pathname()) const
std::string generateFilename(const RepoInfo &info) const
void loadFromCache(const RepoInfo &info, OPT_PROGRESS)
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
std::string & replaceAll(std::string &str_r, const std::string &from_r, const std::string &to_r)
Replace all occurrences of from_r with to_r in str_r (inplace).
transform_iterator< repo::RepoVariablesUrlReplacer, url_set::const_iterator > urls_const_iterator
std::map< std::string, RepoState > RepoStates
static const ServiceType RIS
Repository Index Service (RIS) (formerly known as 'Novell Update' (NU) service)
void saveToCookieFile(const Pathname &path_r) const
Save the status information to a cookie file.
bool empty() const
Test for an empty path.
std::set< ServiceInfo > ServiceSet
ServiceInfo typedefs.
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
void addRepository(const RepoInfo &info, OPT_PROGRESS)
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
static Pool instance()
Singleton ctor.
static RepoManagerOptions makeTestSetup(const Pathname &root_r)
Test setup adjusting all paths to be located below one root_r directory.
Pathname rootDir
remembers root_r value for later use
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
void setScheme(const std::string &scheme)
Set the scheme name in the URL.
int unlink(const Pathname &path)
Like 'unlink'.
thrown when it was impossible to determine one url for this repo.
RepoStatus status(MediaSetAccess &media_r) override
Status of the remote repository.
std::string alias() const
unique identifier for this source.
bool isExist() const
Return whether valid stat info exists.
void addService(const std::string &alias, const Url &url)
unsigned repo_refresh_delay() const
Amount of time in minutes that must pass before another refresh.
bool serviceEmpty() const
std::set< RepoInfo > RepoSet
RepoInfo typedefs.
static const ServiceType NONE
No service set.
static const SolvAttr repositoryToolVersion
Service type enumeration.
std::ostream & operator<<(std::ostream &str, const DeltaCandidates &obj)
static Pathname assertprefix(const Pathname &root_r, const Pathname &path_r)
Return path_r prefixed with root_r, unless it is already prefixed.
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
void cleanMetadata(const RepoInfo &info, OPT_PROGRESS)
std::string asCompleteString() const
Returns a complete string representation of the Url object.
const RepoSet & repos() const
Iterate the known repositories.
void updateSolvFileIndex(const Pathname &solvfile_r)
Create solv file content digest for zypper bash completion.
void removeService(const ServiceInfo &service)
static const ServiceType PLUGIN
Plugin services are scripts installed on your system that provide the package manager with repositori...
bool isCached(const RepoInfo &info) const
Base Exception for service handling.
bool isValid() const
Verifies the Url.
ServiceSet::const_iterator ServiceConstIterator
Pathname geoipCachePath() const
Path where the geoip caches are kept (/var/cache/zypp/geoip)
ServiceConstIterator serviceBegin() const
const std::string & asString() const
Return current Pathname as String.
std::string numstring(char n, int w=0)
static const RepoType NONE
Impl(const RepoManagerOptions &opt)
int touch(const Pathname &path)
Change file's modification and access times.
int compareCI(const C_Str &lhs, const C_Str &rhs)
ServiceConstIterator serviceEnd() const
std::ostream & copy(std::istream &from_r, std::ostream &to_r)
Copy istream to ostream.
static const RepoType RPMMD
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
RWCOW_pointer< Impl > _pimpl
Pointer to implementation.
Pathname builtinRepoSolvfilesPath() const
The builtin config file value.
std::list< RepoInfo > readRepoFile(const Url &repo_file)
Parses repo_file and returns a list of RepoInfo objects corresponding to repositories found within th...
void refreshService(const ServiceInfo &service, const RefreshServiceOptions &options_r)
static const RepoType YAST2
void refreshMetadata(const RepoInfo &info, RawMetadataRefreshPolicy policy, OPT_PROGRESS)
thrown when it was impossible to determine an alias for this repo.
RepoSet::size_type RepoSizeType
std::string generateFilename(const ServiceInfo &info) const
Base class for Exception.
Exception for repository handling.
RepoConstIterator repoBegin() const
bool any_of(const Container &c, Fnc &&cb)
static std::string makeStupidAlias(const Url &url_r=Url())
Some stupid string but suitable as alias for your url if nothing better is available.
media::MediaAccessId _mid
static Date now()
Return the current time.
bool ZYPP_PLUGIN_APPDATA_FORCE_COLLECT()
To trigger appdata refresh unconditionally.
#define PL_(MSG1, MSG2, N)
std::string getHost(EEncoding eflag=zypp::url::E_DECODED) const
Returns the hostname or IP from the URL authority.
Functor thats filter RepoInfo by service which it belongs to.
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
The repository cache is not built yet so you can't create the repostories from the cache...
Pathname repoPackagesCachePath
int dirForEachExt(const Pathname &dir_r, const function< bool(const Pathname &, const DirEntry &)> &fnc_r)
Simiar to.
static const ServiceInfo noService
Represents an empty service.
void removeRepository(const RepoInfo &info, OPT_PROGRESS)
Wrapper class for ::stat/::lstat.
static const RepoInfo noRepo
Represents no Repository (one with an empty alias).
bool regex_match(const std::string &s, smatch &matches, const regex ®ex)
regex ZYPP_STR_REGEX regex ZYPP_STR_REGEX
Thrown when the repo alias is found to be invalid.
static const RepoType RPMPLAINDIR
static const std::string & systemRepoAlias()
Reserved system repository alias .
RepoStatus metadataStatus(const RepoInfo &info) const
Track changing files or directories.
void modifyRepository(const std::string &alias, const RepoInfo &newinfo_r, OPT_PROGRESS)
Repository already exists and some unique attribute can't be duplicated.
ServiceSizeType serviceSize() const
Functor replacing repository variables.
RepoManagerOptions _options
void refreshService(const std::string &alias, const RefreshServiceOptions &options_r)
Repository addRepoSolv(const Pathname &file_r, const std::string &name_r)
Load Solvables from a solv-file into a Repository named name_r.
Downloader for YUM (rpm-nmd) repositories Encapsulates all the knowledge of which files have to be do...
void addService(const ServiceInfo &service)
Easy-to use interface to the ZYPP dependency resolver.
RepoManager(const RepoManagerOptions &options=RepoManagerOptions())
RepoConstIterator repoEnd() const
void refreshGeoIp(const RepoInfo::url_set &urls)
std::string hexstring(char n, int w=4)
RepoManager implementation.
void cleanCacheDirGarbage(OPT_PROGRESS)
std::ostream & operator<<(std::ostream &str, const RepoManager::Impl &obj)
Service has no or invalid url defined.
RepoStatus cacheStatus(const RepoInfo &info) const
bool hasService(const std::string &alias) const
void cleanCache(const RepoInfo &info, OPT_PROGRESS)
RepoSet::const_iterator RepoConstIterator
void setCacheStatus(const RepoInfo &info, const RepoStatus &status)
Repository type enumeration.
DefaultIntegral< bool, false > _reposDirty
Pathname packagesPath(const RepoInfo &info) const