58 #define OPT_PROGRESS const ProgressData::ReceiverFnc & = ProgressData::ReceiverFnc()
73 MediaMounter(
const Url & url_r )
75 media::MediaManager mediamanager;
76 _mid = mediamanager.open( url_r );
77 mediamanager.attach(
_mid );
83 media::MediaManager mediamanager;
84 mediamanager.release(
_mid );
85 mediamanager.close(
_mid );
92 Pathname getPathName(
const Pathname & path_r = Pathname() )
const
94 media::MediaManager mediamanager;
95 return mediamanager.localPath(
_mid, path_r );
104 template <
class Iterator>
105 inline bool foundAliasIn(
const std::string & alias_r, Iterator begin_r, Iterator end_r )
107 for_( it, begin_r, end_r )
108 if ( it->alias() == alias_r )
113 template <
class Container>
114 inline bool foundAliasIn(
const std::string & alias_r,
const Container & cont_r )
115 {
return foundAliasIn( alias_r, cont_r.begin(), cont_r.end() ); }
118 template <
class Iterator>
119 inline Iterator findAlias(
const std::string & alias_r, Iterator begin_r, Iterator end_r )
121 for_( it, begin_r, end_r )
122 if ( it->alias() == alias_r )
127 template <class Container>
128 inline typename Container::iterator findAlias( const
std::
string & alias_r, Container & cont_r )
129 {
return findAlias( alias_r, cont_r.begin(), cont_r.end() ); }
131 template <
class Container>
132 inline typename Container::const_iterator findAlias(
const std::string & alias_r,
const Container & cont_r )
133 {
return findAlias( alias_r, cont_r.begin(), cont_r.end() ); }
137 inline std::string filenameFromAlias(
const std::string & alias_r,
const std::string & stem_r )
139 std::string filename( alias_r );
143 filename = Pathname(filename).extend(
"."+stem_r).asString();
144 MIL <<
"generating filename for " << stem_r <<
" [" << alias_r <<
"] : '" << filename <<
"'" << endl;
168 RepoCollector(
const std::string & targetDistro_)
172 bool collect(
const RepoInfo &repo )
176 && !repo.targetDistribution().empty()
180 <<
"Skipping repository meant for '" << repo.targetDistribution()
181 <<
"' distribution (current distro is '"
187 repos.push_back(repo);
201 std::list<RepoInfo> repositories_in_file(
const Pathname & file )
203 MIL <<
"repo file: " << file << endl;
204 RepoCollector collector;
205 parser::RepoFileReader parser( file, bind( &RepoCollector::collect, &collector, _1 ) );
206 return std::move(collector.repos);
219 std::list<RepoInfo> repositories_in_dir(
const Pathname &dir )
221 MIL <<
"directory " << dir << endl;
222 std::list<RepoInfo>
repos;
223 bool nonroot( geteuid() != 0 );
224 if ( nonroot && ! PathInfo(dir).userMayRX() )
230 std::list<Pathname> entries;
237 str::regex allowedRepoExt(
"^\\.repo(_[0-9]+)?$");
238 for ( std::list<Pathname>::const_iterator it = entries.begin(); it != entries.end(); ++it )
242 if ( nonroot && ! PathInfo(*it).userMayR() )
248 const std::list<RepoInfo> & tmp( repositories_in_file( *it ) );
249 repos.insert( repos.end(), tmp.begin(), tmp.end() );
259 inline void assert_alias(
const RepoInfo & info )
261 if ( info.alias().empty() )
265 if ( info.alias()[0] ==
'.')
267 info,
_(
"Repository alias cannot start with dot.")));
270 inline void assert_alias(
const ServiceInfo & info )
272 if ( info.alias().empty() )
276 if ( info.alias()[0] ==
'.')
278 info,
_(
"Service alias cannot start with dot.")));
283 inline void assert_urls(
const RepoInfo & info )
285 if ( info.baseUrlsEmpty() )
289 inline void assert_url(
const ServiceInfo & info )
291 if ( ! info.url().isValid() )
301 inline Pathname rawcache_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
304 return opt.repoRawCachePath / info.escaped_alias();
315 inline Pathname rawproductdata_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
318 return opt.repoRawCachePath / info.escaped_alias() / info.path();
324 inline Pathname packagescache_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info )
327 return opt.repoPackagesCachePath / info.escaped_alias();
333 inline Pathname solv_path_for_repoinfo(
const RepoManagerOptions &opt,
const RepoInfo &info)
336 return opt.repoSolvCachePath / info.escaped_alias();
342 class ServiceCollector
345 typedef std::set<ServiceInfo> ServiceSet;
347 ServiceCollector( ServiceSet & services_r )
351 bool operator()(
const ServiceInfo & service_r )
const
375 DBG <<
"reading repo file " << repo_file <<
", local path: " << local << endl;
377 return repositories_in_file(local);
388 repoCachePath = Pathname::assertprefix( root_r,
ZConfig::instance().repoCachePath() );
389 repoRawCachePath = Pathname::assertprefix( root_r,
ZConfig::instance().repoMetadataPath() );
390 repoSolvCachePath = Pathname::assertprefix( root_r,
ZConfig::instance().repoSolvfilesPath() );
391 repoPackagesCachePath = Pathname::assertprefix( root_r,
ZConfig::instance().repoPackagesPath() );
392 knownReposPath = Pathname::assertprefix( root_r,
ZConfig::instance().knownReposPath() );
393 knownServicesPath = Pathname::assertprefix( root_r,
ZConfig::instance().knownServicesPath() );
394 pluginsPath = Pathname::assertprefix( root_r,
ZConfig::instance().pluginsPath() );
416 #define OUTS(X) str << " " #X "\t" << obj.X << endl
417 str <<
"RepoManagerOptions (" << obj.
rootDir <<
") {" << endl;
418 OUTS( repoRawCachePath );
419 OUTS( repoSolvCachePath );
420 OUTS( repoPackagesCachePath );
421 OUTS( knownReposPath );
422 OUTS( knownServicesPath );
440 init_knownServices();
441 init_knownRepositories();
450 bool hasRepo(
const std::string & alias )
const
451 {
return foundAliasIn( alias, _repos ); }
461 {
return rawcache_path_for_repoinfo( _options, info ); }
464 {
return packagescache_path_for_repoinfo( _options, info ); }
485 {
return PathInfo(solv_path_for_repoinfo( _options, info ) /
"solv").isExist(); }
510 {
return foundAliasIn( alias,
_services ); }
523 void removeService(
const std::string & alias );
525 { removeService( service.
alias() ); }
531 { refreshService( service.
alias(), options_r ); }
533 void modifyService(
const std::string & oldAlias,
const ServiceInfo & newService );
540 Pathname generateNonExistingName(
const Pathname & dir,
const std::string & basefilename )
const;
543 {
return filenameFromAlias( info.
alias(),
"repo" ); }
546 {
return filenameFromAlias( info.
alias(),
"service" ); }
550 Pathname base = solv_path_for_repoinfo( _options, info );
555 void touchIndexFile(
const RepoInfo & info );
557 template<
typename OutputIterator>
561 std::copy( boost::make_filter_iterator( filter, _repos.begin(), _repos.end() ),
562 boost::make_filter_iterator( filter, _repos.end(), _repos.end() ),
567 void init_knownServices();
568 void init_knownRepositories();
576 friend Impl * rwcowClone<Impl>(
const Impl * rhs );
579 {
return new Impl( *
this ); }
585 {
return str <<
"RepoManager::Impl"; }
592 Pathname servfile = generateNonExistingName( _options.knownServicesPath,
593 generateFilename( service ) );
596 MIL <<
"saving service in " << servfile << endl;
598 std::ofstream file( servfile.c_str() );
605 MIL <<
"done" << endl;
624 const std::string & basefilename )
const
626 std::string final_filename = basefilename;
628 while ( PathInfo(dir + final_filename).isExist() )
633 return dir + Pathname(final_filename);
640 Pathname dir = _options.knownServicesPath;
641 std::list<Pathname> entries;
642 if (PathInfo(dir).isExist())
651 for_(it, entries.begin(), entries.end() )
667 inline void cleanupNonRepoMetadtaFolders(
const Pathname & cachePath_r,
668 const Pathname & defaultCachePath_r,
669 const std::list<std::string> & repoEscAliases_r )
671 if ( cachePath_r != defaultCachePath_r )
674 std::list<std::string> entries;
678 std::set<std::string> oldfiles;
679 set_difference( entries.begin(), entries.end(), repoEscAliases_r.begin(), repoEscAliases_r.end(),
680 std::inserter( oldfiles, oldfiles.end() ) );
681 for (
const std::string & old : oldfiles )
693 MIL <<
"start construct known repos" << endl;
695 if ( PathInfo(_options.knownReposPath).isExist() )
697 std::list<std::string> repoEscAliases;
698 std::list<RepoInfo> orphanedRepos;
699 for (
RepoInfo & repoInfo : repositories_in_dir(_options.knownReposPath) )
702 repoInfo.setMetadataPath( rawcache_path_for_repoinfo(_options, repoInfo) );
704 repoInfo.setPackagesPath( packagescache_path_for_repoinfo(_options, repoInfo) );
706 _repos.insert( repoInfo );
709 const std::string & serviceAlias( repoInfo.service() );
710 if ( ! ( serviceAlias.empty() || hasService( serviceAlias ) ) )
712 WAR <<
"Schedule orphaned service repo for deletion: " << repoInfo << endl;
713 orphanedRepos.push_back( repoInfo );
717 repoEscAliases.push_back(repoInfo.escaped_alias());
721 if ( ! orphanedRepos.empty() )
723 for (
auto & repoInfo : orphanedRepos )
725 MIL <<
"Delete orphaned service repo " << repoInfo.alias() << endl;
731 % repoInfo.alias() );
733 removeRepository( repoInfo );
747 repoEscAliases.sort();
749 cleanupNonRepoMetadtaFolders( _options.repoRawCachePath, defaultCache.
repoRawCachePath, repoEscAliases );
750 cleanupNonRepoMetadtaFolders( _options.repoSolvCachePath, defaultCache.
repoSolvCachePath, repoEscAliases );
751 cleanupNonRepoMetadtaFolders( _options.repoPackagesCachePath, defaultCache.
repoPackagesCachePath, repoEscAliases );
753 MIL <<
"end construct known repos" << endl;
760 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
761 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
766 repokind = probe( productdatapath.asUrl() );
769 switch ( repokind.
toEnum() )
772 status =
RepoStatus( productdatapath/
"repodata/repomd.xml");
776 status =
RepoStatus( productdatapath/
"content" ) &&
RepoStatus( mediarootpath/
"media.1/media" );
795 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
800 repokind = probe( productdatapath.asUrl() );
806 switch ( repokind.
toEnum() )
809 p = Pathname(productdatapath +
"/repodata/repomd.xml");
813 p = Pathname(productdatapath +
"/content");
817 p = Pathname(productdatapath +
"/cookie");
835 MIL <<
"Going to try to check whether refresh is needed for " << url << endl;
838 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
840 RepoStatus oldstatus = metadataStatus( info );
842 if ( oldstatus.
empty() )
844 MIL <<
"No cached metadata, going to refresh" << endl;
845 return REFRESH_NEEDED;
851 MIL <<
"never refresh CD/DVD" << endl;
852 return REPO_UP_TO_DATE;
856 policy = RefreshIfNeededIgnoreDelay;
861 if (policy != RefreshForced && policy != RefreshIfNeededIgnoreDelay)
864 double diff = difftime(
870 DBG <<
"last refresh = " << diff <<
" minutes ago" << endl;
876 WAR <<
"Repository '" << info.
alias() <<
"' was refreshed in the future!" << endl;
880 MIL <<
"Repository '" << info.
alias()
881 <<
"' has been refreshed less than repo.refresh.delay ("
883 <<
") minutes ago. Advising to skip refresh" << endl;
884 return REPO_CHECK_DELAYED;
892 repokind = probe( url, info.
path() );
896 switch ( repokind.
toEnum() )
913 newstatus =
RepoStatus( MediaMounter(url).getPathName(info.
path()) );
923 bool refresh =
false;
924 if ( oldstatus == newstatus )
926 MIL <<
"repo has not changed" << endl;
927 if ( policy == RefreshForced )
929 MIL <<
"refresh set to forced" << endl;
935 MIL <<
"repo has changed, going to refresh" << endl;
940 touchIndexFile(info);
942 return refresh ? REFRESH_NEEDED : REPO_UP_TO_DATE;
948 ERR <<
"refresh check failed for " << url << endl;
952 return REFRESH_NEEDED;
962 RepoException rexception( info,
_PL(
"Valid metadata not found at specified URL",
963 "Valid metadata not found at specified URLs",
975 if (checkIfToRefreshMetadata(info, url, policy)!=REFRESH_NEEDED)
978 MIL <<
"Going to refresh metadata from " << url << endl;
986 repokind = probe( *it, info.
path() );
993 for_( it, repoBegin(), repoEnd() )
995 if ( info.
alias() == (*it).alias() )
998 modifiedrepo.
setType( repokind );
999 modifyRepository( info.
alias(), modifiedrepo );
1006 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1017 Exception ex(
_(
"Can't create metadata cache directory."));
1025 shared_ptr<repo::Downloader> downloader_ptr;
1027 MIL <<
"Creating downloader for [ " << info.
alias() <<
" ]" << endl;
1040 for_( it, repoBegin(), repoEnd() )
1042 Pathname cachepath(rawcache_path_for_repoinfo( _options, *it ));
1043 if ( PathInfo(cachepath).isExist() )
1044 downloader_ptr->addCachePath(cachepath);
1047 downloader_ptr->download( media, tmpdir.
path() );
1051 MediaMounter media( url );
1054 Pathname productpath( tmpdir.
path() / info.
path() );
1073 ERR <<
"Trying another url..." << endl;
1082 ERR <<
"No more urls..." << endl;
1091 progress.
sendTo(progressfnc);
1101 progress.
sendTo(progressfnc);
1111 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1112 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
1119 RepoStatus raw_metadata_status = metadataStatus(info);
1120 if ( raw_metadata_status.
empty() )
1125 refreshMetadata(info, RefreshIfNeeded, progressrcv );
1126 raw_metadata_status = metadataStatus(info);
1129 bool needs_cleaning =
false;
1130 if ( isCached( info ) )
1132 MIL << info.
alias() <<
" is already cached." << endl;
1135 if ( cache_status == raw_metadata_status )
1137 MIL << info.
alias() <<
" cache is up to date with metadata." << endl;
1138 if ( policy == BuildIfNeeded ) {
1142 MIL << info.
alias() <<
" cache rebuild is forced" << endl;
1146 needs_cleaning =
true;
1160 MIL << info.
alias() <<
" building cache..." << info.
type() << endl;
1162 Pathname base = solv_path_for_repoinfo( _options, info);
1170 if( ! PathInfo(base).userMayW() )
1172 Exception ex(
str::form(
_(
"Can't create cache at %s - no writing permissions."), base.c_str()) );
1175 Pathname solvfile = base /
"solv";
1181 switch ( repokind.
toEnum() )
1185 repokind = probe( productdatapath.asUrl() );
1191 MIL <<
"repo type is " << repokind << endl;
1193 switch ( repokind.
toEnum() )
1201 scoped_ptr<MediaMounter> forPlainDirs;
1204 cmd.push_back(
"repo2solv" );
1206 cmd.push_back(
"-o" );
1207 cmd.push_back( solvfile.asString() );
1208 cmd.push_back(
"-X" );
1212 forPlainDirs.reset(
new MediaMounter( *info.
baseUrlsBegin() ) );
1214 cmd.push_back(
"-R" );
1216 cmd.push_back( forPlainDirs->getPathName( info.
path() ).c_str() );
1219 cmd.push_back( productdatapath.asString() );
1222 std::string errdetail;
1225 WAR <<
" " << output;
1226 if ( errdetail.empty() ) {
1230 errdetail += output;
1233 int ret = prog.
close();
1250 setCacheStatus(info, raw_metadata_status);
1251 MIL <<
"Commit cache.." << endl;
1259 MIL <<
"going to probe the repo type at " << url <<
" (" << path <<
")" << endl;
1265 MIL <<
"Probed type NONE (not exists) at " << url <<
" (" << path <<
")" << endl;
1277 bool gotMediaException =
false;
1285 MIL <<
"Probed type RPMMD at " << url <<
" (" << path <<
")" << endl;
1292 DBG <<
"problem checking for repodata/repomd.xml file" << endl;
1294 gotMediaException =
true;
1301 MIL <<
"Probed type YAST2 at " << url <<
" (" << path <<
")" << endl;
1308 DBG <<
"problem checking for content file" << endl;
1310 gotMediaException =
true;
1316 MediaMounter media( url );
1317 if ( PathInfo(media.getPathName()/path).isDir() )
1320 MIL <<
"Probed type RPMPLAINDIR at " << url <<
" (" << path <<
")" << endl;
1334 if (gotMediaException)
1337 MIL <<
"Probed type NONE at " << url <<
" (" << path <<
")" << endl;
1345 MIL <<
"Going to clean up garbage in cache dirs" << endl;
1348 progress.
sendTo(progressrcv);
1351 std::list<Pathname> cachedirs;
1352 cachedirs.push_back(_options.repoRawCachePath);
1353 cachedirs.push_back(_options.repoPackagesCachePath);
1354 cachedirs.push_back(_options.repoSolvCachePath);
1356 for_( dir, cachedirs.begin(), cachedirs.end() )
1358 if ( PathInfo(*dir).isExist() )
1360 std::list<Pathname> entries;
1365 unsigned sdircount = entries.size();
1366 unsigned sdircurrent = 1;
1367 for_( subdir, entries.begin(), entries.end() )
1371 for_( r, repoBegin(), repoEnd() )
1372 if ( subdir->basename() == r->escaped_alias() )
1373 { found =
true;
break; }
1378 progress.
set( progress.
val() + sdircurrent * 100 / sdircount );
1383 progress.
set( progress.
val() + 100 );
1393 progress.
sendTo(progressrcv);
1396 MIL <<
"Removing raw metadata cache for " << info.
alias() << endl;
1407 Pathname solvfile = solv_path_for_repoinfo(_options, info) /
"solv";
1409 if ( ! PathInfo(solvfile).isExist() )
1434 MIL <<
"Try to handle exception by rebuilding the solv-file" << endl;
1435 cleanCache( info, progressrcv );
1436 buildCache( info, BuildIfNeeded, progressrcv );
1454 MIL <<
"Try adding repo " << info << endl;
1457 if ( _repos.find(tosave) != _repos.end() )
1461 if ( _options.probe )
1463 DBG <<
"unknown repository type, probing" << endl;
1481 Pathname repofile = generateNonExistingName(
1482 _options.knownReposPath, generateFilename(tosave));
1484 MIL <<
"Saving repo in " << repofile << endl;
1486 std::ofstream file(repofile.c_str());
1500 RepoInfo & oinfo( const_cast<RepoInfo &>(info) );
1504 _repos.insert(tosave);
1509 bool havePasswords =
false;
1511 if ( urlit->hasCredentialsInAuthority() )
1513 havePasswords =
true;
1517 if ( havePasswords )
1523 if (urlit->hasCredentialsInAuthority())
1531 MIL <<
"done" << endl;
1538 for ( std::list<RepoInfo>::const_iterator it = repos.begin();
1543 for_ ( kit, repoBegin(), repoEnd() )
1545 if ( (*it).alias() == (*kit).alias() )
1547 ERR <<
"To be added repo " << (*it).alias() <<
" conflicts with existing repo " << (*kit).alias() << endl;
1553 std::string filename = Pathname(url.
getPathName()).basename();
1555 if ( filename == Pathname() )
1564 Pathname repofile = generateNonExistingName(_options.knownReposPath, filename);
1566 MIL <<
"Saving " << repos.size() <<
" repo" << ( repos.size() ?
"s" :
"" ) <<
" in " << repofile << endl;
1568 std::ofstream file(repofile.c_str());
1575 for ( std::list<RepoInfo>::iterator it = repos.begin();
1579 MIL <<
"Saving " << (*it).alias() << endl;
1580 it->setFilepath(repofile.asString());
1581 it->dumpAsIniOn(file);
1587 MIL <<
"done" << endl;
1599 MIL <<
"Going to delete repo " << info.
alias() << endl;
1601 for_( it, repoBegin(), repoEnd() )
1606 if ( (!info.
alias().empty()) && ( info.
alias() != (*it).alias() ) )
1621 std::list<RepoInfo> filerepos = repositories_in_file(todelete.
filepath());
1622 if ( (filerepos.size() == 1) && ( filerepos.front().alias() == todelete.
alias() ) )
1630 MIL << todelete.
alias() <<
" successfully deleted." << endl;
1642 std::ofstream file(todelete.
filepath().c_str());
1648 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1649 fit != filerepos.end();
1652 if ( (*fit).alias() != todelete.
alias() )
1653 (*fit).dumpAsIniOn(file);
1661 if ( isCached(todelete) )
1662 cleanCache( todelete, cSubprogrcv);
1664 cleanMetadata( todelete, mSubprogrcv );
1665 cleanPackages( todelete, pSubprogrcv );
1666 _repos.erase(todelete);
1667 MIL << todelete.
alias() <<
" successfully deleted." << endl;
1681 RepoInfo toedit = getRepositoryInfo(alias);
1685 if ( alias != newinfo.
alias() && hasRepo( newinfo.
alias() ) )
1697 std::list<RepoInfo> filerepos = repositories_in_file(toedit.
filepath());
1707 std::ofstream file(toedit.
filepath().c_str());
1713 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1714 fit != filerepos.end();
1719 if ( (*fit).alias() != toedit.
alias() )
1720 (*fit).dumpAsIniOn(file);
1726 _repos.erase(toedit);
1727 _repos.insert(newinfo);
1729 MIL <<
"repo " << alias <<
" modified" << endl;
1738 if ( it != _repos.end() )
1748 for_( it, repoBegin(), repoEnd() )
1750 for_( urlit, (*it).baseUrlsBegin(), (*it).baseUrlsEnd() )
1752 if ( (*urlit).asString(urlview) == url.
asString(urlview) )
1769 assert_alias( service );
1772 if ( hasService( service.
alias() ) )
1778 saveService( toSave );
1791 MIL <<
"added service " << toSave.
alias() << endl;
1798 MIL <<
"Going to delete service " << alias << endl;
1800 const ServiceInfo & service = getService( alias );
1802 Pathname location = service.
filepath();
1803 if( location.empty() )
1812 if ( tmpSet.size() == 1 )
1819 MIL << alias <<
" successfully deleted." << endl;
1825 std::ofstream file(location.c_str());
1832 for_(it, tmpSet.begin(), tmpSet.end())
1834 if( it->alias() != alias )
1835 it->dumpAsIniOn(file);
1838 MIL << alias <<
" successfully deleted from file " << location << endl;
1842 RepoCollector rcollector;
1843 getRepositoriesInService( alias,
1844 boost::make_function_output_iterator( bind( &RepoCollector::collect, &rcollector, _1 ) ) );
1846 for_(rit, rcollector.repos.begin(), rcollector.repos.end())
1847 removeRepository(*rit);
1856 ServiceSet services( serviceBegin(), serviceEnd() );
1857 for_( it, services.begin(), services.end() )
1859 if ( !it->enabled() )
1863 refreshService(*it, options_r);
1873 assert_alias( service );
1874 assert_url( service );
1878 bool serviceModified =
false;
1879 MIL <<
"Going to refresh service '" << service.
alias() <<
"', url: "<< service.
url() <<
", opts: " << options_r << endl;
1890 serviceModified =
true;
1895 std::string servicesTargetDistro = _options.servicesTargetDistro;
1896 if ( servicesTargetDistro.empty() )
1900 DBG <<
"ServicesTargetDistro: " << servicesTargetDistro << endl;
1903 RepoCollector collector(servicesTargetDistro);
1915 uglyHack.first =
true;
1916 uglyHack.second = e;
1925 for_( it, collector.repos.begin(), collector.repos.end() )
1928 it->setAlias(
str::form(
"%s:%s", service.
alias().c_str(), it->alias().c_str() ) );
1930 it->setService( service.
alias() );
1933 newRepoStates[it->alias()] = *it;
1937 if ( it->baseUrlsEmpty() )
1938 url = service.
url();
1942 url = *it->baseUrlsBegin();
1947 if ( !it->path().empty() )
1956 it->setBaseUrl( url );
1962 RepoInfoList oldRepos;
1963 getRepositoriesInService( service.
alias(), std::back_inserter( oldRepos ) );
1967 for_( oldRepo, oldRepos.begin(), oldRepos.end() )
1969 if ( ! foundAliasIn( oldRepo->alias(), collector.repos ) )
1971 if ( oldRepo->enabled() )
1974 const auto & last = service.
repoStates().find( oldRepo->alias() );
1975 if ( last != service.
repoStates().end() && ! last->second.enabled )
1977 DBG <<
"Service removes user enabled repo " << oldRepo->alias() << endl;
1979 serviceModified =
true;
1982 DBG <<
"Service removes enabled repo " << oldRepo->alias() << endl;
1985 DBG <<
"Service removes disabled repo " << oldRepo->alias() << endl;
1987 removeRepository( *oldRepo );
1993 for_( it, collector.repos.begin(), collector.repos.end() )
1999 TriBool toBeEnabled( indeterminate );
2000 DBG <<
"Service request to " << (it->enabled()?
"enable":
"disable") <<
" service repo " << it->alias() << endl;
2002 if ( options_r.testFlag( RefreshService_restoreStatus ) )
2004 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() << endl;
2016 DBG <<
"User request to enable service repo " << it->alias() << endl;
2022 serviceModified =
true;
2026 DBG <<
"User request to disable service repo " << it->alias() << endl;
2027 toBeEnabled =
false;
2031 RepoInfoList::iterator oldRepo( findAlias( it->alias(), oldRepos ) );
2032 if ( oldRepo == oldRepos.end() )
2037 if ( ! indeterminate(toBeEnabled) )
2038 it->setEnabled( toBeEnabled );
2040 DBG <<
"Service adds repo " << it->alias() <<
" " << (it->enabled()?
"enabled":
"disabled") << endl;
2041 addRepository( *it );
2046 bool oldRepoModified =
false;
2048 if ( indeterminate(toBeEnabled) )
2052 if ( oldRepo->enabled() == it->enabled() )
2053 toBeEnabled = it->enabled();
2054 else if (options_r.testFlag( RefreshService_restoreStatus ) )
2056 toBeEnabled = it->enabled();
2057 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() <<
" forces " << (toBeEnabled?
"enabled":
"disabled") << endl;
2061 const auto & last = service.
repoStates().find( oldRepo->alias() );
2062 if ( last == service.
repoStates().end() || last->second.enabled != it->enabled() )
2063 toBeEnabled = it->enabled();
2066 toBeEnabled = oldRepo->enabled();
2067 DBG <<
"User modified service repo " << it->alias() <<
" may stay " << (toBeEnabled?
"enabled":
"disabled") << endl;
2073 if ( toBeEnabled == oldRepo->enabled() )
2075 DBG <<
"Service repo " << it->alias() <<
" stays " << (oldRepo->enabled()?
"enabled":
"disabled") << endl;
2077 else if ( toBeEnabled )
2079 DBG <<
"Service repo " << it->alias() <<
" gets enabled" << endl;
2080 oldRepo->setEnabled(
true );
2081 oldRepoModified =
true;
2085 DBG <<
"Service repo " << it->alias() <<
" gets disabled" << endl;
2086 oldRepo->setEnabled(
false );
2087 oldRepoModified =
true;
2093 if ( oldRepo->autorefresh() != it->autorefresh() )
2095 DBG <<
"Service repo " << it->alias() <<
" gets new AUTOREFRESH " << it->autorefresh() << endl;
2096 oldRepo->setAutorefresh( it->autorefresh() );
2097 oldRepoModified =
true;
2101 if ( oldRepo->priority() != it->priority() )
2103 DBG <<
"Service repo " << it->alias() <<
" gets new PRIORITY " << it->priority() << endl;
2104 oldRepo->setPriority( it->priority() );
2105 oldRepoModified =
true;
2110 if ( oldRepo->url() != it->url() )
2112 DBG <<
"Service repo " << it->alias() <<
" gets new URL " << it->url() << endl;
2113 oldRepo->setBaseUrl( it->url() );
2114 oldRepoModified =
true;
2118 if ( oldRepoModified )
2120 modifyRepository( oldRepo->alias(), *oldRepo );
2129 serviceModified =
true;
2136 serviceModified =
true;
2144 modifyService( service.
alias(), service );
2147 if ( uglyHack.first )
2149 throw( uglyHack.second );
2157 MIL <<
"Going to modify service " << oldAlias << endl;
2168 const ServiceInfo & oldService = getService(oldAlias);
2170 Pathname location = oldService.
filepath();
2171 if( location.empty() )
2181 std::ofstream file(location.c_str());
2182 for_(it, tmpSet.begin(), tmpSet.end())
2184 if( *it != oldAlias )
2185 it->dumpAsIniOn(file);
2195 if ( oldAlias != service.
alias()
2198 std::vector<RepoInfo> toModify;
2199 getRepositoriesInService(oldAlias, std::back_inserter(toModify));
2200 for_( it, toModify.begin(), toModify.end() )
2207 const auto & last = service.
repoStates().find( it->alias() );
2209 it->setEnabled( last->second.enabled );
2212 it->setEnabled(
false );
2215 if ( oldAlias != service.
alias() )
2216 it->setService(service.
alias());
2218 modifyRepository(it->alias(), *it);
2262 : _pimpl( new
Impl(opt) )
2294 std::string host( url_r.
getHost() );
2295 if ( ! host.empty() )
2417 {
return str << *obj.
_pimpl; }
void saveToCookieFile(const Pathname &path_r) const
Save the status information to a cookie file.
Pathname packagesPath(const RepoInfo &info) const
RepoManager(const RepoManagerOptions &options=RepoManagerOptions())
static const ValueType day
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.
RepoStatus status(MediaSetAccess &media)
Status of the remote repository.
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.
void refreshServices(const RefreshServiceOptions &options_r)
Pathname repoRawCachePath
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
The time the data were changed the last time.
ServiceConstIterator serviceBegin() const
static ZConfig & instance()
Singleton ctor.
static TmpDir makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
void refreshService(const std::string &alias, const RefreshServiceOptions &options_r)
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
void refreshServices(const RefreshServiceOptions &options_r=RefreshServiceOptions())
Refreshes all enabled services.
Service plugin is immutable.
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
Whether the status is empty (default constucted)
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()
String related utilities and Regular expression matching.
void addRepoToEnable(const std::string &alias_r)
Add alias_r to the set of ReposToEnable.
void removeRepository(const RepoInfo &info, OPT_PROGRESS)
RefreshServiceFlags RefreshServiceOptions
Options tuning RefreshService.
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 refreshService(const std::string &alias, const RefreshServiceOptions &options_r=RefreshServiceOptions())
Refresh specific service.
void setFilepath(const Pathname &filename)
set the path to the .repo file
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.
const RepoStates & repoStates() const
Access the remembered repository states.
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.
void refreshService(const ServiceInfo &service, const RefreshServiceOptions &options_r)
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.
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.
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.
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
RepoSizeType repoSize() const
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
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::map< std::string, RepoState > RepoStates
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.
format formatNAC(const std::string &string_r)
A formater with (N)o (A)rgument (C)heck.
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
void setRepoStates(RepoStates newStates_r)
Remember a new set of repository states.
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
static bool error(const MessageString &msg_r, const UserData &userData_r=UserData())
send error text
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...
static bool schemeIsVolatile(const std::string &scheme_r)
cd dvd
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...
Base Exception for service handling.
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.
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).
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
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
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
Track changing files or directories.
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
static bool warning(const MessageString &msg_r, const UserData &userData_r=UserData())
send warning text
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
Easy-to use interface to the ZYPP dependency resolver.
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.
static bool schemeIsLocal(const std::string &scheme_r)
hd cd dvd dir file iso
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
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