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() 78 const char * env = getenv(
"ZYPP_PLUGIN_APPDATA_FORCE_COLLECT");
108 class UrlCredentialExtractor
111 UrlCredentialExtractor( Pathname & root_r )
115 ~UrlCredentialExtractor()
119 bool collect(
const Url & url_r )
121 bool ret = url_r.hasCredentialsInAuthority();
125 _cmPtr->addUserCred( url_r );
130 template<
class TContainer>
131 bool collect(
const TContainer & urls_r )
132 {
bool ret =
false;
for (
const Url & url : urls_r ) {
if ( collect( url ) && !ret ) ret =
true; }
return ret; }
135 bool extract( Url & url_r )
137 bool ret = collect( url_r );
139 url_r.setPassword( std::string() );
143 template<
class TContainer>
144 bool extract( TContainer & urls_r )
145 {
bool ret =
false;
for ( Url & url : urls_r ) {
if ( extract( url ) && !ret ) ret =
true; }
return ret; }
149 scoped_ptr<media::CredentialManager>
_cmPtr;
164 MediaMounter(
const Url & url_r )
166 media::MediaManager mediamanager;
167 _mid = mediamanager.open( url_r );
168 mediamanager.attach(
_mid );
174 media::MediaManager mediamanager;
175 mediamanager.release(
_mid );
176 mediamanager.close(
_mid );
183 Pathname getPathName(
const Pathname & path_r = Pathname() )
const 185 media::MediaManager mediamanager;
186 return mediamanager.localPath(
_mid, path_r );
195 template <
class Iterator>
196 inline bool foundAliasIn(
const std::string & alias_r, Iterator begin_r, Iterator end_r )
198 for_( it, begin_r, end_r )
199 if ( it->alias() == alias_r )
204 template <
class Container>
205 inline bool foundAliasIn(
const std::string & alias_r,
const Container & cont_r )
206 {
return foundAliasIn( alias_r, cont_r.begin(), cont_r.end() ); }
209 template <
class Iterator>
210 inline Iterator findAlias(
const std::string & alias_r, Iterator begin_r, Iterator end_r )
212 for_( it, begin_r, end_r )
213 if ( it->alias() == alias_r )
218 template <
class Container>
219 inline typename Container::iterator findAlias(
const std::string & alias_r, Container & cont_r )
220 {
return findAlias( alias_r, cont_r.begin(), cont_r.end() ); }
222 template <
class Container>
223 inline typename Container::const_iterator findAlias(
const std::string & alias_r,
const Container & cont_r )
224 {
return findAlias( alias_r, cont_r.begin(), cont_r.end() ); }
228 inline std::string filenameFromAlias(
const std::string & alias_r,
const std::string & stem_r )
230 std::string filename( alias_r );
234 filename = Pathname(filename).extend(
"."+stem_r).asString();
235 MIL <<
"generating filename for " << stem_r <<
" [" << alias_r <<
"] : '" << filename <<
"'" << endl;
259 RepoCollector(
const std::string & targetDistro_)
263 bool collect(
const RepoInfo &repo )
267 && !repo.targetDistribution().empty()
271 <<
"Skipping repository meant for '" << repo.targetDistribution()
272 <<
"' distribution (current distro is '" 278 repos.push_back(repo);
292 std::list<RepoInfo> repositories_in_file(
const Pathname & file )
294 MIL <<
"repo file: " << file << endl;
295 RepoCollector collector;
296 parser::RepoFileReader parser( file, bind( &RepoCollector::collect, &collector, _1 ) );
297 return std::move(collector.repos);
310 std::list<RepoInfo> repositories_in_dir(
const Pathname &dir )
312 MIL <<
"directory " << dir << endl;
313 std::list<RepoInfo>
repos;
314 bool nonroot( geteuid() != 0 );
315 if ( nonroot && ! PathInfo(dir).userMayRX() )
317 JobReport::warning( str::Format(
_(
"Cannot read repo directory '%1%': Permission denied")) % dir );
321 std::list<Pathname> entries;
328 str::regex allowedRepoExt(
"^\\.repo(_[0-9]+)?$");
329 for ( std::list<Pathname>::const_iterator it = entries.begin(); it != entries.end(); ++it )
333 if ( nonroot && ! PathInfo(*it).userMayR() )
335 JobReport::warning( str::Format(
_(
"Cannot read repo file '%1%': Permission denied")) % *it );
339 const std::list<RepoInfo> & tmp( repositories_in_file( *it ) );
340 repos.insert(
repos.end(), tmp.begin(), tmp.end() );
350 inline void assert_alias(
const RepoInfo & info )
352 if ( info.alias().empty() )
356 if ( info.alias()[0] ==
'.')
358 info,
_(
"Repository alias cannot start with dot.")));
361 inline void assert_alias(
const ServiceInfo & info )
363 if ( info.alias().empty() )
367 if ( info.alias()[0] ==
'.')
369 info,
_(
"Service alias cannot start with dot.")));
374 inline void assert_urls(
const RepoInfo & info )
376 if ( info.baseUrlsEmpty() )
380 inline void assert_url(
const ServiceInfo & info )
382 if ( ! info.url().isValid() )
392 inline bool isTmpRepo(
const RepoInfo & info_r )
393 {
return( info_r.filepath().empty() && info_r.usesAutoMethadataPaths() ); }
401 inline Pathname rawcache_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
404 return isTmpRepo( info ) ? info.metadataPath() : opt.repoRawCachePath / info.escaped_alias();
415 inline Pathname rawproductdata_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
416 {
return rawcache_path_for_repoinfo( opt, info ) / info.path(); }
421 inline Pathname packagescache_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
424 return isTmpRepo( info ) ? info.packagesPath() : opt.repoPackagesCachePath / info.escaped_alias();
430 inline Pathname solv_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
433 return isTmpRepo( info ) ? info.metadataPath().dirname() /
"%SLV%" : opt.repoSolvCachePath / info.escaped_alias();
439 class ServiceCollector
442 typedef std::set<ServiceInfo> ServiceSet;
444 ServiceCollector( ServiceSet & services_r )
448 bool operator()(
const ServiceInfo & service_r )
const 460 inline bool autoPruneInDir(
const Pathname & path_r )
461 {
return not PathInfo(path_r/
".no_auto_prune").isExist(); }
470 DBG <<
"reading repo file " << repo_file <<
", local path: " << local << endl;
472 return repositories_in_file(local);
511 #define OUTS(X) str << " " #X "\t" << obj.X << endl 512 str <<
"RepoManagerOptions (" << obj.
rootDir <<
") {" << endl;
513 OUTS( repoRawCachePath );
514 OUTS( repoSolvCachePath );
515 OUTS( repoPackagesCachePath );
516 OUTS( knownReposPath );
517 OUTS( knownServicesPath );
534 , _pluginRepoverification( _options.pluginsPath/
"repoverification", _options.rootDir )
536 init_knownServices();
537 init_knownRepositories();
544 && geteuid() == 0 && ( _options.rootDir.empty() || _options.rootDir ==
"/" ) )
547 std::list<Pathname> entries;
549 if ( ! entries.empty() )
552 cmd.push_back(
"<" );
553 cmd.push_back(
">" );
554 cmd.push_back(
"PROGRAM" );
555 for (
const auto & rinfo :
repos() )
557 if ( ! rinfo.enabled() )
559 cmd.push_back(
"-R" );
560 cmd.push_back( rinfo.alias() );
561 cmd.push_back(
"-t" );
562 cmd.push_back( rinfo.type().asString() );
563 cmd.push_back(
"-p" );
564 cmd.push_back( (rinfo.metadataPath()/rinfo.path()).
asString() );
567 for_( it, entries.begin(), entries.end() )
590 bool hasRepo(
const std::string & alias )
const 591 {
return foundAliasIn( alias,
repos() ); }
601 {
return rawcache_path_for_repoinfo( _options, info ); }
604 {
return packagescache_path_for_repoinfo( _options, info ); }
608 RefreshCheckStatus checkIfToRefreshMetadata(
const RepoInfo & info,
const Url & url, RawMetadataRefreshPolicy policy );
626 {
return PathInfo(solv_path_for_repoinfo( _options, info ) /
"solv").
isExist(); }
651 {
return foundAliasIn( alias,
_services ); }
664 void removeService(
const std::string & alias );
666 { removeService( service.
alias() ); }
668 void refreshServices(
const RefreshServiceOptions & options_r );
670 void refreshService(
const std::string & alias,
const RefreshServiceOptions & options_r );
672 { refreshService( service.
alias(), options_r ); }
674 void modifyService(
const std::string & oldAlias,
const ServiceInfo & newService );
683 Pathname generateNonExistingName(
const Pathname & dir,
const std::string & basefilename )
const;
686 {
return filenameFromAlias( info.
alias(),
"repo" ); }
689 {
return filenameFromAlias( info.
alias(),
"service" ); }
693 Pathname base = solv_path_for_repoinfo( _options, info );
698 void touchIndexFile(
const RepoInfo & info );
700 template<
typename OutputIterator>
705 boost::make_filter_iterator( filter,
repos().end(),
repos().end() ),
710 void init_knownServices();
711 void init_knownRepositories();
726 friend Impl * rwcowClone<Impl>(
const Impl * rhs );
729 {
return new Impl( *
this ); }
735 {
return str <<
"RepoManager::Impl"; }
739 void RepoManager::Impl::saveService( ServiceInfo & service )
const 742 Pathname servfile = generateNonExistingName( _options.knownServicesPath,
743 generateFilename( service ) );
744 service.setFilepath( servfile );
746 MIL <<
"saving service in " << servfile << endl;
748 std::ofstream file( servfile.c_str() );
754 service.dumpAsIniOn( file );
755 MIL <<
"done" << endl;
773 Pathname RepoManager::Impl::generateNonExistingName(
const Pathname & dir,
774 const std::string & basefilename )
const 776 std::string final_filename = basefilename;
778 while ( PathInfo(dir + final_filename).isExist() )
783 return dir + Pathname(final_filename);
788 void RepoManager::Impl::init_knownServices()
790 Pathname dir = _options.knownServicesPath;
791 std::list<Pathname> entries;
792 if (PathInfo(dir).isExist())
801 for_(it, entries.begin(), entries.end() )
803 parser::ServiceFileReader(*it, ServiceCollector(
_services));
807 repo::PluginServices(_options.pluginsPath/
"services", ServiceCollector(
_services));
817 inline void cleanupNonRepoMetadtaFolders(
const Pathname & cachePath_r,
818 const Pathname & defaultCachePath_r,
819 const std::list<std::string> & repoEscAliases_r )
821 if ( cachePath_r != defaultCachePath_r )
824 std::list<std::string> entries;
828 std::set<std::string> oldfiles;
829 set_difference( entries.begin(), entries.end(), repoEscAliases_r.begin(), repoEscAliases_r.end(),
830 std::inserter( oldfiles, oldfiles.end() ) );
836 for (
const std::string & old : oldfiles )
840 pi( cachePath_r/old );
850 void RepoManager::Impl::init_knownRepositories()
852 MIL <<
"start construct known repos" << endl;
854 if ( PathInfo(_options.knownReposPath).isExist() )
856 std::list<std::string> repoEscAliases;
857 std::list<RepoInfo> orphanedRepos;
858 for ( RepoInfo & repoInfo : repositories_in_dir(_options.knownReposPath) )
861 repoInfo.setMetadataPath( rawcache_path_for_repoinfo(_options, repoInfo) );
863 repoInfo.setPackagesPath( packagescache_path_for_repoinfo(_options, repoInfo) );
865 _reposX.insert( repoInfo );
868 const std::string & serviceAlias( repoInfo.service() );
869 if ( ! ( serviceAlias.empty() || hasService( serviceAlias ) ) )
871 WAR <<
"Schedule orphaned service repo for deletion: " << repoInfo << endl;
872 orphanedRepos.push_back( repoInfo );
876 repoEscAliases.push_back(repoInfo.escaped_alias());
880 if ( ! orphanedRepos.empty() )
882 for (
const auto & repoInfo : orphanedRepos )
884 MIL <<
"Delete orphaned service repo " << repoInfo.alias() << endl;
888 JobReport::warning( str::Format(
_(
"Unknown service '%1%': Removing orphaned service repository '%2%'"))
890 % repoInfo.alias() );
892 removeRepository( repoInfo );
894 catch (
const Exception & caugth )
906 repoEscAliases.sort();
907 cleanupNonRepoMetadtaFolders( _options.repoRawCachePath,
910 cleanupNonRepoMetadtaFolders( _options.repoSolvCachePath,
914 if ( autoPruneInDir( _options.repoPackagesCachePath ) )
915 cleanupNonRepoMetadtaFolders( _options.repoPackagesCachePath,
919 MIL <<
"end construct known repos" << endl;
924 RepoStatus RepoManager::Impl::metadataStatus(
const RepoInfo & info )
const 926 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
927 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
932 repokind = probeCache( productdatapath );
939 switch ( repokind.
toEnum() )
942 status = RepoStatus( productdatapath/
"repodata/repomd.xml");
943 if ( info.requireStatusWithMediaFile() )
944 status = status && RepoStatus( mediarootpath/
"media.1/media" );
948 status = RepoStatus( productdatapath/
"content" ) && RepoStatus( mediarootpath/
"media.1/media" );
962 if ( ! status.empty() )
963 status = status && RepoStatus( info );
969 void RepoManager::Impl::touchIndexFile(
const RepoInfo & info )
971 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
976 repokind = probeCache( productdatapath );
982 switch ( repokind.
toEnum() )
985 p = Pathname(productdatapath +
"/repodata/repomd.xml");
989 p = Pathname(productdatapath +
"/content");
993 p = Pathname(productdatapath +
"/cookie");
1006 RepoManager::RefreshCheckStatus RepoManager::Impl::checkIfToRefreshMetadata(
const RepoInfo & info,
const Url & url, RawMetadataRefreshPolicy policy )
1011 MIL <<
"Check if to refresh repo " << info.alias() <<
" at " << url <<
" (" << info.type() <<
")" << endl;
1013 refreshGeoIPData( { url } );
1016 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1018 RepoStatus oldstatus = metadataStatus( info );
1020 if ( oldstatus.empty() )
1022 MIL <<
"No cached metadata, going to refresh" << endl;
1023 return REFRESH_NEEDED;
1026 if ( url.schemeIsVolatile() )
1028 MIL <<
"Never refresh CD/DVD" << endl;
1029 return REPO_UP_TO_DATE;
1032 if ( policy == RefreshForced )
1034 MIL <<
"Forced refresh!" << endl;
1035 return REFRESH_NEEDED;
1038 if ( url.schemeIsLocal() )
1040 policy = RefreshIfNeededIgnoreDelay;
1044 if ( policy != RefreshIfNeededIgnoreDelay )
1049 RepoStatus cachestatus = cacheStatus( info );
1051 if ( oldstatus == cachestatus )
1059 WAR <<
"Repository '" << info.alias() <<
"' was refreshed in the future!" << endl;
1063 MIL <<
"Repository '" << info.alias()
1064 <<
"' has been refreshed less than repo.refresh.delay (" 1066 <<
") minutes ago. Advising to skip refresh" << endl;
1067 return REPO_CHECK_DELAYED;
1072 MIL <<
"Metadata and solv cache don't match. Check data on server..." << endl;
1076 repo::RepoType repokind = info.type();
1079 repokind = probe( url, info.path() );
1082 RepoStatus newstatus;
1083 switch ( repokind.toEnum() )
1100 newstatus = RepoStatus( info ) && RepoStatus( MediaMounter(url).getPathName(info.path()) );
1110 if ( oldstatus == newstatus )
1112 MIL <<
"repo has not changed" << endl;
1113 touchIndexFile( info );
1114 return REPO_UP_TO_DATE;
1118 MIL <<
"repo has changed, going to refresh" << endl;
1119 return REFRESH_NEEDED;
1122 catch (
const Exception &e )
1125 ERR <<
"refresh check failed for " << url << endl;
1129 return REFRESH_NEEDED;
1133 void RepoManager::Impl::refreshMetadata(
const RepoInfo & info, RawMetadataRefreshPolicy policy,
const ProgressData::ReceiverFnc & progress )
1139 refreshGeoIPData( info.baseUrls() );
1142 RepoException rexception( info,
PL_(
"Valid metadata not found at specified URL",
1143 "Valid metadata not found at specified URLs",
1144 info.baseUrlsSize() ) );
1147 media::ScopedDisableMediaChangeReport guard( info.baseUrlsSize() > 1 );
1157 if (checkIfToRefreshMetadata(info, url, policy)!=REFRESH_NEEDED)
1160 MIL <<
"Going to refresh metadata from " << url << endl;
1165 repo::RepoType repokind = info.type();
1167 repo::RepoType probed = probe( *it, info.path() );
1168 if ( repokind != probed )
1172 for_( it, repoBegin(), repoEnd() )
1174 if ( info.alias() == (*it).alias() )
1176 RepoInfo modifiedrepo = *it;
1177 modifiedrepo.setType( repokind );
1184 info.setProbedType( repokind );
1191 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1194 Exception ex(
str::form(
_(
"Can't create %s"), mediarootpath.c_str()) );
1200 if( tmpdir.path().empty() )
1202 Exception ex(
_(
"Can't create metadata cache directory."));
1210 shared_ptr<repo::Downloader> downloader_ptr;
1212 MIL <<
"Creating downloader for [ " << info.alias() <<
" ]" << endl;
1216 if ( _pluginRepoverification.checkIfNeeded() )
1217 downloader_ptr->setPluginRepoverification( _pluginRepoverification );
1228 for_( it, repoBegin(), repoEnd() )
1230 Pathname cachepath(rawcache_path_for_repoinfo( _options, *it ));
1231 if ( PathInfo(cachepath).isExist() )
1232 downloader_ptr->addCachePath(cachepath);
1235 downloader_ptr->download( media, tmpdir.path() );
1240 MediaMounter media( url );
1241 RepoStatus newstatus = RepoStatus( media.getPathName( info.path() ) );
1243 Pathname productpath( tmpdir.path() / info.path() );
1245 newstatus.saveToCookieFile( productpath/
"cookie" );
1255 if ( ! isTmpRepo( info ) )
1261 catch (
const Exception &e )
1264 ERR <<
"Trying another url..." << endl;
1269 if (it == info.baseUrlsBegin())
1270 rexception.remember(e);
1272 rexception.addHistory( e.asUserString() );
1276 ERR <<
"No more urls..." << endl;
1284 ProgressData progress(100);
1285 progress.sendTo(progressfnc);
1292 void RepoManager::Impl::cleanPackages(
const RepoInfo & info,
const ProgressData::ReceiverFnc & progressfnc,
bool isAutoClean_r )
1294 ProgressData progress(100);
1295 progress.sendTo(progressfnc);
1298 const Pathname & rpc { packagescache_path_for_repoinfo(_options, info) };
1299 if ( not isAutoClean_r || autoPruneInDir( rpc.dirname() ) )
1305 void RepoManager::Impl::buildCache(
const RepoInfo & info, CacheBuildPolicy policy,
const ProgressData::ReceiverFnc & progressrcv )
1308 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1309 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
1313 Exception ex(
str::form(
_(
"Can't create %s"), _options.repoCachePath.c_str()) );
1316 RepoStatus raw_metadata_status = metadataStatus(info);
1317 if ( raw_metadata_status.empty() )
1322 refreshMetadata(info, RefreshIfNeeded, progressrcv );
1323 raw_metadata_status = metadataStatus(info);
1326 bool needs_cleaning =
false;
1327 if ( isCached( info ) )
1329 MIL << info.alias() <<
" is already cached." << endl;
1330 RepoStatus cache_status = cacheStatus(info);
1332 if ( cache_status == raw_metadata_status )
1334 MIL << info.alias() <<
" cache is up to date with metadata." << endl;
1335 if ( policy == BuildIfNeeded )
1338 const Pathname & base = solv_path_for_repoinfo( _options, info);
1339 if ( ! PathInfo(base/
"solv.idx").isExist() )
1345 MIL << info.alias() <<
" cache rebuild is forced" << endl;
1349 needs_cleaning =
true;
1352 ProgressData progress(100);
1353 callback::SendReport<ProgressReport> report;
1354 progress.sendTo( ProgressReportAdaptor( progressrcv, report ) );
1355 progress.name(
str::form(
_(
"Building repository '%s' cache"), info.label().c_str()));
1363 MIL << info.alias() <<
" building cache..." << info.type() << endl;
1365 Pathname base = solv_path_for_repoinfo( _options, info);
1369 Exception ex(
str::form(
_(
"Can't create %s"), base.c_str()) );
1373 if( ! PathInfo(base).userMayW() )
1375 Exception ex(
str::form(
_(
"Can't create cache at %s - no writing permissions."), base.c_str()) );
1378 Pathname solvfile = base /
"solv";
1381 repo::RepoType repokind = info.type();
1384 switch ( repokind.toEnum() )
1388 repokind = probeCache( productdatapath );
1394 MIL <<
"repo type is " << repokind << endl;
1396 switch ( repokind.toEnum() )
1404 scoped_ptr<MediaMounter> forPlainDirs;
1407 cmd.push_back( PathInfo(
"/usr/bin/repo2solv" ).isFile() ?
"repo2solv" :
"repo2solv.sh" );
1409 cmd.push_back(
"-o" );
1410 cmd.push_back( solvfile.asString() );
1411 cmd.push_back(
"-X" );
1416 forPlainDirs.reset(
new MediaMounter( info.url() ) );
1418 cmd.push_back(
"-R" );
1420 cmd.push_back( forPlainDirs->getPathName( info.path() ).c_str() );
1423 cmd.push_back( productdatapath.asString() );
1426 std::string errdetail;
1428 for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) {
1429 WAR <<
" " << output;
1430 errdetail += output;
1433 int ret = prog.close();
1437 ex.addHistory( str::Str() << prog.command() << endl << errdetail << prog.execError() );
1442 guard.resetDispose();
1451 setCacheStatus(info, raw_metadata_status);
1452 MIL <<
"Commit cache.." << endl;
1465 repo::RepoType RepoManager::Impl::probe(
const Url & url,
const Pathname & path )
const 1467 MIL <<
"going to probe the repo type at " << url <<
" (" << path <<
")" << endl;
1469 if ( url.getScheme() ==
"dir" && ! PathInfo( url.getPathName()/path ).isDir() )
1473 MIL <<
"Probed type NONE (not exists) at " << url <<
" (" << path <<
")" << endl;
1485 bool gotMediaException =
false;
1491 if ( access.doesFileExist(path/
"/repodata/repomd.xml") )
1493 MIL <<
"Probed type RPMMD at " << url <<
" (" << path <<
")" << endl;
1497 catch (
const media::MediaException &e )
1500 DBG <<
"problem checking for repodata/repomd.xml file" << endl;
1502 gotMediaException =
true;
1507 if ( access.doesFileExist(path/
"/content") )
1509 MIL <<
"Probed type YAST2 at " << url <<
" (" << path <<
")" << endl;
1513 catch (
const media::MediaException &e )
1516 DBG <<
"problem checking for content file" << endl;
1518 gotMediaException =
true;
1522 if ( ! ( url.schemeIsDownloading() || url.schemeIsPlugin() ) )
1524 MediaMounter media( url );
1525 if ( PathInfo(media.getPathName()/path).isDir() )
1528 MIL <<
"Probed type RPMPLAINDIR at " << url <<
" (" << path <<
")" << endl;
1533 catch (
const Exception &e )
1537 Exception enew(
str::form(
_(
"Unknown error reading from '%s'"), url.asString().c_str() ));
1542 if (gotMediaException)
1545 MIL <<
"Probed type NONE at " << url <<
" (" << path <<
")" << endl;
1554 repo::RepoType RepoManager::Impl::probeCache(
const Pathname & path_r )
const 1556 MIL <<
"going to probe the cached repo at " << path_r << endl;
1560 if ( PathInfo(path_r/
"/repodata/repomd.xml").isFile() )
1562 else if ( PathInfo(path_r/
"/content").isFile() )
1564 else if ( PathInfo(path_r).isDir() )
1567 MIL <<
"Probed cached type " << ret <<
" at " << path_r << endl;
1575 MIL <<
"Going to clean up garbage in cache dirs" << endl;
1577 ProgressData progress(300);
1578 progress.sendTo(progressrcv);
1581 std::list<Pathname> cachedirs;
1582 cachedirs.push_back(_options.repoRawCachePath);
1583 cachedirs.push_back(_options.repoPackagesCachePath);
1584 cachedirs.push_back(_options.repoSolvCachePath);
1586 for_( dir, cachedirs.begin(), cachedirs.end() )
1588 if ( PathInfo(*dir).isExist() )
1590 std::list<Pathname> entries;
1595 unsigned sdircount = entries.size();
1596 unsigned sdircurrent = 1;
1597 for_( subdir, entries.begin(), entries.end() )
1601 for_( r, repoBegin(), repoEnd() )
1602 if ( subdir->basename() == r->escaped_alias() )
1603 { found =
true;
break; }
1608 progress.set( progress.val() + sdircurrent * 100 / sdircount );
1613 progress.set( progress.val() + 100 );
1622 ProgressData progress(100);
1623 progress.sendTo(progressrcv);
1626 MIL <<
"Removing raw metadata cache for " << info.alias() << endl;
1637 Pathname solvfile = solv_path_for_repoinfo(_options, info) /
"solv";
1639 if ( ! PathInfo(solvfile).isExist() )
1649 if ( toolversion != LIBSOLV_TOOLVERSION )
1651 repo.eraseFromPool();
1652 ZYPP_THROW(Exception(str::Str() <<
"Solv-file was created by '"<<toolversion<<
"'-parser (want "<<LIBSOLV_TOOLVERSION<<
")."));
1655 catch (
const Exception & exp )
1658 MIL <<
"Try to handle exception by rebuilding the solv-file" << endl;
1659 cleanCache( info, progressrcv );
1660 buildCache( info, BuildIfNeeded, progressrcv );
1672 ProgressData progress(100);
1673 callback::SendReport<ProgressReport> report;
1674 progress.sendTo( ProgressReportAdaptor( progressrcv, report ) );
1675 progress.name(
str::form(
_(
"Adding repository '%s'"), info.label().c_str()));
1678 MIL <<
"Try adding repo " << info << endl;
1680 RepoInfo tosave = info;
1685 if ( _options.probe )
1687 DBG <<
"unknown repository type, probing" << endl;
1688 assert_urls(tosave);
1690 RepoType probedtype( probe( tosave.url(), info.path() ) );
1694 tosave.setType(probedtype);
1702 Pathname repofile = generateNonExistingName(
1703 _options.knownReposPath, generateFilename(tosave));
1705 MIL <<
"Saving repo in " << repofile << endl;
1707 std::ofstream file(repofile.c_str());
1714 tosave.dumpAsIniOn(file);
1715 tosave.setFilepath(repofile);
1716 tosave.setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ) );
1717 tosave.setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ) );
1721 RepoInfo & oinfo( const_cast<RepoInfo &>(info) );
1722 oinfo.setFilepath(repofile);
1723 oinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ) );
1724 oinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ) );
1726 reposManip().insert(tosave);
1731 UrlCredentialExtractor( _options.rootDir ).collect( tosave.baseUrls() );
1733 HistoryLog(_options.rootDir).addRepository(tosave);
1736 MIL <<
"done" << endl;
1743 for ( std::list<RepoInfo>::const_iterator it =
repos.begin();
1748 for_ ( kit, repoBegin(), repoEnd() )
1750 if ( (*it).alias() == (*kit).alias() )
1752 ERR <<
"To be added repo " << (*it).alias() <<
" conflicts with existing repo " << (*kit).alias() << endl;
1758 std::string filename = Pathname(url.getPathName()).basename();
1760 if ( filename == Pathname() )
1769 Pathname repofile = generateNonExistingName(_options.knownReposPath, filename);
1771 MIL <<
"Saving " <<
repos.size() <<
" repo" << (
repos.size() ?
"s" :
"" ) <<
" in " << repofile << endl;
1773 std::ofstream file(repofile.c_str());
1780 for ( std::list<RepoInfo>::iterator it =
repos.begin();
1784 MIL <<
"Saving " << (*it).alias() << endl;
1785 it->dumpAsIniOn(file);
1786 it->setFilepath(repofile);
1787 it->setMetadataPath( rawcache_path_for_repoinfo( _options, *it ) );
1788 it->setPackagesPath( packagescache_path_for_repoinfo( _options, *it ) );
1789 reposManip().insert(*it);
1791 HistoryLog(_options.rootDir).addRepository(*it);
1794 MIL <<
"done" << endl;
1801 ProgressData progress;
1802 callback::SendReport<ProgressReport> report;
1803 progress.sendTo( ProgressReportAdaptor( progressrcv, report ) );
1804 progress.name(
str::form(
_(
"Removing repository '%s'"), info.label().c_str()));
1806 MIL <<
"Going to delete repo " << info.alias() << endl;
1808 for_( it, repoBegin(), repoEnd() )
1813 if ( (!info.alias().empty()) && ( info.alias() != (*it).alias() ) )
1820 RepoInfo todelete = *it;
1821 if (todelete.filepath().empty())
1828 std::list<RepoInfo> filerepos = repositories_in_file(todelete.filepath());
1829 if ( filerepos.size() == 0
1830 ||(filerepos.size() == 1 && filerepos.front().alias() == todelete.alias() ) )
1834 if ( ! ( ret == 0 || ret == ENOENT ) )
1839 MIL << todelete.alias() <<
" successfully deleted." << endl;
1851 std::ofstream file(todelete.filepath().c_str());
1855 ZYPP_THROW( Exception(
str::form(
_(
"Can't open file '%s' for writing."), todelete.filepath().c_str() )));
1857 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1858 fit != filerepos.end();
1861 if ( (*fit).alias() != todelete.alias() )
1862 (*fit).dumpAsIniOn(file);
1866 CombinedProgressData cSubprogrcv(progress, 20);
1867 CombinedProgressData mSubprogrcv(progress, 40);
1868 CombinedProgressData pSubprogrcv(progress, 40);
1870 if ( isCached(todelete) )
1871 cleanCache( todelete, cSubprogrcv);
1873 cleanMetadata( todelete, mSubprogrcv );
1874 cleanPackages( todelete, pSubprogrcv,
true );
1875 reposManip().erase(todelete);
1876 MIL << todelete.alias() <<
" successfully deleted." << endl;
1877 HistoryLog(_options.rootDir).removeRepository(todelete);
1888 void RepoManager::Impl::modifyRepository(
const std::string & alias,
const RepoInfo & newinfo_r,
const ProgressData::ReceiverFnc & progressrcv )
1890 RepoInfo toedit = getRepositoryInfo(alias);
1891 RepoInfo newinfo( newinfo_r );
1894 if ( alias != newinfo.alias() && hasRepo( newinfo.alias() ) )
1899 if (toedit.filepath().empty())
1906 std::list<RepoInfo> filerepos = repositories_in_file(toedit.filepath());
1916 std::ofstream file(toedit.filepath().c_str());
1920 ZYPP_THROW( Exception(
str::form(
_(
"Can't open file '%s' for writing."), toedit.filepath().c_str() )));
1922 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1923 fit != filerepos.end();
1928 if ( (*fit).alias() != toedit.alias() )
1929 (*fit).dumpAsIniOn(file);
1931 newinfo.dumpAsIniOn(file);
1934 if ( toedit.enabled() && !newinfo.enabled() )
1937 const Pathname & solvidx = solv_path_for_repoinfo(_options, newinfo)/
"solv.idx";
1938 if ( PathInfo(solvidx).isExist() )
1942 newinfo.setFilepath(toedit.filepath());
1943 newinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, newinfo ) );
1944 newinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, newinfo ) );
1948 RepoInfo & oinfo( const_cast<RepoInfo &>(newinfo_r) );
1949 oinfo.setFilepath(toedit.filepath());
1950 oinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, newinfo ) );
1951 oinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, newinfo ) );
1953 reposManip().erase(toedit);
1954 reposManip().insert(newinfo);
1956 UrlCredentialExtractor( _options.rootDir ).collect( newinfo.baseUrls() );
1957 HistoryLog(_options.rootDir).modifyRepository(toedit, newinfo);
1958 MIL <<
"repo " << alias <<
" modified" << endl;
1964 RepoInfo RepoManager::Impl::getRepositoryInfo(
const std::string & alias,
const ProgressData::ReceiverFnc & progressrcv )
1966 RepoConstIterator it( findAlias( alias,
repos() ) );
1967 if ( it !=
repos().end() )
1970 info.setAlias( alias );
1975 RepoInfo RepoManager::Impl::getRepositoryInfo(
const Url & url,
const url::ViewOption & urlview,
const ProgressData::ReceiverFnc & progressrcv )
1977 for_( it, repoBegin(), repoEnd() )
1979 for_( urlit, (*it).baseUrlsBegin(), (*it).baseUrlsEnd() )
1981 if ( (*urlit).asString(urlview) == url.asString(urlview) )
1986 info.setBaseUrl( url );
1996 void RepoManager::Impl::addService(
const ServiceInfo & service )
1998 assert_alias( service );
2001 if ( hasService( service.alias() ) )
2006 ServiceInfo toSave( service );
2007 saveService( toSave );
2011 UrlCredentialExtractor( _options.rootDir ).collect( toSave.url() );
2013 MIL <<
"added service " << toSave.alias() << endl;
2018 void RepoManager::Impl::removeService(
const std::string & alias )
2020 MIL <<
"Going to delete service " << alias << endl;
2022 const ServiceInfo & service = getService( alias );
2024 Pathname location = service.filepath();
2025 if( location.empty() )
2031 parser::ServiceFileReader( location, ServiceCollector(tmpSet) );
2034 if ( tmpSet.size() == 1 )
2041 MIL << alias <<
" successfully deleted." << endl;
2047 std::ofstream file(location.c_str());
2054 for_(it, tmpSet.begin(), tmpSet.end())
2056 if( it->alias() != alias )
2057 it->dumpAsIniOn(file);
2060 MIL << alias <<
" successfully deleted from file " << location << endl;
2064 RepoCollector rcollector;
2065 getRepositoriesInService( alias,
2066 boost::make_function_output_iterator( bind( &RepoCollector::collect, &rcollector, _1 ) ) );
2068 for_(rit, rcollector.repos.begin(), rcollector.repos.end())
2069 removeRepository(*rit);
2074 void RepoManager::Impl::refreshServices(
const RefreshServiceOptions & options_r )
2078 ServiceSet services( serviceBegin(), serviceEnd() );
2079 for_( it, services.begin(), services.end() )
2081 if ( !it->enabled() )
2085 refreshService(*it, options_r);
2087 catch (
const repo::ServicePluginInformalException & e )
2092 void RepoManager::Impl::refreshService(
const std::string & alias,
const RefreshServiceOptions & options_r )
2094 ServiceInfo service( getService( alias ) );
2095 assert_alias( service );
2096 assert_url( service );
2097 MIL <<
"Going to refresh service '" << service.alias() <<
"', url: " << service.url() <<
", opts: " << options_r << endl;
2099 if ( service.ttl() && !( options_r.testFlag( RefreshService_forceRefresh) || options_r.testFlag( RefreshService_restoreStatus ) ) )
2102 Date lrf = service.lrf();
2108 if ( (lrf+=service.ttl()) > now )
2110 MIL <<
"Skip: '" << service.alias() <<
"' metadata valid until " << lrf << endl;
2115 WAR <<
"Force: '" << service.alias() <<
"' metadata last refresh in the future: " << lrf << endl;
2122 bool serviceModified =
false;
2129 repo::ServiceType type = probeService( service.url() );
2132 service.setProbedType( type );
2133 serviceModified =
true;
2138 std::string servicesTargetDistro = _options.servicesTargetDistro;
2139 if ( servicesTargetDistro.empty() )
2143 DBG <<
"ServicesTargetDistro: " << servicesTargetDistro << endl;
2147 RepoCollector collector(servicesTargetDistro);
2152 std::pair<DefaultIntegral<bool,false>, repo::ServicePluginInformalException> uglyHack;
2160 ServiceRepos( _options.rootDir, service, bind( &RepoCollector::collect, &collector, _1 ) );
2162 catch (
const repo::ServicePluginInformalException & e )
2165 uglyHack.first =
true;
2166 uglyHack.second = e;
2168 if ( service.ttl() != origTtl )
2170 if ( !service.ttl() )
2171 service.setLrf( Date() );
2172 serviceModified =
true;
2180 for_( it, collector.repos.begin(), collector.repos.end() )
2183 it->setAlias(
str::form(
"%s:%s", service.alias().c_str(), it->alias().c_str() ) );
2185 it->setService( service.alias() );
2188 newRepoStates[it->alias()] = *it;
2196 if ( !it->path().empty() )
2198 if ( it->path() !=
"/" )
2203 if ( it->baseUrlsEmpty() )
2205 Url url( service.rawUrl() );
2206 if ( !path.empty() )
2207 url.setPathName( url.getPathName() / path );
2208 it->setBaseUrl( std::move(url) );
2210 else if ( !path.empty() )
2213 for ( Url & url : urls )
2215 url.setPathName( url.getPathName() / path );
2217 it->setBaseUrls( std::move(urls) );
2224 RepoInfoList oldRepos;
2225 getRepositoriesInService( service.alias(), std::back_inserter( oldRepos ) );
2229 for_( oldRepo, oldRepos.begin(), oldRepos.end() )
2231 if ( ! foundAliasIn( oldRepo->alias(), collector.repos ) )
2233 if ( oldRepo->enabled() )
2236 const auto & last = service.repoStates().find( oldRepo->alias() );
2237 if ( last != service.repoStates().end() && ! last->second.enabled )
2239 DBG <<
"Service removes user enabled repo " << oldRepo->alias() << endl;
2240 service.addRepoToEnable( oldRepo->alias() );
2241 serviceModified =
true;
2244 DBG <<
"Service removes enabled repo " << oldRepo->alias() << endl;
2247 DBG <<
"Service removes disabled repo " << oldRepo->alias() << endl;
2249 removeRepository( *oldRepo );
2255 UrlCredentialExtractor urlCredentialExtractor( _options.rootDir );
2256 for_( it, collector.repos.begin(), collector.repos.end() )
2262 TriBool toBeEnabled( indeterminate );
2263 DBG <<
"Service request to " << (it->enabled()?
"enable":
"disable") <<
" service repo " << it->alias() << endl;
2265 if ( options_r.testFlag( RefreshService_restoreStatus ) )
2267 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() << endl;
2272 service.delRepoToEnable( it->alias() );
2277 if ( service.repoToEnableFind( it->alias() ) )
2279 DBG <<
"User request to enable service repo " << it->alias() << endl;
2284 service.delRepoToEnable( it->alias() );
2285 serviceModified =
true;
2287 else if ( service.repoToDisableFind( it->alias() ) )
2289 DBG <<
"User request to disable service repo " << it->alias() << endl;
2290 toBeEnabled =
false;
2294 RepoInfoList::iterator oldRepo( findAlias( it->alias(), oldRepos ) );
2295 if ( oldRepo == oldRepos.end() )
2300 if ( ! indeterminate(toBeEnabled) )
2301 it->setEnabled( (
bool ) toBeEnabled );
2303 DBG <<
"Service adds repo " << it->alias() <<
" " << (it->enabled()?
"enabled":
"disabled") << endl;
2304 addRepository( *it );
2309 bool oldRepoModified =
false;
2311 if ( indeterminate(toBeEnabled) )
2315 if ( oldRepo->enabled() == it->enabled() )
2316 toBeEnabled = it->enabled();
2317 else if (options_r.testFlag( RefreshService_restoreStatus ) )
2319 toBeEnabled = it->enabled();
2320 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() <<
" forces " << (toBeEnabled?
"enabled":
"disabled") << endl;
2324 const auto & last = service.repoStates().find( oldRepo->alias() );
2325 if ( last == service.repoStates().end() || last->second.enabled != it->enabled() )
2326 toBeEnabled = it->enabled();
2329 toBeEnabled = oldRepo->enabled();
2330 DBG <<
"User modified service repo " << it->alias() <<
" may stay " << (toBeEnabled?
"enabled":
"disabled") << endl;
2336 if ( toBeEnabled == oldRepo->enabled() )
2338 DBG <<
"Service repo " << it->alias() <<
" stays " << (oldRepo->enabled()?
"enabled":
"disabled") << endl;
2340 else if ( toBeEnabled )
2342 DBG <<
"Service repo " << it->alias() <<
" gets enabled" << endl;
2343 oldRepo->setEnabled(
true );
2344 oldRepoModified =
true;
2348 DBG <<
"Service repo " << it->alias() <<
" gets disabled" << endl;
2349 oldRepo->setEnabled(
false );
2350 oldRepoModified =
true;
2356 if ( oldRepo->rawName() != it->rawName() )
2358 DBG <<
"Service repo " << it->alias() <<
" gets new NAME " << it->rawName() << endl;
2359 oldRepo->setName( it->rawName() );
2360 oldRepoModified =
true;
2364 if ( oldRepo->autorefresh() != it->autorefresh() )
2366 DBG <<
"Service repo " << it->alias() <<
" gets new AUTOREFRESH " << it->autorefresh() << endl;
2367 oldRepo->setAutorefresh( it->autorefresh() );
2368 oldRepoModified =
true;
2372 if ( oldRepo->priority() != it->priority() )
2374 DBG <<
"Service repo " << it->alias() <<
" gets new PRIORITY " << it->priority() << endl;
2375 oldRepo->setPriority( it->priority() );
2376 oldRepoModified =
true;
2382 urlCredentialExtractor.extract( newUrls );
2383 if ( oldRepo->rawBaseUrls() != newUrls )
2385 DBG <<
"Service repo " << it->alias() <<
" gets new URLs " << newUrls << endl;
2386 oldRepo->setBaseUrls( std::move(newUrls) );
2387 oldRepoModified =
true;
2397 oldRepo->getRawGpgChecks( ogpg[0], ogpg[1], ogpg[2] );
2398 it-> getRawGpgChecks( ngpg[0], ngpg[1], ngpg[2] );
2399 #define Z_CHKGPG(I,N) \ 2400 if ( ! sameTriboolState( ogpg[I], ngpg[I] ) ) \ 2402 DBG << "Service repo " << it->alias() << " gets new "#N"Check " << ngpg[I] << endl; \ 2403 oldRepo->set##N##Check( ngpg[I] ); \ 2404 oldRepoModified = true; \ 2413 if ( oldRepoModified )
2415 modifyRepository( oldRepo->alias(), *oldRepo );
2421 if ( ! service.reposToDisableEmpty() )
2423 service.clearReposToDisable();
2424 serviceModified =
true;
2428 if ( service.repoStates() != newRepoStates )
2430 service.setRepoStates( std::move(newRepoStates) );
2431 serviceModified =
true;
2438 if ( service.ttl() )
2441 serviceModified =
true;
2444 if ( serviceModified )
2447 modifyService( service.alias(), service );
2451 if ( uglyHack.first )
2453 throw( uglyHack.second );
2459 void RepoManager::Impl::modifyService(
const std::string & oldAlias,
const ServiceInfo & newService )
2461 MIL <<
"Going to modify service " << oldAlias << endl;
2465 ServiceInfo service(newService);
2472 const ServiceInfo & oldService = getService(oldAlias);
2474 Pathname location = oldService.filepath();
2475 if( location.empty() )
2482 parser::ServiceFileReader( location, ServiceCollector(tmpSet) );
2485 std::ofstream file(location.c_str());
2486 for_(it, tmpSet.begin(), tmpSet.end())
2488 if( *it != oldAlias )
2489 it->dumpAsIniOn(file);
2491 service.dumpAsIniOn(file);
2493 service.setFilepath(location);
2498 UrlCredentialExtractor( _options.rootDir ).collect( service.url() );
2502 if ( oldAlias != service.alias()
2503 || oldService.enabled() != service.enabled() )
2505 std::vector<RepoInfo> toModify;
2506 getRepositoriesInService(oldAlias, std::back_inserter(toModify));
2507 for_( it, toModify.begin(), toModify.end() )
2509 if ( oldService.enabled() != service.enabled() )
2511 if ( service.enabled() )
2514 const auto & last = service.repoStates().find( it->alias() );
2515 if ( last != service.repoStates().end() )
2516 it->setEnabled( last->second.enabled );
2519 it->setEnabled(
false );
2522 if ( oldAlias != service.alias() )
2523 it->setService(service.alias());
2525 modifyRepository(it->alias(), *it);
2534 repo::ServiceType RepoManager::Impl::probeService(
const Url & url )
const 2539 if ( access.doesFileExist(
"/repo/repoindex.xml") )
2542 catch (
const media::MediaException &e )
2550 catch (
const Exception &e )
2554 Exception enew(
str::form(
_(
"Unknown error reading from '%s'"), url.asString().c_str() ));
2567 MIL <<
"GeoIp disabled via ZConfig, not refreshing the GeoIP information." << std::endl;
2571 std::vector<std::string> hosts;
2572 for (
const auto &baseUrl : urls ) {
2573 const auto &host = baseUrl.getHost();
2575 hosts.push_back( host );
2580 if ( hosts.empty() ) {
2581 MIL <<
"No configured geoip URL found, not updating geoip data" << std::endl;
2588 MIL <<
"Unable to create cache directory for GeoIP." << std::endl;
2592 if ( !PathInfo(geoIPCache).userMayRWX() ) {
2593 MIL <<
"No access rights for the GeoIP cache directory." << std::endl;
2602 PathInfo pi( dir/entry.name );
2603 auto age = std::chrono::system_clock::now() - std::chrono::system_clock::from_time_t( pi.mtime() );
2604 if ( age < std::chrono::hours(24) )
2607 MIL <<
"Removing GeoIP file for " << entry.name <<
" since it's older than 24hrs." << std::endl;
2613 std::for_each( hosts.begin(), hosts.end(), [ & ](
const std::string &hostname ) {
2617 MIL <<
"Skipping GeoIP request for " << hostname <<
" since a valid cache entry exists." << std::endl;
2621 MIL <<
"Query GeoIP for " << hostname << std::endl;
2632 MIL <<
"Ignoring invalid GeoIP hostname: " << hostname << std::endl;
2644 MIL <<
"Failed to query GeoIP from hostname: " << hostname << std::endl;
2647 if ( !file->
empty() ) {
2649 constexpr
auto writeHostToFile = [](
const Pathname &fName,
const std::string &host ){
2651 out.open( fName.asString(), std::ios_base::trunc );
2652 if ( out.is_open() ) {
2653 out << host << std::endl;
2655 MIL <<
"Failed to create/open GeoIP cache file " << fName << std::endl;
2659 std::string geoipMirror;
2662 if ( reader.seekToNode( 1,
"host" ) ) {
2663 const auto &
str = reader.nodeText().asString();
2671 MIL <<
"Storing geoIP redirection: " << hostname <<
" -> " <<
str << std::endl;
2676 MIL <<
"No host entry or empty file returned for GeoIP, remembering for 24hrs" << std::endl;
2680 MIL <<
"Empty or invalid GeoIP file, not requesting again for 24hrs" << std::endl;
2683 writeHostToFile( geoIPCache / hostname, geoipMirror );
2689 MIL <<
"Failed to query GeoIP data." << std::endl;
2700 : _pimpl( new
Impl(opt) )
2707 {
return _pimpl->repoEmpty(); }
2710 {
return _pimpl->repoSize(); }
2713 {
return _pimpl->repoBegin(); }
2716 {
return _pimpl->repoEnd(); }
2719 {
return _pimpl->getRepo( alias ); }
2722 {
return _pimpl->hasRepo( alias ); }
2732 std::string host( url_r.
getHost() );
2733 if ( ! host.empty() )
2745 {
return _pimpl->metadataStatus( info ); }
2748 {
return _pimpl->checkIfToRefreshMetadata( info, url, policy ); }
2751 {
return _pimpl->metadataPath( info ); }
2754 {
return _pimpl->packagesPath( info ); }
2757 {
return _pimpl->refreshMetadata( info, policy, progressrcv ); }
2760 {
return _pimpl->cleanMetadata( info, progressrcv ); }
2763 {
return _pimpl->cleanPackages( info, progressrcv ); }
2766 {
return _pimpl->cacheStatus( info ); }
2769 {
return _pimpl->buildCache( info, policy, progressrcv ); }
2772 {
return _pimpl->cleanCache( info, progressrcv ); }
2775 {
return _pimpl->isCached( info ); }
2778 {
return _pimpl->loadFromCache( info, progressrcv ); }
2781 {
return _pimpl->cleanCacheDirGarbage( progressrcv ); }
2784 {
return _pimpl->probe( url, path ); }
2787 {
return _pimpl->probe( url ); }
2790 {
return _pimpl->addRepository( info, progressrcv ); }
2793 {
return _pimpl->addRepositories( url, progressrcv ); }
2796 {
return _pimpl->removeRepository( info, progressrcv ); }
2799 {
return _pimpl->modifyRepository( alias, newinfo, progressrcv ); }
2802 {
return _pimpl->getRepositoryInfo( alias, progressrcv ); }
2805 {
return _pimpl->getRepositoryInfo( url, urlview, progressrcv ); }
2808 {
return _pimpl->serviceEmpty(); }
2811 {
return _pimpl->serviceSize(); }
2814 {
return _pimpl->serviceBegin(); }
2817 {
return _pimpl->serviceEnd(); }
2820 {
return _pimpl->getService( alias ); }
2823 {
return _pimpl->hasService( alias ); }
2826 {
return _pimpl->probeService( url ); }
2829 {
return _pimpl->addService( alias, url ); }
2832 {
return _pimpl->addService( service ); }
2835 {
return _pimpl->removeService( alias ); }
2838 {
return _pimpl->removeService( service ); }
2841 {
return _pimpl->refreshServices( options_r ); }
2844 {
return _pimpl->refreshService( alias, options_r ); }
2847 {
return _pimpl->refreshService( service, options_r ); }
2850 {
return _pimpl->modifyService( oldAlias, service ); }
2853 {
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