57 using namespace zypp::repo;
59 #define OPT_PROGRESS const ProgressData::ReceiverFnc & = ProgressData::ReceiverFnc()
74 MediaMounter(
const Url & url_r )
76 media::MediaManager mediamanager;
77 _mid = mediamanager.open( url_r );
78 mediamanager.attach(
_mid );
84 media::MediaManager mediamanager;
85 mediamanager.release(
_mid );
86 mediamanager.close(
_mid );
93 Pathname getPathName(
const Pathname & path_r = Pathname() )
const
95 media::MediaManager mediamanager;
96 return mediamanager.localPath(
_mid, path_r );
105 template <
class Iterator>
106 inline bool foundAliasIn(
const std::string & alias_r, Iterator begin_r, Iterator end_r )
108 for_( it, begin_r, end_r )
109 if ( it->alias() == alias_r )
114 template <
class Container>
115 inline bool foundAliasIn(
const std::string & alias_r,
const Container & cont_r )
116 {
return foundAliasIn( alias_r, cont_r.begin(), cont_r.end() ); }
119 template <
class Iterator>
120 inline Iterator findAlias(
const std::string & alias_r, Iterator begin_r, Iterator end_r )
122 for_( it, begin_r, end_r )
123 if ( it->alias() == alias_r )
128 template <class Container>
129 inline typename Container::iterator findAlias( const std::
string & alias_r, Container & cont_r )
130 {
return findAlias( alias_r, cont_r.begin(), cont_r.end() ); }
132 template <
class Container>
133 inline typename Container::const_iterator findAlias(
const std::string & alias_r,
const Container & cont_r )
134 {
return findAlias( alias_r, cont_r.begin(), cont_r.end() ); }
138 inline std::string filenameFromAlias(
const std::string & alias_r,
const std::string & stem_r )
140 std::string filename( alias_r );
144 filename = Pathname(filename).extend(
"."+stem_r).asString();
145 MIL <<
"generating filename for " << stem_r <<
" [" << alias_r <<
"] : '" << filename <<
"'" << endl;
169 RepoCollector(
const std::string & targetDistro_)
173 bool collect(
const RepoInfo &repo )
177 && !repo.targetDistribution().empty()
182 <<
"' distribution (current distro is '"
183 << repo.targetDistribution() <<
"')." << endl;
188 repos.push_back(repo);
202 std::list<RepoInfo> repositories_in_file(
const Pathname & file )
204 MIL <<
"repo file: " << file << endl;
205 RepoCollector collector;
206 parser::RepoFileReader parser( file, bind( &RepoCollector::collect, &collector, _1 ) );
207 return collector.repos;
220 std::list<RepoInfo> repositories_in_dir(
const Pathname &dir )
222 MIL <<
"directory " << dir << endl;
223 std::list<RepoInfo>
repos;
224 std::list<Pathname> entries;
231 str::regex allowedRepoExt(
"^\\.repo(_[0-9]+)?$");
232 for ( std::list<Pathname>::const_iterator it = entries.begin(); it != entries.end(); ++it )
236 std::list<RepoInfo> tmp = repositories_in_file( *it );
237 repos.insert( repos.end(), tmp.begin(), tmp.end() );
248 inline void assert_alias(
const RepoInfo & info )
250 if ( info.alias().empty() )
254 if ( info.alias()[0] ==
'.')
256 info,
_(
"Repository alias cannot start with dot.")));
259 inline void assert_alias(
const ServiceInfo & info )
261 if ( info.alias().empty() )
265 if ( info.alias()[0] ==
'.')
267 info,
_(
"Service alias cannot start with dot.")));
272 inline void assert_urls(
const RepoInfo & info )
274 if ( info.baseUrlsEmpty() )
278 inline void assert_url(
const ServiceInfo & info )
280 if ( ! info.url().isValid() )
290 inline Pathname rawcache_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
293 return opt.repoRawCachePath / info.escaped_alias();
304 inline Pathname rawproductdata_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
307 return opt.repoRawCachePath / info.escaped_alias() / info.path();
313 inline Pathname packagescache_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
316 return opt.repoPackagesCachePath / info.escaped_alias();
322 inline Pathname solv_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info)
325 return opt.repoSolvCachePath / info.escaped_alias();
331 class ServiceCollector
334 typedef std::set<ServiceInfo> ServiceSet;
336 ServiceCollector( ServiceSet & services_r )
340 bool operator()(
const ServiceInfo & service_r )
const
364 DBG <<
"reading repo file " << repo_file <<
", local path: " << local << endl;
366 return repositories_in_file(local);
377 repoCachePath = Pathname::assertprefix( root_r,
ZConfig::instance().repoCachePath() );
378 repoRawCachePath = Pathname::assertprefix( root_r,
ZConfig::instance().repoMetadataPath() );
379 repoSolvCachePath = Pathname::assertprefix( root_r,
ZConfig::instance().repoSolvfilesPath() );
380 repoPackagesCachePath = Pathname::assertprefix( root_r,
ZConfig::instance().repoPackagesPath() );
381 knownReposPath = Pathname::assertprefix( root_r,
ZConfig::instance().knownReposPath() );
382 knownServicesPath = Pathname::assertprefix( root_r,
ZConfig::instance().knownServicesPath() );
383 pluginsPath = Pathname::assertprefix( root_r,
ZConfig::instance().pluginsPath() );
405 #define OUTS(X) str << " " #X "\t" << obj.X << endl
406 str <<
"RepoManagerOptions (" << obj.
rootDir <<
") {" << endl;
407 OUTS( repoRawCachePath );
408 OUTS( repoSolvCachePath );
409 OUTS( repoPackagesCachePath );
410 OUTS( knownReposPath );
411 OUTS( knownServicesPath );
429 init_knownServices();
430 init_knownRepositories();
439 bool hasRepo(
const std::string & alias )
const
440 {
return foundAliasIn( alias, _repos ); }
450 {
return rawcache_path_for_repoinfo( _options, info ); }
453 {
return packagescache_path_for_repoinfo( _options, info ); }
474 {
return PathInfo(solv_path_for_repoinfo( _options, info ) /
"solv").isExist(); }
499 {
return foundAliasIn( alias,
_services ); }
512 void removeService(
const std::string & alias );
514 { removeService( service.
alias() ); }
516 void refreshServices();
518 void refreshService(
const std::string & alias );
520 { refreshService( service.
alias() ); }
522 void modifyService(
const std::string & oldAlias,
const ServiceInfo & newService );
529 Pathname generateNonExistingName(
const Pathname & dir,
const std::string & basefilename )
const;
532 {
return filenameFromAlias( info.
alias(),
"repo" ); }
535 {
return filenameFromAlias( info.
alias(),
"service" ); }
539 Pathname base = solv_path_for_repoinfo( _options, info );
544 void touchIndexFile(
const RepoInfo & info );
546 template<
typename OutputIterator>
550 std::copy( boost::make_filter_iterator( filter, _repos.begin(), _repos.end() ),
551 boost::make_filter_iterator( filter, _repos.end(), _repos.end() ),
556 void init_knownServices();
557 void init_knownRepositories();
565 friend Impl * rwcowClone<Impl>(
const Impl * rhs );
568 {
return new Impl( *
this ); }
574 {
return str <<
"RepoManager::Impl"; }
581 Pathname servfile = generateNonExistingName( _options.knownServicesPath,
582 generateFilename( service ) );
585 MIL <<
"saving service in " << servfile << endl;
587 std::ofstream file( servfile.c_str() );
594 MIL <<
"done" << endl;
613 const std::string & basefilename )
const
615 std::string final_filename = basefilename;
617 while ( PathInfo(dir + final_filename).isExist() )
622 return dir + Pathname(final_filename);
629 Pathname dir = _options.knownServicesPath;
630 std::list<Pathname> entries;
631 if (PathInfo(dir).isExist())
640 for_(it, entries.begin(), entries.end() )
656 inline void cleanupNonRepoMetadtaFolders(
const Pathname & cachePath_r,
657 const Pathname & defaultCachePath_r,
658 const std::list<std::string> & repoEscAliases_r )
660 if ( cachePath_r != defaultCachePath_r )
663 std::list<std::string> entries;
667 std::set<std::string> oldfiles;
668 set_difference( entries.begin(), entries.end(), repoEscAliases_r.begin(), repoEscAliases_r.end(),
669 std::inserter( oldfiles, oldfiles.end() ) );
670 for (
const std::string & old : oldfiles )
682 MIL <<
"start construct known repos" << endl;
684 if ( PathInfo(_options.knownReposPath).isExist() )
686 std::list<std::string> repoEscAliases;
687 for (
RepoInfo & repoInfo : repositories_in_dir(_options.knownReposPath) )
690 repoInfo.setMetadataPath( rawcache_path_for_repoinfo(_options, repoInfo) );
692 repoInfo.setPackagesPath( packagescache_path_for_repoinfo(_options, repoInfo) );
694 _repos.insert( repoInfo );
695 repoEscAliases.push_back(repoInfo.escaped_alias());
697 repoEscAliases.sort();
705 cleanupNonRepoMetadtaFolders( _options.repoRawCachePath, defaultCache.
repoRawCachePath, repoEscAliases );
706 cleanupNonRepoMetadtaFolders( _options.repoSolvCachePath, defaultCache.
repoSolvCachePath, repoEscAliases );
707 cleanupNonRepoMetadtaFolders( _options.repoPackagesCachePath, defaultCache.
repoPackagesCachePath, repoEscAliases );
709 MIL <<
"end construct known repos" << endl;
716 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
717 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
721 switch ( repokind.
toEnum() )
725 repokind = probe( productdatapath.asUrl() );
731 switch ( repokind.
toEnum() )
735 status =
RepoStatus( productdatapath +
"/repodata/repomd.xml");
741 status =
RepoStatus( productdatapath +
"/content") && (
RepoStatus( mediarootpath +
"/media.1/media"));
747 if ( PathInfo(Pathname(productdatapath +
"/cookie")).isExist() )
748 status =
RepoStatus( productdatapath +
"/cookie");
764 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
769 repokind = probe( productdatapath.asUrl() );
775 switch ( repokind.
toEnum() )
778 p = Pathname(productdatapath +
"/repodata/repomd.xml");
782 p = Pathname(productdatapath +
"/content");
786 p = Pathname(productdatapath +
"/cookie");
808 MIL <<
"Going to try to check whether refresh is needed for " << url << endl;
811 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
813 oldstatus = metadataStatus(info);
815 if ( oldstatus.
empty() )
817 MIL <<
"No cached metadata, going to refresh" << endl;
818 return REFRESH_NEEDED;
823 if ( scheme ==
"cd" || scheme ==
"dvd" )
825 MIL <<
"never refresh CD/DVD" << endl;
826 return REPO_UP_TO_DATE;
831 if (policy != RefreshForced && policy != RefreshIfNeededIgnoreDelay)
834 double diff = difftime(
840 DBG <<
"last refresh = " << diff <<
" minutes ago" << endl;
846 WAR <<
"Repository '" << info.
alias() <<
"' was refreshed in the future!" << endl;
850 MIL <<
"Repository '" << info.
alias()
851 <<
"' has been refreshed less than repo.refresh.delay ("
853 <<
") minutes ago. Advising to skip refresh" << endl;
854 return REPO_CHECK_DELAYED;
864 switch ( repokind.
toEnum() )
868 repokind = probe( url, info.
path() );
878 shared_ptr<repo::Downloader> downloader_ptr;
885 RepoStatus newstatus = downloader_ptr->status(media);
886 bool refresh =
false;
889 MIL <<
"repo has not changed" << endl;
890 if ( policy == RefreshForced )
892 MIL <<
"refresh set to forced" << endl;
898 MIL <<
"repo has changed, going to refresh" << endl;
903 touchIndexFile(info);
905 return refresh ? REFRESH_NEEDED : REPO_UP_TO_DATE;
909 MediaMounter media( url );
911 bool refresh =
false;
914 MIL <<
"repo has not changed" << endl;
915 if ( policy == RefreshForced )
917 MIL <<
"refresh set to forced" << endl;
923 MIL <<
"repo has changed, going to refresh" << endl;
928 touchIndexFile(info);
930 return refresh ? REFRESH_NEEDED : REPO_UP_TO_DATE;
940 ERR <<
"refresh check failed for " << url << endl;
944 return REFRESH_NEEDED;
955 "Valid metadata not found at specified URLs",
967 if (checkIfToRefreshMetadata(info, url, policy)!=REFRESH_NEEDED)
970 MIL <<
"Going to refresh metadata from " << url << endl;
975 switch ( repokind.
toEnum() )
979 repokind = probe( *it, info.
path() );
986 for_( it, repoBegin(), repoEnd() )
988 if ( info.
alias() == (*it).alias() )
991 modifiedrepo.
setType( repokind );
992 modifyRepository( info.
alias(), modifiedrepo );
1002 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1013 Exception ex(
_(
"Can't create metadata cache directory."));
1021 shared_ptr<repo::Downloader> downloader_ptr;
1023 MIL <<
"Creating downloader for [ " << info.
alias() <<
" ]" << endl;
1036 for_( it, repoBegin(), repoEnd() )
1038 Pathname cachepath(rawcache_path_for_repoinfo( _options, *it ));
1039 if ( PathInfo(cachepath).isExist() )
1040 downloader_ptr->addCachePath(cachepath);
1043 downloader_ptr->download( media, tmpdir.
path() );
1047 MediaMounter media( url );
1050 Pathname productpath( tmpdir.
path() / info.
path() );
1052 std::ofstream file( (productpath/
"cookie").c_str() );
1059 if ( ! info.
path().empty() && info.
path() !=
"/" )
1060 file <<
" (" << info.
path() <<
")";
1062 file << newstatus.
checksum() << endl;
1081 ERR <<
"Trying another url..." << endl;
1090 ERR <<
"No more urls..." << endl;
1099 progress.
sendTo(progressfnc);
1109 progress.
sendTo(progressfnc);
1119 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1120 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
1127 RepoStatus raw_metadata_status = metadataStatus(info);
1128 if ( raw_metadata_status.
empty() )
1133 refreshMetadata(info, RefreshIfNeeded, progressrcv );
1134 raw_metadata_status = metadataStatus(info);
1137 bool needs_cleaning =
false;
1138 if ( isCached( info ) )
1140 MIL << info.
alias() <<
" is already cached." << endl;
1145 MIL << info.
alias() <<
" cache is up to date with metadata." << endl;
1146 if ( policy == BuildIfNeeded ) {
1150 MIL << info.
alias() <<
" cache rebuild is forced" << endl;
1154 needs_cleaning =
true;
1168 MIL << info.
alias() <<
" building cache..." << info.
type() << endl;
1170 Pathname base = solv_path_for_repoinfo( _options, info);
1178 if( ! PathInfo(base).userMayW() )
1180 Exception ex(
str::form(
_(
"Can't create cache at %s - no writing permissions."), base.c_str()) );
1183 Pathname solvfile = base /
"solv";
1189 switch ( repokind.
toEnum() )
1193 repokind = probe( productdatapath.asUrl() );
1199 MIL <<
"repo type is " << repokind << endl;
1201 switch ( repokind.
toEnum() )
1209 scoped_ptr<MediaMounter> forPlainDirs;
1212 cmd.push_back(
"repo2solv.sh" );
1215 cmd.push_back(
"-o" );
1216 cmd.push_back( solvfile.asString() );
1220 forPlainDirs.reset(
new MediaMounter( *info.
baseUrlsBegin() ) );
1222 cmd.push_back(
"-R" );
1224 cmd.push_back( forPlainDirs->getPathName( info.
path() ).c_str() );
1227 cmd.push_back( productdatapath.asString() );
1230 std::string errdetail;
1233 WAR <<
" " << output;
1234 if ( errdetail.empty() ) {
1238 errdetail += output;
1241 int ret = prog.
close();
1258 setCacheStatus(info, raw_metadata_status);
1259 MIL <<
"Commit cache.." << endl;
1267 MIL <<
"going to probe the repo type at " << url <<
" (" << path <<
")" << endl;
1273 MIL <<
"Probed type NONE (not exists) at " << url <<
" (" << path <<
")" << endl;
1285 bool gotMediaException =
false;
1293 MIL <<
"Probed type RPMMD at " << url <<
" (" << path <<
")" << endl;
1300 DBG <<
"problem checking for repodata/repomd.xml file" << endl;
1302 gotMediaException =
true;
1309 MIL <<
"Probed type YAST2 at " << url <<
" (" << path <<
")" << endl;
1316 DBG <<
"problem checking for content file" << endl;
1318 gotMediaException =
true;
1324 MediaMounter media( url );
1325 if ( PathInfo(media.getPathName()/path).isDir() )
1328 MIL <<
"Probed type RPMPLAINDIR at " << url <<
" (" << path <<
")" << endl;
1342 if (gotMediaException)
1345 MIL <<
"Probed type NONE at " << url <<
" (" << path <<
")" << endl;
1353 MIL <<
"Going to clean up garbage in cache dirs" << endl;
1356 progress.
sendTo(progressrcv);
1359 std::list<Pathname> cachedirs;
1360 cachedirs.push_back(_options.repoRawCachePath);
1361 cachedirs.push_back(_options.repoPackagesCachePath);
1362 cachedirs.push_back(_options.repoSolvCachePath);
1364 for_( dir, cachedirs.begin(), cachedirs.end() )
1366 if ( PathInfo(*dir).isExist() )
1368 std::list<Pathname> entries;
1373 unsigned sdircount = entries.size();
1374 unsigned sdircurrent = 1;
1375 for_( subdir, entries.begin(), entries.end() )
1379 for_( r, repoBegin(), repoEnd() )
1380 if ( subdir->basename() == r->escaped_alias() )
1381 { found =
true;
break; }
1386 progress.
set( progress.
val() + sdircurrent * 100 / sdircount );
1391 progress.
set( progress.
val() + 100 );
1401 progress.
sendTo(progressrcv);
1404 MIL <<
"Removing raw metadata cache for " << info.
alias() << endl;
1415 Pathname solvfile = solv_path_for_repoinfo(_options, info) /
"solv";
1417 if ( ! PathInfo(solvfile).isExist() )
1442 MIL <<
"Try to handle exception by rebuilding the solv-file" << endl;
1443 cleanCache( info, progressrcv );
1444 buildCache( info, BuildIfNeeded, progressrcv );
1462 MIL <<
"Try adding repo " << info << endl;
1465 if ( _repos.find(tosave) != _repos.end() )
1469 if ( _options.probe )
1471 DBG <<
"unknown repository type, probing" << endl;
1489 Pathname repofile = generateNonExistingName(
1490 _options.knownReposPath, generateFilename(tosave));
1492 MIL <<
"Saving repo in " << repofile << endl;
1494 std::ofstream file(repofile.c_str());
1508 RepoInfo & oinfo( const_cast<RepoInfo &>(info) );
1512 _repos.insert(tosave);
1517 bool havePasswords =
false;
1519 if ( urlit->hasCredentialsInAuthority() )
1521 havePasswords =
true;
1525 if ( havePasswords )
1531 if (urlit->hasCredentialsInAuthority())
1539 MIL <<
"done" << endl;
1546 for ( std::list<RepoInfo>::const_iterator it = repos.begin();
1551 for_ ( kit, repoBegin(), repoEnd() )
1553 if ( (*it).alias() == (*kit).alias() )
1555 ERR <<
"To be added repo " << (*it).alias() <<
" conflicts with existing repo " << (*kit).alias() << endl;
1561 std::string filename = Pathname(url.
getPathName()).basename();
1563 if ( filename == Pathname() )
1572 Pathname repofile = generateNonExistingName(_options.knownReposPath, filename);
1574 MIL <<
"Saving " << repos.size() <<
" repo" << ( repos.size() ?
"s" :
"" ) <<
" in " << repofile << endl;
1576 std::ofstream file(repofile.c_str());
1583 for ( std::list<RepoInfo>::iterator it = repos.begin();
1587 MIL <<
"Saving " << (*it).alias() << endl;
1588 it->setFilepath(repofile.asString());
1589 it->dumpAsIniOn(file);
1595 MIL <<
"done" << endl;
1607 MIL <<
"Going to delete repo " << info.
alias() << endl;
1609 for_( it, repoBegin(), repoEnd() )
1614 if ( (!info.
alias().empty()) && ( info.
alias() != (*it).alias() ) )
1629 std::list<RepoInfo> filerepos = repositories_in_file(todelete.
filepath());
1630 if ( (filerepos.size() == 1) && ( filerepos.front().alias() == todelete.
alias() ) )
1638 MIL << todelete.
alias() <<
" sucessfully deleted." << endl;
1650 std::ofstream file(todelete.
filepath().c_str());
1656 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1657 fit != filerepos.end();
1660 if ( (*fit).alias() != todelete.
alias() )
1661 (*fit).dumpAsIniOn(file);
1669 if ( isCached(todelete) )
1670 cleanCache( todelete, cSubprogrcv);
1672 cleanMetadata( todelete, mSubprogrcv );
1673 cleanPackages( todelete, pSubprogrcv );
1674 _repos.erase(todelete);
1675 MIL << todelete.
alias() <<
" sucessfully deleted." << endl;
1689 RepoInfo toedit = getRepositoryInfo(alias);
1693 if ( alias != newinfo.
alias() && hasRepo( newinfo.
alias() ) )
1705 std::list<RepoInfo> filerepos = repositories_in_file(toedit.
filepath());
1715 std::ofstream file(toedit.
filepath().c_str());
1721 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1722 fit != filerepos.end();
1727 if ( (*fit).alias() != toedit.
alias() )
1728 (*fit).dumpAsIniOn(file);
1734 _repos.erase(toedit);
1735 _repos.insert(newinfo);
1737 MIL <<
"repo " << alias <<
" modified" << endl;
1746 if ( it != _repos.end() )
1756 for_( it, repoBegin(), repoEnd() )
1758 for_( urlit, (*it).baseUrlsBegin(), (*it).baseUrlsEnd() )
1760 if ( (*urlit).asString(urlview) == url.
asString(urlview) )
1777 assert_alias( service );
1780 if ( hasService( service.
alias() ) )
1786 saveService( toSave );
1799 MIL <<
"added service " << toSave.
alias() << endl;
1806 MIL <<
"Going to delete repo " << alias << endl;
1808 const ServiceInfo & service = getService( alias );
1810 Pathname location = service.
filepath();
1811 if( location.empty() )
1820 if ( tmpSet.size() == 1 )
1827 MIL << alias <<
" sucessfully deleted." << endl;
1833 std::ofstream file(location.c_str());
1840 for_(it, tmpSet.begin(), tmpSet.end())
1842 if( it->alias() != alias )
1843 it->dumpAsIniOn(file);
1846 MIL << alias <<
" sucessfully deleted from file " << location << endl;
1850 RepoCollector rcollector;
1851 getRepositoriesInService( alias,
1852 boost::make_function_output_iterator( bind( &RepoCollector::collect, &rcollector, _1 ) ) );
1854 for_(rit, rcollector.repos.begin(), rcollector.repos.end())
1855 removeRepository(*rit);
1864 ServiceSet services( serviceBegin(), serviceEnd() );
1865 for_( it, services.begin(), services.end() )
1867 if ( !it->enabled() )
1871 refreshService(*it);
1881 assert_alias( service );
1882 assert_url( service );
1886 bool serviceModified =
false;
1887 MIL <<
"Going to refresh service '" << service.
alias() <<
"', url: "<< service.
url() << endl;
1898 serviceModified =
true;
1903 std::string servicesTargetDistro = _options.servicesTargetDistro;
1904 if ( servicesTargetDistro.empty() )
1908 DBG <<
"ServicesTargetDistro: " << servicesTargetDistro << endl;
1911 RepoCollector collector(servicesTargetDistro);
1923 uglyHack.first =
true;
1924 uglyHack.second = e;
1928 for_( it, collector.repos.begin(), collector.repos.end() )
1933 if ( it->baseUrlsEmpty() )
1934 url = service.
url();
1938 url = *it->baseUrlsBegin();
1943 if ( !it->path().empty() )
1952 it->setAlias(
str::form(
"%s:%s", service.
alias().c_str(), it->alias().c_str() ) );
1955 it->setBaseUrl( url );
1957 it->setService( service.
alias() );
1963 RepoInfoList oldRepos;
1964 getRepositoriesInService( service.
alias(), std::back_inserter( oldRepos ) );
1967 for_( it, oldRepos.begin(), oldRepos.end() )
1969 if ( ! foundAliasIn( it->alias(), collector.repos ) )
1973 DBG <<
"Service removes enabled repo " << it->alias() << endl;
1975 serviceModified =
true;
1979 DBG <<
"Service removes disabled repo " << it->alias() << endl;
1981 removeRepository( *it );
1987 for_( it, collector.repos.begin(), collector.repos.end() )
1997 if ( beEnabled ) it->setEnabled(
true);
1998 if ( beDisabled ) it->setEnabled(
false);
2006 serviceModified =
true;
2009 RepoInfoList::iterator oldRepo( findAlias( it->alias(), oldRepos ) );
2010 if ( oldRepo == oldRepos.end() )
2017 DBG <<
"Service adds repo " << it->alias() <<
" " << (it->enabled()?
"enabled":
"disabled") << endl;
2018 addRepository( *it );
2026 bool oldRepoModified =
false;
2031 if ( ! oldRepo->enabled() )
2033 DBG <<
"Service repo " << it->alias() <<
" gets enabled" << endl;
2034 oldRepo->setEnabled(
true );
2035 oldRepoModified =
true;
2039 DBG <<
"Service repo " << it->alias() <<
" stays enabled" << endl;
2042 else if ( beDisabled )
2044 if ( oldRepo->enabled() )
2046 DBG <<
"Service repo " << it->alias() <<
" gets disabled" << endl;
2047 oldRepo->setEnabled(
false );
2048 oldRepoModified =
true;
2052 DBG <<
"Service repo " << it->alias() <<
" stays disabled" << endl;
2057 DBG <<
"Service repo " << it->alias() <<
" stays " << (oldRepo->enabled()?
"enabled":
"disabled") << endl;
2062 if ( oldRepo->url() != it->url() )
2064 DBG <<
"Service repo " << it->alias() <<
" gets new URL " << it->url() << endl;
2065 oldRepo->setBaseUrl( it->url() );
2066 oldRepoModified =
true;
2070 if ( oldRepoModified )
2072 modifyRepository( oldRepo->alias(), *oldRepo );
2081 serviceModified =
true;
2086 if ( serviceModified )
2089 modifyService( service.
alias(), service );
2092 if ( uglyHack.first )
2094 throw( uglyHack.second );
2102 MIL <<
"Going to modify service " << oldAlias << endl;
2110 MIL <<
"Not modifying plugin service '" << oldAlias <<
"'" << endl;
2114 const ServiceInfo & oldService = getService(oldAlias);
2116 Pathname location = oldService.
filepath();
2117 if( location.empty() )
2127 std::ofstream file(location.c_str());
2128 for_(it, tmpSet.begin(), tmpSet.end())
2130 if( *it != oldAlias )
2131 it->dumpAsIniOn(file);
2141 if( oldAlias != service.
alias()
2145 std::vector<RepoInfo> toModify;
2146 getRepositoriesInService(oldAlias, std::back_inserter(toModify));
2147 for_( it, toModify.begin(), toModify.end() )
2150 it->setEnabled(
false);
2157 it->setService(service.
alias());
2158 modifyRepository(it->alias(), *it);
2202 : _pimpl( new
Impl(opt) )
2209 {
return _pimpl->repoEmpty(); }
2212 {
return _pimpl->repoSize(); }
2215 {
return _pimpl->repoBegin(); }
2218 {
return _pimpl->repoEnd(); }
2221 {
return _pimpl->getRepo( alias ); }
2224 {
return _pimpl->hasRepo( alias ); }
2234 std::string host( url_r.
getHost() );
2235 if ( ! host.empty() )
2247 {
return _pimpl->metadataStatus( info ); }
2250 {
return _pimpl->checkIfToRefreshMetadata( info, url, policy ); }
2253 {
return _pimpl->metadataPath( info ); }
2256 {
return _pimpl->packagesPath( info ); }
2259 {
return _pimpl->refreshMetadata( info, policy, progressrcv ); }
2262 {
return _pimpl->cleanMetadata( info, progressrcv ); }
2265 {
return _pimpl->cleanPackages( info, progressrcv ); }
2268 {
return _pimpl->cacheStatus( info ); }
2271 {
return _pimpl->buildCache( info, policy, progressrcv ); }
2274 {
return _pimpl->cleanCache( info, progressrcv ); }
2277 {
return _pimpl->isCached( info ); }
2280 {
return _pimpl->loadFromCache( info, progressrcv ); }
2283 {
return _pimpl->cleanCacheDirGarbage( progressrcv ); }
2286 {
return _pimpl->probe( url, path ); }
2289 {
return _pimpl->probe( url ); }
2292 {
return _pimpl->addRepository( info, progressrcv ); }
2295 {
return _pimpl->addRepositories( url, progressrcv ); }
2298 {
return _pimpl->removeRepository( info, progressrcv ); }
2301 {
return _pimpl->modifyRepository( alias, newinfo, progressrcv ); }
2304 {
return _pimpl->getRepositoryInfo( alias, progressrcv ); }
2307 {
return _pimpl->getRepositoryInfo( url, urlview, progressrcv ); }
2310 {
return _pimpl->serviceEmpty(); }
2313 {
return _pimpl->serviceSize(); }
2316 {
return _pimpl->serviceBegin(); }
2319 {
return _pimpl->serviceEnd(); }
2322 {
return _pimpl->getService( alias ); }
2325 {
return _pimpl->hasService( alias ); }
2328 {
return _pimpl->probeService( url ); }
2331 {
return _pimpl->addService( alias, url ); }
2334 {
return _pimpl->addService( service ); }
2337 {
return _pimpl->removeService( alias ); }
2340 {
return _pimpl->removeService( service ); }
2343 {
return _pimpl->refreshServices(); }
2346 {
return _pimpl->refreshService( alias ); }
2349 {
return _pimpl->refreshService( service ); }
2352 {
return _pimpl->modifyService( oldAlias, service ); }
2357 {
return str << *obj.
_pimpl; }
Pathname packagesPath(const RepoInfo &info) const
RepoManager(const RepoManagerOptions &options=RepoManagerOptions())
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
void removeService(const std::string &alias)
Removes service specified by its name.
thrown when it was impossible to match a repository
Thrown when the repo alias is found to be invalid.
RepoManagerOptions(const Pathname &root_r=Pathname())
Default ctor following ZConfig global settings.
bool hasService(const std::string &alias) const
std::string alias() const
unique identifier for this source.
static const std::string & sha1()
sha1
int exchange(const Pathname &lpath, const Pathname &rpath)
Exchanges two files or directories.
void setCacheStatus(const RepoInfo &info, const RepoStatus &status)
std::string generateFilename(const ServiceInfo &info) 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.
virtual std::ostream & dumpAsIniOn(std::ostream &str) const
Write this RepoInfo object into str in a .repo file format.
Pathname repoRawCachePath
void refreshServices()
Refreshes all enabled services.
bool serviceEmpty() const
Gets true if no service is in RepoManager (so no one in specified location)
void modifyService(const std::string &oldAlias, const ServiceInfo &service)
Modifies service file (rewrites it with new values) and underlying repositories if needed...
Read service data from a .service file.
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Date timestamp() const
timestamp of the repository.
ServiceConstIterator serviceBegin() const
std::string checksum() const
Checksum of the repository.
static ZConfig & instance()
Singleton ctor.
static TmpDir makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
RWCOW_pointer< Impl > _pimpl
Pointer to implementation.
void cleanCacheDirGarbage(const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Remove any subdirectories of cache directories which no longer belong to any of known repositories...
RepoConstIterator repoBegin() const
Pathname filepath() const
File where this repo was read from.
void resetDispose()
Set no dispose function.
bool isCached(const RepoInfo &info) const
RepoStatus metadataStatus(const RepoInfo &info) const
Status of local metadata.
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
#define _PL(MSG1, MSG2, N)
Return translated text (plural form).
bool empty() const
Test for an empty path.
std::string getHost(EEncoding eflag=zypp::url::E_DECODED) const
Returns the hostname or IP from the URL authority.
RefreshCheckStatus
Possibly return state of checkIfRefreshMEtadata function.
Pathname metadataPath(const RepoInfo &info) const
Path where the metadata is downloaded and kept.
const std::string & command() const
The command we're executing.
urls_const_iterator baseUrlsBegin() const
iterator that points at begin of repository urls
RepoSet::size_type RepoSizeType
bool empty() const
Is the status empty?
void loadFromCache(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Load resolvables into the pool.
ServiceConstIterator serviceEnd() const
Iterator to place behind last service in internal storage.
repo::RepoType probe(const Url &url, const Pathname &path) const
Probe repo metadata type.
std::string generateFilename(const RepoInfo &info) const
RepoConstIterator repoBegin() const
void refreshMetadata(const RepoInfo &info, RawMetadataRefreshPolicy policy=RefreshIfNeeded, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Refresh local raw cache.
Pathname packagesPath(const RepoInfo &info) const
Path where the rpm packages are downloaded and kept.
void addService(const std::string &alias, const Url &url)
void touchIndexFile(const RepoInfo &info)
void setAlias(const std::string &alias)
set the repository alias
void init_knownRepositories()
void addRepoToEnable(const std::string &alias_r)
Add alias_r to the set of ReposToEnable.
void removeRepository(const RepoInfo &info, OPT_PROGRESS)
void modifyService(const std::string &oldAlias, const ServiceInfo &newService)
bool toMax()
Set counter value to current max value (unless no range).
void setProbedType(const repo::RepoType &t) const
This allows to adjust the RepoType lazy, from NONE to some probed value, even for const objects...
void setFilepath(const Pathname &filename)
set the path to the .repo file
void refreshService(const ServiceInfo &service)
What is known about a repository.
void removeRepository(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Remove the best matching repository from known repos list.
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Pathname knownServicesPath
void setBaseUrl(const Url &url)
Clears current base URL list and adds url.
bool enabled() const
If enabled is false, then this repository must be ignored as if does not exists, except when checking...
void reposErase(const std::string &alias_r)
Remove a Repository named alias_r.
Service already exists and some unique attribute can't be duplicated.
bool repo_add_probe() const
Whether repository urls should be probed.
urls_const_iterator baseUrlsEnd() const
iterator that points at end of repository urls
std::string targetDistribution() const
This is register.target attribute of the installed base product.
static RepoStatus fromCookieFile(const Pathname &path)
reads the status from a file which contains the checksum and timestamp in each line.
Service without alias was used in an operation.
RepoStatus metadataStatus(const RepoInfo &info) const
RepoSet::const_iterator RepoConstIterator
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
RepoStatus dirStatus(const Pathname &dir)
Gives a cookie for a dir.
Url::asString() view options.
void cleanMetadata(const RepoInfo &info, OPT_PROGRESS)
void modifyRepository(const std::string &alias, const RepoInfo &newinfo, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Modify repository attributes.
Pathname repoSolvCachePath
std::vector< std::string > Arguments
RepoManagerOptions _options
std::string asString() const
Returns a default string representation of the Url object.
ServiceInfo getService(const std::string &alias) const
void refreshService(const std::string &alias)
Refresh specific service.
RepoSizeType repoSize() const
void remember(const Exception &old_r)
Store an other Exception as history.
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).
void removeService(const ServiceInfo &service)
transform_iterator< repo::RepoVariablesUrlReplacer, url_set::const_iterator > urls_const_iterator
Progress callback from another progress.
std::string label() const
Label for use in messages for the user interface.
void addRepository(const RepoInfo &info, OPT_PROGRESS)
static const ServiceType RIS
Repository Index Service (RIS) (formerly known as 'Novell Update' (NU) service)
RepoManager implementation.
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
std::set< RepoInfo > RepoSet
RepoInfo typedefs.
bool toMin()
Set counter value to current min value.
RepoInfo getRepositoryInfo(const std::string &alias, OPT_PROGRESS)
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
static Pool instance()
Singleton ctor.
bool serviceEmpty() const
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
void removeRepository(const RepoInfo &repo)
Log recently removed repository.
Provide a new empty temporary directory and recursively delete it when no longer needed.
void clearReposToDisable()
Clear the set of ReposToDisable.
Lightweight repository attribute value lookup.
std::string asCompleteString() const
Returns a complete string representation of the Url object.
std::ostream & operator<<(std::ostream &str, const Exception &obj)
RepoConstIterator repoEnd() const
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
void cleanCacheDirGarbage(OPT_PROGRESS)
int unlink(const Pathname &path)
Like 'unlink'.
thrown when it was impossible to determine one url for this repo.
static const ServiceType NONE
No service set.
static const SolvAttr repositoryToolVersion
Service type enumeration.
void modifyRepository(const std::string &alias, const RepoInfo &newinfo_r, OPT_PROGRESS)
ServiceSet::const_iterator ServiceConstIterator
std::ostream & operator<<(std::ostream &str, const DeltaCandidates &obj)
repo::ServiceType probeService(const Url &url) const
Probe the type or the service.
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
void setMetadataPath(const Pathname &path)
set the path where the local metadata is stored
void setType(const repo::RepoType &t)
set the repository type
Maintain [min,max] and counter (value) for progress counting.
RepoStatus cacheStatus(const RepoInfo &info) const
Pathname generateNonExistingName(const Pathname &dir, const std::string &basefilename) const
Generate a non existing filename in a directory, using a base name.
void addRepository(const RepoInfo &repo)
Log a newly added repository.
RepoInfo getRepo(const std::string &alias) const
Writing the zypp history fileReference counted signleton for writhing the zypp history file...
void addRepository(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Adds a repository to the list of known repositories.
RepoInfo getRepositoryInfo(const std::string &alias, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Find a matching repository info.
#define _(MSG)
Return translated text.
static const ServiceType PLUGIN
Plugin services are scripts installed on your system that provide the package manager with repositori...
std::string receiveLine()
Read one line from the input stream.
void init_knownServices()
void delRepoToEnable(const std::string &alias_r)
Remove alias_r from the set of ReposToEnable.
static std::string makeStupidAlias(const Url &url_r=Url())
Some stupid string but suitable as alias for your url if nothing better is available.
RefreshCheckStatus checkIfToRefreshMetadata(const RepoInfo &info, const Url &url, RawMetadataRefreshPolicy policy=RefreshIfNeeded)
Checks whether to refresh metadata for specified repository and url.
void cleanCache(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
clean local cache
void cleanCache(const RepoInfo &info, OPT_PROGRESS)
std::string numstring(char n, int w=0)
ServiceSet::size_type ServiceSizeType
bool reposToDisableEmpty() const
static const RepoType NONE
int touch(const Pathname &path)
Change file's modification and access times.
void saveToCookieFile(const Pathname &path) const
save the status information to a cookie file
ServiceInfo getService(const std::string &alias) const
Finds ServiceInfo by alias or return ServiceInfo::noService.
void getRepositoriesInService(const std::string &alias, OutputIterator out) const
void setPackagesPath(const Pathname &path)
set the path where the local packages are stored
std::ostream & copy(std::istream &from_r, std::ostream &to_r)
Copy istream to ostream.
int close()
Wait for the progamm to complete.
bool hasRepo(const std::string &alias) const
Return whether there is a known repository for alias.
static const RepoType RPMMD
creates and provides information about known sources.
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
std::string form(const char *format,...)
Printf style construction of std::string.
RepoStatus cacheStatus(const RepoInfo &info) const
Status of metadata cache.
repo::RepoType type() const
Type of repository,.
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
RepoSizeType repoSize() const
void addService(const ServiceInfo &service)
std::list< RepoInfo > readRepoFile(const Url &repo_file)
Parses repo_file and returns a list of RepoInfo objects corresponding to repositories found within th...
RepoInfo getRepo(const std::string &alias) const
Find RepoInfo by alias or return RepoInfo::noRepo.
static const RepoType YAST2
thrown when it was impossible to determine an alias for this repo.
void buildCache(const RepoInfo &info, CacheBuildPolicy policy=BuildIfNeeded, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Refresh local cache.
Base class for Exception.
void addRepositories(const Url &url, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Adds repositores from a repo file to the list of known repositories.
std::set< ServiceInfo > ServiceSet
ServiceInfo typedefs.
Exception for repository handling.
void saveService(ServiceInfo &service) const
Impl(const RepoManagerOptions &opt)
media::MediaAccessId _mid
static Date now()
Return the current time.
repo::RepoType probe(const Url &url, const Pathname &path=Pathname()) const
ServiceConstIterator serviceEnd() const
Functor thats filter RepoInfo by service which it belongs to.
bool isCached(const RepoInfo &info) const
Whether a repository exists in cache.
bool hasRepo(const std::string &alias) const
Reference counted access to a _Tp object calling a custom Dispose function when the last AutoDispose ...
The repository cache is not built yet so you can't create the repostories from the cache...
void eraseFromPool()
Remove this Repository from it's Pool.
Pathname repoPackagesCachePath
static const ServiceInfo noService
Represents an empty service.
RepoConstIterator repoEnd() const
bool hasService(const std::string &alias) const
Return whether there is a known service for alias.
void removeService(const std::string &alias)
void buildCache(const RepoInfo &info, CacheBuildPolicy policy, OPT_PROGRESS)
bool repoToDisableFind(const std::string &alias_r) const
Whether alias_r is mentioned in ReposToDisable.
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.
ServiceSizeType serviceSize() const
Gets count of service in RepoManager (in specified location)
static const RepoType RPMPLAINDIR
static const std::string & systemRepoAlias()
Reserved system repository alias .
bool repoToEnableFind(const std::string &alias_r) const
Whether alias_r is mentioned in ReposToEnable.
ServiceSizeType serviceSize() const
Local facts about a repository This class represents the status of a repository on the system...
void cleanPackages(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Clean local package cache.
unsigned repo_refresh_delay() const
Amount of time in minutes that must pass before another refresh.
Repository already exists and some unique attribute can't be duplicated.
ServiceConstIterator serviceBegin() const
Iterator to first service in internal storage.
bool set(value_type val_r)
Set new counter value.
std::string getScheme() const
Returns the scheme name of the URL.
Url url() const
Gets url to service.
static bool schemeIsDownloading(const std::string &scheme_r)
http https ftp sftp tftp
void modifyRepository(const RepoInfo &oldrepo, const RepoInfo &newrepo)
Log certain modifications to a repository.
std::ostream & operator<<(std::ostream &str, const RepoManager::Impl &obj)
Impl * clone() const
clone for RWCOW_pointer
urls_size_type baseUrlsSize() const
number of repository urls
Repository addRepoSolv(const Pathname &file_r, const std::string &name_r)
Load Solvables from a solv-file into a Repository named name_r.
std::string asString() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void name(const std::string &name_r)
Set counter name.
Downloader for YUM (rpm-nmd) repositories Encapsulates all the knowledge of which files have to be do...
Pathname metadataPath(const RepoInfo &info) const
void setProbedType(const repo::ServiceType &t) const
void cleanPackages(const RepoInfo &info, OPT_PROGRESS)
void loadFromCache(const RepoInfo &info, OPT_PROGRESS)
std::string hexstring(char n, int w=4)
void addService(const std::string &alias, const Url &url)
Adds new service by it's alias and url.
void refreshMetadata(const RepoInfo &info, RawMetadataRefreshPolicy policy, OPT_PROGRESS)
Service has no or invalid url defined.
void addRepositories(const Url &url, OPT_PROGRESS)
void cleanMetadata(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Clean local metadata.
Pathname path() const
Repository path.
bool hasCredentialsInAuthority() const
Returns true if username and password are encoded in the authority component.
virtual std::ostream & dumpAsIniOn(std::ostream &str) const
Writes ServiceInfo to stream in ".service" format.
repo::ServiceType type() const
void refreshService(const std::string &alias)
iterator begin() const
Iterator to the begin of query results.
Repository type enumeration.
RefreshCheckStatus checkIfToRefreshMetadata(const RepoInfo &info, const Url &url, RawMetadataRefreshPolicy policy)
repo::ServiceType probeService(const Url &url) const