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(); }
473 DBG <<
"reading repo file " << repo_file <<
", local path: " << local << endl;
475 return repositories_in_file(local);
514 #define OUTS(X) str << " " #X "\t" << obj.X << endl 515 str <<
"RepoManagerOptions (" << obj.
rootDir <<
") {" << endl;
516 OUTS( repoRawCachePath );
517 OUTS( repoSolvCachePath );
518 OUTS( repoPackagesCachePath );
519 OUTS( knownReposPath );
520 OUTS( knownServicesPath );
537 , _pluginRepoverification( _options.pluginsPath/
"repoverification", _options.rootDir )
539 init_knownServices();
540 init_knownRepositories();
547 && geteuid() == 0 && ( _options.rootDir.empty() || _options.rootDir ==
"/" ) )
550 std::list<Pathname> entries;
552 if ( ! entries.empty() )
555 cmd.push_back(
"<" );
556 cmd.push_back(
">" );
557 cmd.push_back(
"PROGRAM" );
558 for (
const auto & rinfo :
repos() )
560 if ( ! rinfo.enabled() )
562 cmd.push_back(
"-R" );
563 cmd.push_back( rinfo.alias() );
564 cmd.push_back(
"-t" );
565 cmd.push_back( rinfo.type().asString() );
566 cmd.push_back(
"-p" );
567 cmd.push_back( (rinfo.metadataPath()/rinfo.path()).
asString() );
570 for_( it, entries.begin(), entries.end() )
593 bool hasRepo(
const std::string & alias )
const 594 {
return foundAliasIn( alias,
repos() ); }
604 {
return rawcache_path_for_repoinfo( _options, info ); }
607 {
return packagescache_path_for_repoinfo( _options, info ); }
611 RefreshCheckStatus checkIfToRefreshMetadata(
const RepoInfo & info,
const Url & url, RawMetadataRefreshPolicy policy );
629 {
return PathInfo(solv_path_for_repoinfo( _options, info ) /
"solv").
isExist(); }
654 {
return foundAliasIn( alias,
_services ); }
667 void removeService(
const std::string & alias );
669 { removeService( service.
alias() ); }
671 void refreshServices(
const RefreshServiceOptions & options_r );
673 void refreshService(
const std::string & alias,
const RefreshServiceOptions & options_r );
675 { refreshService( service.
alias(), options_r ); }
677 void modifyService(
const std::string & oldAlias,
const ServiceInfo & newService );
686 Pathname generateNonExistingName(
const Pathname & dir,
const std::string & basefilename )
const;
689 {
return filenameFromAlias( info.
alias(),
"repo" ); }
692 {
return filenameFromAlias( info.
alias(),
"service" ); }
696 Pathname base = solv_path_for_repoinfo( _options, info );
701 void touchIndexFile(
const RepoInfo & info );
703 template<
typename OutputIterator>
708 boost::make_filter_iterator( filter,
repos().end(),
repos().end() ),
713 void init_knownServices();
714 void init_knownRepositories();
729 friend Impl * rwcowClone<Impl>(
const Impl * rhs );
732 {
return new Impl( *
this ); }
738 {
return str <<
"RepoManager::Impl"; }
742 void RepoManager::Impl::saveService( ServiceInfo & service )
const 745 Pathname servfile = generateNonExistingName( _options.knownServicesPath,
746 generateFilename( service ) );
747 service.setFilepath( servfile );
749 MIL <<
"saving service in " << servfile << endl;
751 std::ofstream file( servfile.c_str() );
757 service.dumpAsIniOn( file );
758 MIL <<
"done" << endl;
776 Pathname RepoManager::Impl::generateNonExistingName(
const Pathname & dir,
777 const std::string & basefilename )
const 779 std::string final_filename = basefilename;
781 while ( PathInfo(dir + final_filename).isExist() )
786 return dir + Pathname(final_filename);
791 void RepoManager::Impl::init_knownServices()
793 Pathname dir = _options.knownServicesPath;
794 std::list<Pathname> entries;
795 if (PathInfo(dir).isExist())
804 for_(it, entries.begin(), entries.end() )
806 parser::ServiceFileReader(*it, ServiceCollector(
_services));
810 repo::PluginServices(_options.pluginsPath/
"services", ServiceCollector(
_services));
821 inline void cleanupNonRepoMetadtaFolders(
const Pathname & cachePath_r,
822 const Pathname & defaultCachePath_r,
823 const std::list<std::string> & repoEscAliases_r )
828 if ( cachePath_r != defaultCachePath_r )
831 std::list<std::string> entries;
835 std::set<std::string> oldfiles;
836 set_difference( entries.begin(), entries.end(), repoEscAliases_r.begin(), repoEscAliases_r.end(),
837 std::inserter( oldfiles, oldfiles.end() ) );
843 for (
const std::string & old : oldfiles )
847 pi( cachePath_r/old );
857 void RepoManager::Impl::init_knownRepositories()
859 MIL <<
"start construct known repos" << endl;
861 if ( PathInfo(_options.knownReposPath).isExist() )
863 std::list<std::string> repoEscAliases;
864 std::list<RepoInfo> orphanedRepos;
865 for ( RepoInfo & repoInfo : repositories_in_dir(_options.knownReposPath) )
868 repoInfo.setMetadataPath( rawcache_path_for_repoinfo(_options, repoInfo) );
870 repoInfo.setPackagesPath( packagescache_path_for_repoinfo(_options, repoInfo) );
872 _reposX.insert( repoInfo );
875 const std::string & serviceAlias( repoInfo.service() );
876 if ( ! ( serviceAlias.empty() || hasService( serviceAlias ) ) )
878 WAR <<
"Schedule orphaned service repo for deletion: " << repoInfo << endl;
879 orphanedRepos.push_back( repoInfo );
883 repoEscAliases.push_back(repoInfo.escaped_alias());
887 if ( ! orphanedRepos.empty() )
889 for (
const auto & repoInfo : orphanedRepos )
891 MIL <<
"Delete orphaned service repo " << repoInfo.alias() << endl;
895 JobReport::warning( str::Format(
_(
"Unknown service '%1%': Removing orphaned service repository '%2%'"))
897 % repoInfo.alias() );
899 removeRepository( repoInfo );
901 catch (
const Exception & caugth )
915 repoEscAliases.sort();
916 cleanupNonRepoMetadtaFolders( _options.repoRawCachePath,
919 cleanupNonRepoMetadtaFolders( _options.repoSolvCachePath,
923 if ( autoPruneInDir( _options.repoPackagesCachePath ) )
924 cleanupNonRepoMetadtaFolders( _options.repoPackagesCachePath,
929 MIL <<
"end construct known repos" << endl;
934 RepoStatus RepoManager::Impl::metadataStatus(
const RepoInfo & info )
const 936 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
937 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
942 repokind = probeCache( productdatapath );
949 switch ( repokind.
toEnum() )
952 status = RepoStatus( productdatapath/
"repodata/repomd.xml");
953 if ( info.requireStatusWithMediaFile() )
954 status = status && RepoStatus( mediarootpath/
"media.1/media" );
958 status = RepoStatus( productdatapath/
"content" ) && RepoStatus( mediarootpath/
"media.1/media" );
972 if ( ! status.empty() )
973 status = status && RepoStatus( info );
979 void RepoManager::Impl::touchIndexFile(
const RepoInfo & info )
981 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
986 repokind = probeCache( productdatapath );
992 switch ( repokind.
toEnum() )
995 p = Pathname(productdatapath +
"/repodata/repomd.xml");
999 p = Pathname(productdatapath +
"/content");
1003 p = Pathname(productdatapath +
"/cookie");
1016 RepoManager::RefreshCheckStatus RepoManager::Impl::checkIfToRefreshMetadata(
const RepoInfo & info,
const Url & url, RawMetadataRefreshPolicy policy )
1021 MIL <<
"Check if to refresh repo " << info.alias() <<
" at " << url <<
" (" << info.type() <<
")" << endl;
1023 refreshGeoIPData( { url } );
1026 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1028 RepoStatus oldstatus = metadataStatus( info );
1030 if ( oldstatus.empty() )
1032 MIL <<
"No cached metadata, going to refresh" << endl;
1033 return REFRESH_NEEDED;
1036 if ( url.schemeIsVolatile() )
1038 MIL <<
"Never refresh CD/DVD" << endl;
1039 return REPO_UP_TO_DATE;
1042 if ( policy == RefreshForced )
1044 MIL <<
"Forced refresh!" << endl;
1045 return REFRESH_NEEDED;
1048 if ( url.schemeIsLocal() )
1050 policy = RefreshIfNeededIgnoreDelay;
1054 if ( policy != RefreshIfNeededIgnoreDelay )
1059 RepoStatus cachestatus = cacheStatus( info );
1061 if ( oldstatus == cachestatus )
1069 WAR <<
"Repository '" << info.alias() <<
"' was refreshed in the future!" << endl;
1073 MIL <<
"Repository '" << info.alias()
1074 <<
"' has been refreshed less than repo.refresh.delay (" 1076 <<
") minutes ago. Advising to skip refresh" << endl;
1077 return REPO_CHECK_DELAYED;
1082 MIL <<
"Metadata and solv cache don't match. Check data on server..." << endl;
1086 repo::RepoType repokind = info.type();
1089 repokind = probe( url, info.path() );
1092 RepoStatus newstatus;
1093 switch ( repokind.toEnum() )
1110 newstatus = RepoStatus( info ) && RepoStatus( MediaMounter(url).getPathName(info.path()) );
1120 if ( oldstatus == newstatus )
1122 MIL <<
"repo has not changed" << endl;
1123 touchIndexFile( info );
1124 return REPO_UP_TO_DATE;
1128 MIL <<
"repo has changed, going to refresh" << endl;
1129 return REFRESH_NEEDED;
1132 catch (
const Exception &e )
1135 ERR <<
"refresh check failed for " << url << endl;
1139 return REFRESH_NEEDED;
1143 void RepoManager::Impl::refreshMetadata(
const RepoInfo & info, RawMetadataRefreshPolicy policy,
const ProgressData::ReceiverFnc & progress )
1149 refreshGeoIPData( info.baseUrls() );
1152 RepoException rexception( info,
PL_(
"Valid metadata not found at specified URL",
1153 "Valid metadata not found at specified URLs",
1154 info.baseUrlsSize() ) );
1157 media::ScopedDisableMediaChangeReport guard( info.baseUrlsSize() > 1 );
1167 if (checkIfToRefreshMetadata(info, url, policy)!=REFRESH_NEEDED)
1170 MIL <<
"Going to refresh metadata from " << url << endl;
1175 repo::RepoType repokind = info.type();
1177 repo::RepoType probed = probe( *it, info.path() );
1178 if ( repokind != probed )
1182 for_( it, repoBegin(), repoEnd() )
1184 if ( info.alias() == (*it).alias() )
1186 RepoInfo modifiedrepo = *it;
1187 modifiedrepo.setType( repokind );
1194 info.setProbedType( repokind );
1201 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1204 Exception ex(
str::form(
_(
"Can't create %s"), mediarootpath.c_str()) );
1210 if( tmpdir.path().empty() )
1212 Exception ex(
_(
"Can't create metadata cache directory."));
1220 shared_ptr<repo::Downloader> downloader_ptr;
1222 MIL <<
"Creating downloader for [ " << info.alias() <<
" ]" << endl;
1226 if ( _pluginRepoverification.checkIfNeeded() )
1227 downloader_ptr->setPluginRepoverification( _pluginRepoverification );
1238 for_( it, repoBegin(), repoEnd() )
1240 Pathname cachepath(rawcache_path_for_repoinfo( _options, *it ));
1241 if ( PathInfo(cachepath).isExist() )
1242 downloader_ptr->addCachePath(cachepath);
1245 downloader_ptr->download( media, tmpdir.path() );
1250 MediaMounter media( url );
1251 RepoStatus newstatus = RepoStatus( media.getPathName( info.path() ) );
1253 Pathname productpath( tmpdir.path() / info.path() );
1255 newstatus.saveToCookieFile( productpath/
"cookie" );
1265 if ( ! isTmpRepo( info ) )
1271 catch (
const Exception &e )
1274 ERR <<
"Trying another url..." << endl;
1279 if (it == info.baseUrlsBegin())
1280 rexception.remember(e);
1282 rexception.addHistory( e.asUserString() );
1286 ERR <<
"No more urls..." << endl;
1294 ProgressData progress(100);
1295 progress.sendTo(progressfnc);
1302 void RepoManager::Impl::cleanPackages(
const RepoInfo & info,
const ProgressData::ReceiverFnc & progressfnc,
bool isAutoClean_r )
1304 ProgressData progress(100);
1305 progress.sendTo(progressfnc);
1308 const Pathname & rpc { packagescache_path_for_repoinfo(_options, info) };
1309 if ( not isAutoClean_r || autoPruneInDir( rpc.dirname() ) )
1315 void RepoManager::Impl::buildCache(
const RepoInfo & info, CacheBuildPolicy policy,
const ProgressData::ReceiverFnc & progressrcv )
1318 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1319 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
1323 Exception ex(
str::form(
_(
"Can't create %s"), _options.repoCachePath.c_str()) );
1326 RepoStatus raw_metadata_status = metadataStatus(info);
1327 if ( raw_metadata_status.empty() )
1332 refreshMetadata(info, RefreshIfNeeded, progressrcv );
1333 raw_metadata_status = metadataStatus(info);
1336 bool needs_cleaning =
false;
1337 if ( isCached( info ) )
1339 MIL << info.alias() <<
" is already cached." << endl;
1340 RepoStatus cache_status = cacheStatus(info);
1342 if ( cache_status == raw_metadata_status )
1344 MIL << info.alias() <<
" cache is up to date with metadata." << endl;
1345 if ( policy == BuildIfNeeded )
1348 const Pathname & base = solv_path_for_repoinfo( _options, info);
1349 if ( ! PathInfo(base/
"solv.idx").isExist() )
1355 MIL << info.alias() <<
" cache rebuild is forced" << endl;
1359 needs_cleaning =
true;
1362 ProgressData progress(100);
1363 callback::SendReport<ProgressReport> report;
1364 progress.sendTo( ProgressReportAdaptor( progressrcv, report ) );
1365 progress.name(
str::form(
_(
"Building repository '%s' cache"), info.label().c_str()));
1373 MIL << info.alias() <<
" building cache..." << info.type() << endl;
1375 Pathname base = solv_path_for_repoinfo( _options, info);
1379 Exception ex(
str::form(
_(
"Can't create %s"), base.c_str()) );
1383 if( ! PathInfo(base).userMayW() )
1385 Exception ex(
str::form(
_(
"Can't create cache at %s - no writing permissions."), base.c_str()) );
1388 Pathname solvfile = base /
"solv";
1391 repo::RepoType repokind = info.type();
1394 switch ( repokind.toEnum() )
1398 repokind = probeCache( productdatapath );
1404 MIL <<
"repo type is " << repokind << endl;
1406 switch ( repokind.toEnum() )
1414 scoped_ptr<MediaMounter> forPlainDirs;
1417 cmd.push_back( PathInfo(
"/usr/bin/repo2solv" ).isFile() ?
"repo2solv" :
"repo2solv.sh" );
1419 cmd.push_back(
"-o" );
1420 cmd.push_back( solvfile.asString() );
1421 cmd.push_back(
"-X" );
1426 forPlainDirs.reset(
new MediaMounter( info.url() ) );
1428 cmd.push_back(
"-R" );
1430 cmd.push_back( forPlainDirs->getPathName( info.path() ).c_str() );
1433 cmd.push_back( productdatapath.asString() );
1436 std::string errdetail;
1438 for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) {
1439 WAR <<
" " << output;
1440 errdetail += output;
1443 int ret = prog.close();
1447 ex.addHistory( str::Str() << prog.command() << endl << errdetail << prog.execError() );
1452 guard.resetDispose();
1461 setCacheStatus(info, raw_metadata_status);
1462 MIL <<
"Commit cache.." << endl;
1475 repo::RepoType RepoManager::Impl::probe(
const Url & url,
const Pathname & path )
const 1477 MIL <<
"going to probe the repo type at " << url <<
" (" << path <<
")" << endl;
1479 if ( url.getScheme() ==
"dir" && ! PathInfo( url.getPathName()/path ).isDir() )
1483 MIL <<
"Probed type NONE (not exists) at " << url <<
" (" << path <<
")" << endl;
1495 bool gotMediaException =
false;
1501 if ( access.doesFileExist(path/
"/repodata/repomd.xml") )
1503 MIL <<
"Probed type RPMMD at " << url <<
" (" << path <<
")" << endl;
1507 catch (
const media::MediaException &e )
1510 DBG <<
"problem checking for repodata/repomd.xml file" << endl;
1512 gotMediaException =
true;
1517 if ( access.doesFileExist(path/
"/content") )
1519 MIL <<
"Probed type YAST2 at " << url <<
" (" << path <<
")" << endl;
1523 catch (
const media::MediaException &e )
1526 DBG <<
"problem checking for content file" << endl;
1528 gotMediaException =
true;
1532 if ( ! ( url.schemeIsDownloading() || url.schemeIsPlugin() ) )
1534 MediaMounter media( url );
1535 if ( PathInfo(media.getPathName()/path).isDir() )
1538 MIL <<
"Probed type RPMPLAINDIR at " << url <<
" (" << path <<
")" << endl;
1543 catch (
const Exception &e )
1547 Exception enew(
str::form(
_(
"Unknown error reading from '%s'"), url.asString().c_str() ));
1552 if (gotMediaException)
1555 MIL <<
"Probed type NONE at " << url <<
" (" << path <<
")" << endl;
1564 repo::RepoType RepoManager::Impl::probeCache(
const Pathname & path_r )
const 1566 MIL <<
"going to probe the cached repo at " << path_r << endl;
1570 if ( PathInfo(path_r/
"/repodata/repomd.xml").isFile() )
1572 else if ( PathInfo(path_r/
"/content").isFile() )
1574 else if ( PathInfo(path_r).isDir() )
1577 MIL <<
"Probed cached type " << ret <<
" at " << path_r << endl;
1585 MIL <<
"Going to clean up garbage in cache dirs" << endl;
1587 ProgressData progress(300);
1588 progress.sendTo(progressrcv);
1591 std::list<Pathname> cachedirs;
1592 cachedirs.push_back(_options.repoRawCachePath);
1593 cachedirs.push_back(_options.repoPackagesCachePath);
1594 cachedirs.push_back(_options.repoSolvCachePath);
1596 for_( dir, cachedirs.begin(), cachedirs.end() )
1598 if ( PathInfo(*dir).isExist() )
1600 std::list<Pathname> entries;
1605 unsigned sdircount = entries.size();
1606 unsigned sdircurrent = 1;
1607 for_( subdir, entries.begin(), entries.end() )
1611 for_( r, repoBegin(), repoEnd() )
1612 if ( subdir->basename() == r->escaped_alias() )
1613 { found =
true;
break; }
1618 progress.set( progress.val() + sdircurrent * 100 / sdircount );
1623 progress.set( progress.val() + 100 );
1632 ProgressData progress(100);
1633 progress.sendTo(progressrcv);
1636 MIL <<
"Removing raw metadata cache for " << info.alias() << endl;
1647 Pathname solvfile = solv_path_for_repoinfo(_options, info) /
"solv";
1649 if ( ! PathInfo(solvfile).isExist() )
1659 if ( toolversion != LIBSOLV_TOOLVERSION )
1661 repo.eraseFromPool();
1662 ZYPP_THROW(Exception(str::Str() <<
"Solv-file was created by '"<<toolversion<<
"'-parser (want "<<LIBSOLV_TOOLVERSION<<
")."));
1665 catch (
const Exception & exp )
1668 MIL <<
"Try to handle exception by rebuilding the solv-file" << endl;
1669 cleanCache( info, progressrcv );
1670 buildCache( info, BuildIfNeeded, progressrcv );
1682 ProgressData progress(100);
1683 callback::SendReport<ProgressReport> report;
1684 progress.sendTo( ProgressReportAdaptor( progressrcv, report ) );
1685 progress.name(
str::form(
_(
"Adding repository '%s'"), info.label().c_str()));
1688 MIL <<
"Try adding repo " << info << endl;
1690 RepoInfo tosave = info;
1695 if ( _options.probe )
1697 DBG <<
"unknown repository type, probing" << endl;
1698 assert_urls(tosave);
1700 RepoType probedtype( probe( tosave.url(), info.path() ) );
1704 tosave.setType(probedtype);
1712 Pathname repofile = generateNonExistingName(
1713 _options.knownReposPath, generateFilename(tosave));
1715 MIL <<
"Saving repo in " << repofile << endl;
1717 std::ofstream file(repofile.c_str());
1724 tosave.dumpAsIniOn(file);
1725 tosave.setFilepath(repofile);
1726 tosave.setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ) );
1727 tosave.setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ) );
1731 RepoInfo & oinfo( const_cast<RepoInfo &>(info) );
1732 oinfo.setFilepath(repofile);
1733 oinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ) );
1734 oinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ) );
1736 reposManip().insert(tosave);
1741 UrlCredentialExtractor( _options.rootDir ).collect( tosave.baseUrls() );
1743 HistoryLog(_options.rootDir).addRepository(tosave);
1746 MIL <<
"done" << endl;
1753 for ( std::list<RepoInfo>::const_iterator it =
repos.begin();
1758 for_ ( kit, repoBegin(), repoEnd() )
1760 if ( (*it).alias() == (*kit).alias() )
1762 ERR <<
"To be added repo " << (*it).alias() <<
" conflicts with existing repo " << (*kit).alias() << endl;
1768 std::string filename = Pathname(url.getPathName()).basename();
1770 if ( filename == Pathname() )
1779 Pathname repofile = generateNonExistingName(_options.knownReposPath, filename);
1781 MIL <<
"Saving " <<
repos.size() <<
" repo" << (
repos.size() ?
"s" :
"" ) <<
" in " << repofile << endl;
1783 std::ofstream file(repofile.c_str());
1790 for ( std::list<RepoInfo>::iterator it =
repos.begin();
1794 MIL <<
"Saving " << (*it).alias() << endl;
1795 it->dumpAsIniOn(file);
1796 it->setFilepath(repofile);
1797 it->setMetadataPath( rawcache_path_for_repoinfo( _options, *it ) );
1798 it->setPackagesPath( packagescache_path_for_repoinfo( _options, *it ) );
1799 reposManip().insert(*it);
1801 HistoryLog(_options.rootDir).addRepository(*it);
1804 MIL <<
"done" << endl;
1811 ProgressData progress;
1812 callback::SendReport<ProgressReport> report;
1813 progress.sendTo( ProgressReportAdaptor( progressrcv, report ) );
1814 progress.name(
str::form(
_(
"Removing repository '%s'"), info.label().c_str()));
1816 MIL <<
"Going to delete repo " << info.alias() << endl;
1818 for_( it, repoBegin(), repoEnd() )
1823 if ( (!info.alias().empty()) && ( info.alias() != (*it).alias() ) )
1830 RepoInfo todelete = *it;
1831 if (todelete.filepath().empty())
1838 std::list<RepoInfo> filerepos = repositories_in_file(todelete.filepath());
1839 if ( filerepos.size() == 0
1840 ||(filerepos.size() == 1 && filerepos.front().alias() == todelete.alias() ) )
1844 if ( ! ( ret == 0 || ret == ENOENT ) )
1849 MIL << todelete.alias() <<
" successfully deleted." << endl;
1861 std::ofstream file(todelete.filepath().c_str());
1865 ZYPP_THROW( Exception(
str::form(
_(
"Can't open file '%s' for writing."), todelete.filepath().c_str() )));
1867 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1868 fit != filerepos.end();
1871 if ( (*fit).alias() != todelete.alias() )
1872 (*fit).dumpAsIniOn(file);
1876 CombinedProgressData cSubprogrcv(progress, 20);
1877 CombinedProgressData mSubprogrcv(progress, 40);
1878 CombinedProgressData pSubprogrcv(progress, 40);
1880 if ( isCached(todelete) )
1881 cleanCache( todelete, cSubprogrcv);
1883 cleanMetadata( todelete, mSubprogrcv );
1884 cleanPackages( todelete, pSubprogrcv,
true );
1885 reposManip().erase(todelete);
1886 MIL << todelete.alias() <<
" successfully deleted." << endl;
1887 HistoryLog(_options.rootDir).removeRepository(todelete);
1898 void RepoManager::Impl::modifyRepository(
const std::string & alias,
const RepoInfo & newinfo_r,
const ProgressData::ReceiverFnc & progressrcv )
1900 RepoInfo toedit = getRepositoryInfo(alias);
1901 RepoInfo newinfo( newinfo_r );
1904 if ( alias != newinfo.alias() && hasRepo( newinfo.alias() ) )
1909 if (toedit.filepath().empty())
1916 std::list<RepoInfo> filerepos = repositories_in_file(toedit.filepath());
1926 std::ofstream file(toedit.filepath().c_str());
1930 ZYPP_THROW( Exception(
str::form(
_(
"Can't open file '%s' for writing."), toedit.filepath().c_str() )));
1932 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1933 fit != filerepos.end();
1938 if ( (*fit).alias() != toedit.alias() )
1939 (*fit).dumpAsIniOn(file);
1941 newinfo.dumpAsIniOn(file);
1944 if ( toedit.enabled() && !newinfo.enabled() )
1947 const Pathname & solvidx = solv_path_for_repoinfo(_options, newinfo)/
"solv.idx";
1948 if ( PathInfo(solvidx).isExist() )
1952 newinfo.setFilepath(toedit.filepath());
1953 newinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, newinfo ) );
1954 newinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, newinfo ) );
1958 RepoInfo & oinfo( const_cast<RepoInfo &>(newinfo_r) );
1959 oinfo.setFilepath(toedit.filepath());
1960 oinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, newinfo ) );
1961 oinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, newinfo ) );
1963 reposManip().erase(toedit);
1964 reposManip().insert(newinfo);
1966 UrlCredentialExtractor( _options.rootDir ).collect( newinfo.baseUrls() );
1967 HistoryLog(_options.rootDir).modifyRepository(toedit, newinfo);
1968 MIL <<
"repo " << alias <<
" modified" << endl;
1974 RepoInfo RepoManager::Impl::getRepositoryInfo(
const std::string & alias,
const ProgressData::ReceiverFnc & progressrcv )
1976 RepoConstIterator it( findAlias( alias,
repos() ) );
1977 if ( it !=
repos().end() )
1980 info.setAlias( alias );
1985 RepoInfo RepoManager::Impl::getRepositoryInfo(
const Url & url,
const url::ViewOption & urlview,
const ProgressData::ReceiverFnc & progressrcv )
1987 for_( it, repoBegin(), repoEnd() )
1989 for_( urlit, (*it).baseUrlsBegin(), (*it).baseUrlsEnd() )
1991 if ( (*urlit).asString(urlview) == url.asString(urlview) )
1996 info.setBaseUrl( url );
2006 void RepoManager::Impl::addService(
const ServiceInfo & service )
2008 assert_alias( service );
2011 if ( hasService( service.alias() ) )
2016 ServiceInfo toSave( service );
2017 saveService( toSave );
2021 UrlCredentialExtractor( _options.rootDir ).collect( toSave.url() );
2023 MIL <<
"added service " << toSave.alias() << endl;
2028 void RepoManager::Impl::removeService(
const std::string & alias )
2030 MIL <<
"Going to delete service " << alias << endl;
2032 const ServiceInfo & service = getService( alias );
2034 Pathname location = service.filepath();
2035 if( location.empty() )
2041 parser::ServiceFileReader( location, ServiceCollector(tmpSet) );
2044 if ( tmpSet.size() == 1 )
2051 MIL << alias <<
" successfully deleted." << endl;
2057 std::ofstream file(location.c_str());
2064 for_(it, tmpSet.begin(), tmpSet.end())
2066 if( it->alias() != alias )
2067 it->dumpAsIniOn(file);
2070 MIL << alias <<
" successfully deleted from file " << location << endl;
2074 RepoCollector rcollector;
2075 getRepositoriesInService( alias,
2076 boost::make_function_output_iterator( bind( &RepoCollector::collect, &rcollector, _1 ) ) );
2078 for_(rit, rcollector.repos.begin(), rcollector.repos.end())
2079 removeRepository(*rit);
2084 void RepoManager::Impl::refreshServices(
const RefreshServiceOptions & options_r )
2088 ServiceSet services( serviceBegin(), serviceEnd() );
2089 for_( it, services.begin(), services.end() )
2091 if ( !it->enabled() )
2095 refreshService(*it, options_r);
2097 catch (
const repo::ServicePluginInformalException & e )
2102 void RepoManager::Impl::refreshService(
const std::string & alias,
const RefreshServiceOptions & options_r )
2104 ServiceInfo service( getService( alias ) );
2105 assert_alias( service );
2106 assert_url( service );
2107 MIL <<
"Going to refresh service '" << service.alias() <<
"', url: " << service.url() <<
", opts: " << options_r << endl;
2109 if ( service.ttl() && !( options_r.testFlag( RefreshService_forceRefresh) || options_r.testFlag( RefreshService_restoreStatus ) ) )
2112 Date lrf = service.lrf();
2118 if ( (lrf+=service.ttl()) > now )
2120 MIL <<
"Skip: '" << service.alias() <<
"' metadata valid until " << lrf << endl;
2125 WAR <<
"Force: '" << service.alias() <<
"' metadata last refresh in the future: " << lrf << endl;
2132 bool serviceModified =
false;
2139 repo::ServiceType type = probeService( service.url() );
2142 service.setProbedType( type );
2143 serviceModified =
true;
2148 std::string servicesTargetDistro = _options.servicesTargetDistro;
2149 if ( servicesTargetDistro.empty() )
2153 DBG <<
"ServicesTargetDistro: " << servicesTargetDistro << endl;
2157 RepoCollector collector(servicesTargetDistro);
2162 std::pair<DefaultIntegral<bool,false>, repo::ServicePluginInformalException> uglyHack;
2170 ServiceRepos( _options.rootDir, service, bind( &RepoCollector::collect, &collector, _1 ) );
2172 catch (
const repo::ServicePluginInformalException & e )
2175 uglyHack.first =
true;
2176 uglyHack.second = e;
2178 if ( service.ttl() != origTtl )
2180 if ( !service.ttl() )
2181 service.setLrf( Date() );
2182 serviceModified =
true;
2190 for_( it, collector.repos.begin(), collector.repos.end() )
2193 it->setAlias(
str::form(
"%s:%s", service.alias().c_str(), it->alias().c_str() ) );
2195 it->setService( service.alias() );
2198 newRepoStates[it->alias()] = *it;
2206 if ( !it->path().empty() )
2208 if ( it->path() !=
"/" )
2213 if ( it->baseUrlsEmpty() )
2215 Url url( service.rawUrl() );
2216 if ( !path.empty() )
2217 url.setPathName( url.getPathName() / path );
2218 it->setBaseUrl( std::move(url) );
2220 else if ( !path.empty() )
2223 for ( Url & url : urls )
2225 url.setPathName( url.getPathName() / path );
2227 it->setBaseUrls( std::move(urls) );
2234 RepoInfoList oldRepos;
2235 getRepositoriesInService( service.alias(), std::back_inserter( oldRepos ) );
2239 for_( oldRepo, oldRepos.begin(), oldRepos.end() )
2241 if ( ! foundAliasIn( oldRepo->alias(), collector.repos ) )
2243 if ( oldRepo->enabled() )
2246 const auto & last = service.repoStates().find( oldRepo->alias() );
2247 if ( last != service.repoStates().end() && ! last->second.enabled )
2249 DBG <<
"Service removes user enabled repo " << oldRepo->alias() << endl;
2250 service.addRepoToEnable( oldRepo->alias() );
2251 serviceModified =
true;
2254 DBG <<
"Service removes enabled repo " << oldRepo->alias() << endl;
2257 DBG <<
"Service removes disabled repo " << oldRepo->alias() << endl;
2259 removeRepository( *oldRepo );
2265 UrlCredentialExtractor urlCredentialExtractor( _options.rootDir );
2266 for_( it, collector.repos.begin(), collector.repos.end() )
2272 TriBool toBeEnabled( indeterminate );
2273 DBG <<
"Service request to " << (it->enabled()?
"enable":
"disable") <<
" service repo " << it->alias() << endl;
2275 if ( options_r.testFlag( RefreshService_restoreStatus ) )
2277 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() << endl;
2282 service.delRepoToEnable( it->alias() );
2287 if ( service.repoToEnableFind( it->alias() ) )
2289 DBG <<
"User request to enable service repo " << it->alias() << endl;
2294 service.delRepoToEnable( it->alias() );
2295 serviceModified =
true;
2297 else if ( service.repoToDisableFind( it->alias() ) )
2299 DBG <<
"User request to disable service repo " << it->alias() << endl;
2300 toBeEnabled =
false;
2304 RepoInfoList::iterator oldRepo( findAlias( it->alias(), oldRepos ) );
2305 if ( oldRepo == oldRepos.end() )
2310 if ( ! indeterminate(toBeEnabled) )
2311 it->setEnabled( (
bool ) toBeEnabled );
2313 DBG <<
"Service adds repo " << it->alias() <<
" " << (it->enabled()?
"enabled":
"disabled") << endl;
2314 addRepository( *it );
2319 bool oldRepoModified =
false;
2321 if ( indeterminate(toBeEnabled) )
2325 if ( oldRepo->enabled() == it->enabled() )
2326 toBeEnabled = it->enabled();
2327 else if (options_r.testFlag( RefreshService_restoreStatus ) )
2329 toBeEnabled = it->enabled();
2330 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() <<
" forces " << (toBeEnabled?
"enabled":
"disabled") << endl;
2334 const auto & last = service.repoStates().find( oldRepo->alias() );
2335 if ( last == service.repoStates().end() || last->second.enabled != it->enabled() )
2336 toBeEnabled = it->enabled();
2339 toBeEnabled = oldRepo->enabled();
2340 DBG <<
"User modified service repo " << it->alias() <<
" may stay " << (toBeEnabled?
"enabled":
"disabled") << endl;
2346 if ( toBeEnabled == oldRepo->enabled() )
2348 DBG <<
"Service repo " << it->alias() <<
" stays " << (oldRepo->enabled()?
"enabled":
"disabled") << endl;
2350 else if ( toBeEnabled )
2352 DBG <<
"Service repo " << it->alias() <<
" gets enabled" << endl;
2353 oldRepo->setEnabled(
true );
2354 oldRepoModified =
true;
2358 DBG <<
"Service repo " << it->alias() <<
" gets disabled" << endl;
2359 oldRepo->setEnabled(
false );
2360 oldRepoModified =
true;
2366 if ( oldRepo->rawName() != it->rawName() )
2368 DBG <<
"Service repo " << it->alias() <<
" gets new NAME " << it->rawName() << endl;
2369 oldRepo->setName( it->rawName() );
2370 oldRepoModified =
true;
2374 if ( oldRepo->autorefresh() != it->autorefresh() )
2376 DBG <<
"Service repo " << it->alias() <<
" gets new AUTOREFRESH " << it->autorefresh() << endl;
2377 oldRepo->setAutorefresh( it->autorefresh() );
2378 oldRepoModified =
true;
2382 if ( oldRepo->priority() != it->priority() )
2384 DBG <<
"Service repo " << it->alias() <<
" gets new PRIORITY " << it->priority() << endl;
2385 oldRepo->setPriority( it->priority() );
2386 oldRepoModified =
true;
2392 urlCredentialExtractor.extract( newUrls );
2393 if ( oldRepo->rawBaseUrls() != newUrls )
2395 DBG <<
"Service repo " << it->alias() <<
" gets new URLs " << newUrls << endl;
2396 oldRepo->setBaseUrls( std::move(newUrls) );
2397 oldRepoModified =
true;
2407 oldRepo->getRawGpgChecks( ogpg[0], ogpg[1], ogpg[2] );
2408 it-> getRawGpgChecks( ngpg[0], ngpg[1], ngpg[2] );
2409 #define Z_CHKGPG(I,N) \ 2410 if ( ! sameTriboolState( ogpg[I], ngpg[I] ) ) \ 2412 DBG << "Service repo " << it->alias() << " gets new "#N"Check " << ngpg[I] << endl; \ 2413 oldRepo->set##N##Check( ngpg[I] ); \ 2414 oldRepoModified = true; \ 2423 if ( oldRepoModified )
2425 modifyRepository( oldRepo->alias(), *oldRepo );
2431 if ( ! service.reposToDisableEmpty() )
2433 service.clearReposToDisable();
2434 serviceModified =
true;
2438 if ( service.repoStates() != newRepoStates )
2440 service.setRepoStates( std::move(newRepoStates) );
2441 serviceModified =
true;
2448 if ( service.ttl() )
2451 serviceModified =
true;
2454 if ( serviceModified )
2457 modifyService( service.alias(), service );
2461 if ( uglyHack.first )
2463 throw( uglyHack.second );
2469 void RepoManager::Impl::modifyService(
const std::string & oldAlias,
const ServiceInfo & newService )
2471 MIL <<
"Going to modify service " << oldAlias << endl;
2475 ServiceInfo service(newService);
2482 const ServiceInfo & oldService = getService(oldAlias);
2484 Pathname location = oldService.filepath();
2485 if( location.empty() )
2492 parser::ServiceFileReader( location, ServiceCollector(tmpSet) );
2495 std::ofstream file(location.c_str());
2496 for_(it, tmpSet.begin(), tmpSet.end())
2498 if( *it != oldAlias )
2499 it->dumpAsIniOn(file);
2501 service.dumpAsIniOn(file);
2503 service.setFilepath(location);
2508 UrlCredentialExtractor( _options.rootDir ).collect( service.url() );
2512 if ( oldAlias != service.alias()
2513 || oldService.enabled() != service.enabled() )
2515 std::vector<RepoInfo> toModify;
2516 getRepositoriesInService(oldAlias, std::back_inserter(toModify));
2517 for_( it, toModify.begin(), toModify.end() )
2519 if ( oldService.enabled() != service.enabled() )
2521 if ( service.enabled() )
2524 const auto & last = service.repoStates().find( it->alias() );
2525 if ( last != service.repoStates().end() )
2526 it->setEnabled( last->second.enabled );
2529 it->setEnabled(
false );
2532 if ( oldAlias != service.alias() )
2533 it->setService(service.alias());
2535 modifyRepository(it->alias(), *it);
2544 repo::ServiceType RepoManager::Impl::probeService(
const Url & url )
const 2549 if ( access.doesFileExist(
"/repo/repoindex.xml") )
2552 catch (
const media::MediaException &e )
2560 catch (
const Exception &e )
2564 Exception enew(
str::form(
_(
"Unknown error reading from '%s'"), url.asString().c_str() ));
2577 MIL <<
"GeoIp disabled via ZConfig, not refreshing the GeoIP information." << std::endl;
2581 std::vector<std::string> hosts;
2582 for (
const auto &baseUrl : urls ) {
2583 const auto &host = baseUrl.getHost();
2585 hosts.push_back( host );
2590 if ( hosts.empty() ) {
2591 MIL <<
"No configured geoip URL found, not updating geoip data" << std::endl;
2598 MIL <<
"Unable to create cache directory for GeoIP." << std::endl;
2602 if ( !PathInfo(geoIPCache).userMayRWX() ) {
2603 MIL <<
"No access rights for the GeoIP cache directory." << std::endl;
2612 PathInfo pi( dir/entry.name );
2613 auto age = std::chrono::system_clock::now() - std::chrono::system_clock::from_time_t( pi.mtime() );
2614 if ( age < std::chrono::hours(24) )
2617 MIL <<
"Removing GeoIP file for " << entry.name <<
" since it's older than 24hrs." << std::endl;
2623 std::for_each( hosts.begin(), hosts.end(), [ & ](
const std::string &hostname ) {
2627 MIL <<
"Skipping GeoIP request for " << hostname <<
" since a valid cache entry exists." << std::endl;
2631 MIL <<
"Query GeoIP for " << hostname << std::endl;
2642 MIL <<
"Ignoring invalid GeoIP hostname: " << hostname << std::endl;
2654 MIL <<
"Failed to query GeoIP from hostname: " << hostname << std::endl;
2657 if ( !file->
empty() ) {
2659 constexpr
auto writeHostToFile = [](
const Pathname &fName,
const std::string &host ){
2661 out.open( fName.asString(), std::ios_base::trunc );
2662 if ( out.is_open() ) {
2663 out << host << std::endl;
2665 MIL <<
"Failed to create/open GeoIP cache file " << fName << std::endl;
2669 std::string geoipMirror;
2672 if ( reader.seekToNode( 1,
"host" ) ) {
2673 const auto &
str = reader.nodeText().asString();
2681 MIL <<
"Storing geoIP redirection: " << hostname <<
" -> " <<
str << std::endl;
2686 MIL <<
"No host entry or empty file returned for GeoIP, remembering for 24hrs" << std::endl;
2690 MIL <<
"Empty or invalid GeoIP file, not requesting again for 24hrs" << std::endl;
2693 writeHostToFile( geoIPCache / hostname, geoipMirror );
2699 MIL <<
"Failed to query GeoIP data." << std::endl;
2710 : _pimpl( new
Impl(opt) )
2717 {
return _pimpl->repoEmpty(); }
2720 {
return _pimpl->repoSize(); }
2723 {
return _pimpl->repoBegin(); }
2726 {
return _pimpl->repoEnd(); }
2729 {
return _pimpl->getRepo( alias ); }
2732 {
return _pimpl->hasRepo( alias ); }
2742 std::string host( url_r.
getHost() );
2743 if ( ! host.empty() )
2755 {
return _pimpl->metadataStatus( info ); }
2758 {
return _pimpl->checkIfToRefreshMetadata( info, url, policy ); }
2761 {
return _pimpl->metadataPath( info ); }
2764 {
return _pimpl->packagesPath( info ); }
2767 {
return _pimpl->refreshMetadata( info, policy, progressrcv ); }
2770 {
return _pimpl->cleanMetadata( info, progressrcv ); }
2773 {
return _pimpl->cleanPackages( info, progressrcv ); }
2776 {
return _pimpl->cacheStatus( info ); }
2779 {
return _pimpl->buildCache( info, policy, progressrcv ); }
2782 {
return _pimpl->cleanCache( info, progressrcv ); }
2785 {
return _pimpl->isCached( info ); }
2788 {
return _pimpl->loadFromCache( info, progressrcv ); }
2791 {
return _pimpl->cleanCacheDirGarbage( progressrcv ); }
2794 {
return _pimpl->probe( url, path ); }
2797 {
return _pimpl->probe( url ); }
2800 {
return _pimpl->addRepository( info, progressrcv ); }
2803 {
return _pimpl->addRepositories( url, progressrcv ); }
2806 {
return _pimpl->removeRepository( info, progressrcv ); }
2809 {
return _pimpl->modifyRepository( alias, newinfo, progressrcv ); }
2812 {
return _pimpl->getRepositoryInfo( alias, progressrcv ); }
2815 {
return _pimpl->getRepositoryInfo( url, urlview, progressrcv ); }
2818 {
return _pimpl->serviceEmpty(); }
2821 {
return _pimpl->serviceSize(); }
2824 {
return _pimpl->serviceBegin(); }
2827 {
return _pimpl->serviceEnd(); }
2830 {
return _pimpl->getService( alias ); }
2833 {
return _pimpl->hasService( alias ); }
2836 {
return _pimpl->probeService( url ); }
2839 {
return _pimpl->addService( alias, url ); }
2842 {
return _pimpl->addService( service ); }
2845 {
return _pimpl->removeService( alias ); }
2848 {
return _pimpl->removeService( service ); }
2851 {
return _pimpl->refreshServices( options_r ); }
2854 {
return _pimpl->refreshService( alias, options_r ); }
2857 {
return _pimpl->refreshService( service, options_r ); }
2860 {
return _pimpl->modifyService( oldAlias, service ); }
2863 {
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
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