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>
65#define OPT_PROGRESS const ProgressData::ReceiverFnc & = ProgressData::ReceiverFnc()
77 const char * env = getenv(
"ZYPP_PLUGIN_APPDATA_FORCE_COLLECT");
107 class UrlCredentialExtractor
110 UrlCredentialExtractor(
Pathname & root_r )
114 ~UrlCredentialExtractor()
115 {
if ( _cmPtr )
_cmPtr->save(); }
118 bool collect(
const Url & url_r )
123 if ( !_cmPtr )
_cmPtr.reset(
new media::CredentialManager( _root ) );
124 _cmPtr->addUserCred( url_r );
129 template<
class TContainer>
130 bool collect(
const TContainer & urls_r )
131 {
bool ret =
false;
for (
const Url & url : urls_r ) {
if ( collect( url ) && !ret ) ret =
true; }
return ret; }
134 bool extract(
Url & url_r )
136 bool ret = collect( url_r );
142 template<
class TContainer>
143 bool extract( TContainer & urls_r )
144 {
bool ret =
false;
for (
Url & url : urls_r ) {
if ( extract( url ) && !ret ) ret =
true; }
return ret; }
163 MediaMounter(
const Url & url_r )
175 mediamanager.
close( _mid );
185 return mediamanager.
localPath( _mid, path_r );
194 template <
class Iterator>
195 inline bool foundAliasIn(
const std::string & alias_r, Iterator begin_r, Iterator end_r )
197 for_( it, begin_r, end_r )
198 if ( it->alias() == alias_r )
203 template <
class Container>
204 inline bool foundAliasIn(
const std::string & alias_r,
const Container & cont_r )
205 {
return foundAliasIn( alias_r, cont_r.begin(), cont_r.end() ); }
208 template <
class Iterator>
209 inline Iterator findAlias(
const std::string & alias_r, Iterator begin_r, Iterator end_r )
211 for_( it, begin_r, end_r )
212 if ( it->alias() == alias_r )
217 template <
class Container>
218 inline typename Container::iterator findAlias(
const std::string & alias_r, Container & cont_r )
219 {
return findAlias( alias_r, cont_r.begin(), cont_r.end() ); }
221 template <
class Container>
222 inline typename Container::const_iterator findAlias(
const std::string & alias_r,
const Container & cont_r )
223 {
return findAlias( alias_r, cont_r.begin(), cont_r.end() ); }
227 inline std::string filenameFromAlias(
const std::string & alias_r,
const std::string & stem_r )
229 std::string filename( alias_r );
234 MIL <<
"generating filename for " << stem_r <<
" [" << alias_r <<
"] : '" << filename <<
"'" << endl;
258 RepoCollector(
const std::string & targetDistro_)
262 bool collect(
const RepoInfo &repo )
271 <<
"' distribution (current distro is '"
277 repos.push_back(repo);
291 std::list<RepoInfo> repositories_in_file(
const Pathname & file )
293 MIL <<
"repo file: " << file << endl;
294 RepoCollector collector;
296 return std::move(collector.repos);
309 std::list<RepoInfo> repositories_in_dir(
const Pathname &dir )
311 MIL <<
"directory " << dir << endl;
312 std::list<RepoInfo>
repos;
313 bool nonroot( geteuid() != 0 );
314 if ( nonroot && !
PathInfo(dir).userMayRX() )
320 std::list<Pathname> entries;
327 str::regex allowedRepoExt(
"^\\.repo(_[0-9]+)?$");
328 for ( std::list<Pathname>::const_iterator it = entries.begin(); it != entries.end(); ++it )
338 const std::list<RepoInfo> & tmp( repositories_in_file( *it ) );
339 repos.insert(
repos.end(), tmp.begin(), tmp.end() );
349 inline void assert_alias(
const RepoInfo & info )
351 if ( info.
alias().empty() )
355 if ( info.
alias()[0] ==
'.')
357 info,
_(
"Repository alias cannot start with dot.")));
360 inline void assert_alias(
const ServiceInfo & info )
362 if ( info.
alias().empty() )
366 if ( info.
alias()[0] ==
'.')
368 info,
_(
"Service alias cannot start with dot.")));
373 inline void assert_urls(
const RepoInfo & info )
391 inline bool isTmpRepo(
const RepoInfo & info_r )
415 {
return rawcache_path_for_repoinfo( opt, info ) / info.
path(); }
438 class ServiceCollector
441 typedef std::set<ServiceInfo> ServiceSet;
443 ServiceCollector( ServiceSet & services_r )
447 bool operator()(
const ServiceInfo & service_r )
const
459 inline bool autoPruneInDir(
const Pathname & path_r )
469 DBG <<
"reading repo file " << repo_file <<
", local path: " << local << endl;
471 return repositories_in_file(local);
510#define OUTS(X) str << " " #X "\t" << obj.X << endl
511 str <<
"RepoManagerOptions (" << obj.
rootDir <<
") {" << endl;
512 OUTS( repoRawCachePath );
513 OUTS( repoSolvCachePath );
514 OUTS( repoPackagesCachePath );
515 OUTS( knownReposPath );
516 OUTS( knownServicesPath );
533 , _pluginRepoverification( _options.pluginsPath/
"repoverification", _options.rootDir )
535 init_knownServices();
536 init_knownRepositories();
542 if ( ( _reposDirty || env::ZYPP_PLUGIN_APPDATA_FORCE_COLLECT() )
543 && geteuid() == 0 && ( _options.rootDir.empty() || _options.rootDir ==
"/" ) )
546 std::list<Pathname> entries;
547 filesystem::readdir( entries, _options.pluginsPath/
"appdata",
false );
548 if ( ! entries.empty() )
551 cmd.push_back(
"<" );
552 cmd.push_back(
">" );
553 cmd.push_back(
"PROGRAM" );
554 for (
const auto & rinfo :
repos() )
556 if ( ! rinfo.enabled() )
558 cmd.push_back(
"-R" );
559 cmd.push_back( rinfo.alias() );
560 cmd.push_back(
"-t" );
561 cmd.push_back( rinfo.type().asString() );
562 cmd.push_back(
"-p" );
563 cmd.push_back( (rinfo.metadataPath()/rinfo.path()).asString() );
566 for_( it, entries.begin(), entries.end() )
589 bool hasRepo(
const std::string & alias )
const
590 {
return foundAliasIn( alias,
repos() ); }
595 return it ==
repos().end() ? RepoInfo::noRepo : *it;
600 {
return rawcache_path_for_repoinfo( _options, info ); }
603 {
return packagescache_path_for_repoinfo( _options, info ); }
607 RefreshCheckStatus checkIfToRefreshMetadata(
const RepoInfo & info,
const Url & url, RawMetadataRefreshPolicy policy );
625 {
return PathInfo(solv_path_for_repoinfo( _options, info ) /
"solv").
isExist(); }
628 {
return RepoStatus::fromCookieFile(solv_path_for_repoinfo(_options, info) /
"cookie"); }
650 {
return foundAliasIn( alias,
_services ); }
655 return it ==
_services.end() ? ServiceInfo::noService : *it;
663 void removeService(
const std::string & alias );
665 { removeService( service.
alias() ); }
667 void refreshServices(
const RefreshServiceOptions & options_r );
669 void refreshService(
const std::string & alias,
const RefreshServiceOptions & options_r );
671 { refreshService( service.
alias(), options_r ); }
673 void modifyService(
const std::string & oldAlias,
const ServiceInfo & newService );
685 {
return filenameFromAlias( info.
alias(),
"repo" ); }
688 {
return filenameFromAlias( info.
alias(),
"service" ); }
692 Pathname base = solv_path_for_repoinfo( _options, info );
693 filesystem::assert_dir(base);
699 template<
typename OutputIterator>
703 std::copy( boost::make_filter_iterator( filter,
repos().begin(),
repos().end() ),
704 boost::make_filter_iterator( filter,
repos().end(),
repos().end() ),
725 friend Impl * rwcowClone<Impl>(
const Impl * rhs );
728 {
return new Impl( *
this ); }
734 {
return str <<
"RepoManager::Impl"; }
738 void RepoManager::Impl::saveService(
ServiceInfo & service )
const
741 Pathname servfile = generateNonExistingName( _options.knownServicesPath,
742 generateFilename( service ) );
745 MIL <<
"saving service in " << servfile << endl;
747 std::ofstream file( servfile.
c_str() );
754 MIL <<
"done" << endl;
773 const std::string & basefilename )
const
775 std::string final_filename = basefilename;
777 while (
PathInfo(dir + final_filename).isExist() )
782 return dir +
Pathname(final_filename);
787 void RepoManager::Impl::init_knownServices()
789 Pathname dir = _options.knownServicesPath;
790 std::list<Pathname> entries;
800 for_(it, entries.begin(), entries.end() )
816 inline void cleanupNonRepoMetadtaFolders(
const Pathname & cachePath_r,
817 const Pathname & defaultCachePath_r,
818 const std::list<std::string> & repoEscAliases_r )
820 if ( cachePath_r != defaultCachePath_r )
823 std::list<std::string> entries;
827 std::set<std::string> oldfiles;
828 set_difference( entries.begin(), entries.end(), repoEscAliases_r.begin(), repoEscAliases_r.end(),
829 std::inserter( oldfiles, oldfiles.end() ) );
835 for (
const std::string & old : oldfiles )
839 pi( cachePath_r/old );
849 void RepoManager::Impl::init_knownRepositories()
851 MIL <<
"start construct known repos" << endl;
855 std::list<std::string> repoEscAliases;
856 std::list<RepoInfo> orphanedRepos;
857 for (
RepoInfo & repoInfo : repositories_in_dir(_options.knownReposPath) )
860 repoInfo.setMetadataPath( rawcache_path_for_repoinfo(_options, repoInfo) );
862 repoInfo.setPackagesPath( packagescache_path_for_repoinfo(_options, repoInfo) );
864 _reposX.insert( repoInfo );
867 const std::string & serviceAlias( repoInfo.service() );
868 if ( ! ( serviceAlias.empty() || hasService( serviceAlias ) ) )
870 WAR <<
"Schedule orphaned service repo for deletion: " << repoInfo << endl;
871 orphanedRepos.push_back( repoInfo );
875 repoEscAliases.push_back(repoInfo.escaped_alias());
879 if ( ! orphanedRepos.empty() )
881 for (
const auto & repoInfo : orphanedRepos )
883 MIL <<
"Delete orphaned service repo " << repoInfo.alias() << endl;
889 % repoInfo.alias() );
891 removeRepository( repoInfo );
905 repoEscAliases.sort();
906 cleanupNonRepoMetadtaFolders( _options.repoRawCachePath,
909 cleanupNonRepoMetadtaFolders( _options.repoSolvCachePath,
913 if ( autoPruneInDir( _options.repoPackagesCachePath ) )
914 cleanupNonRepoMetadtaFolders( _options.repoPackagesCachePath,
918 MIL <<
"end construct known repos" << endl;
925 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
926 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
931 repokind = probeCache( productdatapath );
938 switch ( repokind.
toEnum() )
941 status =
RepoStatus( productdatapath/
"repodata/repomd.xml");
943 status = status &&
RepoStatus( mediarootpath/
"media.1/media" );
947 status =
RepoStatus( productdatapath/
"content" ) &&
RepoStatus( mediarootpath/
"media.1/media" );
961 if ( ! status.
empty() )
968 void RepoManager::Impl::touchIndexFile(
const RepoInfo & info )
970 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
975 repokind = probeCache( productdatapath );
981 switch ( repokind.
toEnum() )
984 p =
Pathname(productdatapath +
"/repodata/repomd.xml");
988 p =
Pathname(productdatapath +
"/content");
992 p =
Pathname(productdatapath +
"/cookie");
1010 MIL <<
"Check if to refresh repo " << info.
alias() <<
" at " << url <<
" (" << info.
type() <<
")" << endl;
1015 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1017 RepoStatus oldstatus = metadataStatus( info );
1019 if ( oldstatus.
empty() )
1021 MIL <<
"No cached metadata, going to refresh" << endl;
1022 return REFRESH_NEEDED;
1027 MIL <<
"Never refresh CD/DVD" << endl;
1028 return REPO_UP_TO_DATE;
1031 if ( policy == RefreshForced )
1033 MIL <<
"Forced refresh!" << endl;
1034 return REFRESH_NEEDED;
1039 policy = RefreshIfNeededIgnoreDelay;
1043 if ( policy != RefreshIfNeededIgnoreDelay )
1048 RepoStatus cachestatus = cacheStatus( info );
1050 if ( oldstatus == cachestatus )
1058 WAR <<
"Repository '" << info.
alias() <<
"' was refreshed in the future!" << endl;
1062 MIL <<
"Repository '" << info.
alias()
1063 <<
"' has been refreshed less than repo.refresh.delay ("
1065 <<
") minutes ago. Advising to skip refresh" << endl;
1066 return REPO_CHECK_DELAYED;
1071 MIL <<
"Metadata and solv cache don't match. Check data on server..." << endl;
1078 repokind = probe( url, info.
path() );
1082 switch ( repokind.
toEnum() )
1109 if ( oldstatus == newstatus )
1111 MIL <<
"repo has not changed" << endl;
1112 touchIndexFile( info );
1113 return REPO_UP_TO_DATE;
1117 MIL <<
"repo has changed, going to refresh" << endl;
1118 return REFRESH_NEEDED;
1124 ERR <<
"refresh check failed for " << url << endl;
1128 return REFRESH_NEEDED;
1141 RepoException rexception( info,
PL_(
"Valid metadata not found at specified URL",
1142 "Valid metadata not found at specified URLs",
1156 if (checkIfToRefreshMetadata(info, url, policy)!=REFRESH_NEEDED)
1159 MIL <<
"Going to refresh metadata from " << url << endl;
1167 if ( repokind != probed )
1171 for_( it, repoBegin(), repoEnd() )
1173 if ( info.
alias() == (*it).alias() )
1176 modifiedrepo.
setType( repokind );
1190 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1199 if( tmpdir.path().empty() )
1201 Exception ex(
_(
"Can't create metadata cache directory."));
1211 MIL <<
"Creating downloader for [ " << info.
alias() <<
" ]" << endl;
1215 if ( _pluginRepoverification.checkIfNeeded() )
1216 downloader_ptr->setPluginRepoverification( _pluginRepoverification );
1227 for_( it, repoBegin(), repoEnd() )
1229 Pathname cachepath(rawcache_path_for_repoinfo( _options, *it ));
1230 if (
PathInfo(cachepath).isExist() )
1231 downloader_ptr->addCachePath(cachepath);
1234 downloader_ptr->download( media, tmpdir.path() );
1239 MediaMounter media( url );
1254 if ( ! isTmpRepo( info ) )
1263 ERR <<
"Trying another url..." << endl;
1269 rexception.remember(e);
1275 ERR <<
"No more urls..." << endl;
1284 progress.sendTo(progressfnc);
1294 progress.sendTo(progressfnc);
1297 const Pathname & rpc { packagescache_path_for_repoinfo(_options, info) };
1298 if ( not isAutoClean_r || autoPruneInDir( rpc.dirname() ) )
1307 Pathname mediarootpath = rawcache_path_for_repoinfo( _options, info );
1308 Pathname productdatapath = rawproductdata_path_for_repoinfo( _options, info );
1315 RepoStatus raw_metadata_status = metadataStatus(info);
1316 if ( raw_metadata_status.
empty() )
1321 refreshMetadata(info, RefreshIfNeeded, progressrcv );
1322 raw_metadata_status = metadataStatus(info);
1325 bool needs_cleaning =
false;
1326 if ( isCached( info ) )
1328 MIL << info.
alias() <<
" is already cached." << endl;
1331 if ( cache_status == raw_metadata_status )
1333 MIL << info.
alias() <<
" cache is up to date with metadata." << endl;
1334 if ( policy == BuildIfNeeded )
1337 const Pathname & base = solv_path_for_repoinfo( _options, info);
1338 if ( !
PathInfo(base/
"solv.idx").isExist() )
1344 MIL << info.
alias() <<
" cache rebuild is forced" << endl;
1348 needs_cleaning =
true;
1354 progress.name(
str::form(
_(
"Building repository '%s' cache"), info.
label().c_str()));
1362 MIL << info.
alias() <<
" building cache..." << info.
type() << endl;
1364 Pathname base = solv_path_for_repoinfo( _options, info);
1383 switch ( repokind.
toEnum() )
1387 repokind = probeCache( productdatapath );
1393 MIL <<
"repo type is " << repokind << endl;
1395 switch ( repokind.
toEnum() )
1406 cmd.push_back(
PathInfo(
"/usr/bin/repo2solv" ).isFile() ?
"repo2solv" :
"repo2solv.sh" );
1408 cmd.push_back(
"-o" );
1409 cmd.push_back( solvfile.
asString() );
1410 cmd.push_back(
"-X" );
1415 forPlainDirs.reset(
new MediaMounter( info.
url() ) );
1417 cmd.push_back(
"-R" );
1419 cmd.push_back( forPlainDirs->getPathName( info.
path() ).c_str() );
1422 cmd.push_back( productdatapath.
asString() );
1425 std::string errdetail;
1427 for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) {
1428 WAR <<
" " << output;
1429 errdetail += output;
1432 int ret = prog.close();
1436 ex.addHistory(
str::Str() << prog.command() << endl << errdetail << prog.execError() );
1441 guard.resetDispose();
1450 setCacheStatus(info, raw_metadata_status);
1451 MIL <<
"Commit cache.." << endl;
1466 MIL <<
"going to probe the repo type at " << url <<
" (" << path <<
")" << endl;
1472 MIL <<
"Probed type NONE (not exists) at " << url <<
" (" << path <<
")" << endl;
1484 bool gotMediaException =
false;
1490 if ( access.doesFileExist(path/
"/repodata/repomd.xml") )
1492 MIL <<
"Probed type RPMMD at " << url <<
" (" << path <<
")" << endl;
1496 catch (
const media::MediaException &e )
1499 DBG <<
"problem checking for repodata/repomd.xml file" << endl;
1501 gotMediaException =
true;
1506 if ( access.doesFileExist(path/
"/content") )
1508 MIL <<
"Probed type YAST2 at " << url <<
" (" << path <<
")" << endl;
1512 catch (
const media::MediaException &e )
1515 DBG <<
"problem checking for content file" << endl;
1517 gotMediaException =
true;
1523 MediaMounter media( url );
1527 MIL <<
"Probed type RPMPLAINDIR at " << url <<
" (" << path <<
")" << endl;
1541 if (gotMediaException)
1544 MIL <<
"Probed type NONE at " << url <<
" (" << path <<
")" << endl;
1555 MIL <<
"going to probe the cached repo at " << path_r << endl;
1559 if (
PathInfo(path_r/
"/repodata/repomd.xml").isFile() )
1561 else if (
PathInfo(path_r/
"/content").isFile() )
1563 else if (
PathInfo(path_r).isDir() )
1566 MIL <<
"Probed cached type " << ret <<
" at " << path_r << endl;
1574 MIL <<
"Going to clean up garbage in cache dirs" << endl;
1577 progress.sendTo(progressrcv);
1580 std::list<Pathname> cachedirs;
1581 cachedirs.push_back(_options.repoRawCachePath);
1582 cachedirs.push_back(_options.repoPackagesCachePath);
1583 cachedirs.push_back(_options.repoSolvCachePath);
1585 for_( dir, cachedirs.begin(), cachedirs.end() )
1589 std::list<Pathname> entries;
1594 unsigned sdircount = entries.size();
1595 unsigned sdircurrent = 1;
1596 for_( subdir, entries.begin(), entries.end() )
1600 for_( r, repoBegin(), repoEnd() )
1601 if ( subdir->basename() == r->escaped_alias() )
1602 { found =
true;
break; }
1607 progress.set( progress.val() + sdircurrent * 100 / sdircount );
1612 progress.set( progress.val() + 100 );
1622 progress.sendTo(progressrcv);
1625 MIL <<
"Removing raw metadata cache for " << info.
alias() << endl;
1636 Pathname solvfile = solv_path_for_repoinfo(_options, info) /
"solv";
1638 if ( !
PathInfo(solvfile).isExist() )
1648 if ( toolversion != LIBSOLV_TOOLVERSION )
1657 MIL <<
"Try to handle exception by rebuilding the solv-file" << endl;
1658 cleanCache( info, progressrcv );
1659 buildCache( info, BuildIfNeeded, progressrcv );
1674 progress.name(
str::form(
_(
"Adding repository '%s'"), info.
label().c_str()));
1677 MIL <<
"Try adding repo " << info << endl;
1684 if ( _options.probe )
1686 DBG <<
"unknown repository type, probing" << endl;
1687 assert_urls(tosave);
1701 Pathname repofile = generateNonExistingName(
1702 _options.knownReposPath, generateFilename(tosave));
1704 MIL <<
"Saving repo in " << repofile << endl;
1706 std::ofstream file(repofile.
c_str());
1715 tosave.
setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ) );
1716 tosave.
setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ) );
1721 oinfo.setFilepath(repofile);
1722 oinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, tosave ) );
1723 oinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, tosave ) );
1725 reposManip().insert(tosave);
1730 UrlCredentialExtractor( _options.rootDir ).collect( tosave.
baseUrls() );
1735 MIL <<
"done" << endl;
1742 for ( std::list<RepoInfo>::const_iterator it =
repos.begin();
1747 for_ ( kit, repoBegin(), repoEnd() )
1749 if ( (*it).alias() == (*kit).alias() )
1751 ERR <<
"To be added repo " << (*it).alias() <<
" conflicts with existing repo " << (*kit).alias() << endl;
1768 Pathname repofile = generateNonExistingName(_options.knownReposPath, filename);
1770 MIL <<
"Saving " <<
repos.size() <<
" repo" << (
repos.size() ?
"s" :
"" ) <<
" in " << repofile << endl;
1772 std::ofstream file(repofile.
c_str());
1779 for ( std::list<RepoInfo>::iterator it =
repos.begin();
1783 MIL <<
"Saving " << (*it).alias() << endl;
1784 it->dumpAsIniOn(file);
1785 it->setFilepath(repofile);
1786 it->setMetadataPath( rawcache_path_for_repoinfo( _options, *it ) );
1787 it->setPackagesPath( packagescache_path_for_repoinfo( _options, *it ) );
1788 reposManip().insert(*it);
1793 MIL <<
"done" << endl;
1805 MIL <<
"Going to delete repo " << info.
alias() << endl;
1807 for_( it, repoBegin(), repoEnd() )
1812 if ( (!info.
alias().empty()) && ( info.
alias() != (*it).alias() ) )
1827 std::list<RepoInfo> filerepos = repositories_in_file(todelete.
filepath());
1828 if ( filerepos.size() == 0
1829 ||(filerepos.size() == 1 && filerepos.front().alias() == todelete.
alias() ) )
1833 if ( ! ( ret == 0 || ret == ENOENT ) )
1838 MIL << todelete.
alias() <<
" successfully deleted." << endl;
1856 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1857 fit != filerepos.end();
1860 if ( (*fit).alias() != todelete.
alias() )
1861 (*fit).dumpAsIniOn(file);
1869 if ( isCached(todelete) )
1870 cleanCache( todelete, cSubprogrcv);
1872 cleanMetadata( todelete, mSubprogrcv );
1873 cleanPackages( todelete, pSubprogrcv,
true );
1874 reposManip().erase(todelete);
1875 MIL << todelete.
alias() <<
" successfully deleted." << endl;
1889 RepoInfo toedit = getRepositoryInfo(alias);
1893 if ( alias != newinfo.alias() && hasRepo( newinfo.alias() ) )
1905 std::list<RepoInfo> filerepos = repositories_in_file(toedit.
filepath());
1921 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
1922 fit != filerepos.end();
1927 if ( (*fit).alias() != toedit.
alias() )
1928 (*fit).dumpAsIniOn(file);
1930 newinfo.dumpAsIniOn(file);
1933 if ( toedit.
enabled() && !newinfo.enabled() )
1936 const Pathname & solvidx = solv_path_for_repoinfo(_options, newinfo)/
"solv.idx";
1941 newinfo.setFilepath(toedit.
filepath());
1942 newinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, newinfo ) );
1943 newinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, newinfo ) );
1948 oinfo.setFilepath(toedit.
filepath());
1949 oinfo.setMetadataPath( rawcache_path_for_repoinfo( _options, newinfo ) );
1950 oinfo.setPackagesPath( packagescache_path_for_repoinfo( _options, newinfo ) );
1952 reposManip().erase(toedit);
1953 reposManip().insert(newinfo);
1955 UrlCredentialExtractor( _options.rootDir ).collect( newinfo.baseUrls() );
1957 MIL <<
"repo " << alias <<
" modified" << endl;
1965 RepoConstIterator it( findAlias( alias,
repos() ) );
1966 if ( it !=
repos().end() )
1976 for_( it, repoBegin(), repoEnd() )
1978 for_( urlit, (*it).baseUrlsBegin(), (*it).baseUrlsEnd() )
1980 if ( (*urlit).asString(urlview) == url.
asString(urlview) )
1995 void RepoManager::Impl::addService(
const ServiceInfo & service )
1997 assert_alias( service );
2000 if ( hasService( service.
alias() ) )
2006 saveService( toSave );
2010 UrlCredentialExtractor( _options.rootDir ).collect( toSave.url() );
2012 MIL <<
"added service " << toSave.alias() << endl;
2017 void RepoManager::Impl::removeService(
const std::string & alias )
2019 MIL <<
"Going to delete service " << alias << endl;
2021 const ServiceInfo & service = getService( alias );
2024 if( location.
empty() )
2033 if ( tmpSet.size() == 1 )
2040 MIL << alias <<
" successfully deleted." << endl;
2046 std::ofstream file(location.
c_str());
2053 for_(it, tmpSet.begin(), tmpSet.end())
2055 if( it->alias() != alias )
2056 it->dumpAsIniOn(file);
2059 MIL << alias <<
" successfully deleted from file " << location << endl;
2063 RepoCollector rcollector;
2064 getRepositoriesInService( alias,
2065 boost::make_function_output_iterator( bind( &RepoCollector::collect, &rcollector, _1 ) ) );
2067 for_(rit, rcollector.repos.begin(), rcollector.repos.end())
2068 removeRepository(*rit);
2073 void RepoManager::
Impl::refreshServices( const RefreshServiceOptions & options_r )
2077 ServiceSet services( serviceBegin(), serviceEnd() );
2078 for_( it, services.begin(), services.end() )
2080 if ( !it->enabled() )
2084 refreshService(*it, options_r);
2091 void RepoManager::Impl::refreshService(
const std::string & alias,
const RefreshServiceOptions & options_r )
2094 assert_alias( service );
2095 assert_url( service );
2096 MIL <<
"Going to refresh service '" << service.
alias() <<
"', url: " << service.
url() <<
", opts: " << options_r << endl;
2098 if ( service.
ttl() && !( options_r.testFlag( RefreshService_forceRefresh) || options_r.testFlag( RefreshService_restoreStatus ) ) )
2107 if ( (lrf+=service.
ttl()) > now )
2109 MIL <<
"Skip: '" << service.
alias() <<
"' metadata valid until " << lrf << endl;
2114 WAR <<
"Force: '" << service.
alias() <<
"' metadata last refresh in the future: " << lrf << endl;
2121 bool serviceModified =
false;
2132 serviceModified =
true;
2137 std::string servicesTargetDistro = _options.servicesTargetDistro;
2138 if ( servicesTargetDistro.empty() )
2142 DBG <<
"ServicesTargetDistro: " << servicesTargetDistro << endl;
2146 RepoCollector collector(servicesTargetDistro);
2159 ServiceRepos( _options.rootDir, service, bind( &RepoCollector::collect, &collector, _1 ) );
2164 uglyHack.first =
true;
2165 uglyHack.second = e;
2167 if ( service.
ttl() != origTtl )
2169 if ( !service.
ttl() )
2171 serviceModified =
true;
2179 for_( it, collector.repos.begin(), collector.repos.end() )
2182 it->setAlias(
str::form(
"%s:%s", service.
alias().c_str(), it->alias().c_str() ) );
2184 it->setService( service.
alias() );
2187 newRepoStates[it->alias()] = *it;
2195 if ( !it->path().empty() )
2197 if ( it->path() !=
"/" )
2202 if ( it->baseUrlsEmpty() )
2205 if ( !path.
empty() )
2207 it->setBaseUrl( std::move(url) );
2209 else if ( !path.
empty() )
2212 for (
Url & url : urls )
2216 it->setBaseUrls( std::move(urls) );
2223 RepoInfoList oldRepos;
2224 getRepositoriesInService( service.
alias(), std::back_inserter( oldRepos ) );
2228 for_( oldRepo, oldRepos.begin(), oldRepos.end() )
2230 if ( ! foundAliasIn( oldRepo->alias(), collector.repos ) )
2232 if ( oldRepo->enabled() )
2235 const auto & last = service.
repoStates().find( oldRepo->alias() );
2236 if ( last != service.
repoStates().end() && ! last->second.enabled )
2238 DBG <<
"Service removes user enabled repo " << oldRepo->alias() << endl;
2240 serviceModified =
true;
2243 DBG <<
"Service removes enabled repo " << oldRepo->alias() << endl;
2246 DBG <<
"Service removes disabled repo " << oldRepo->alias() << endl;
2248 removeRepository( *oldRepo );
2254 UrlCredentialExtractor urlCredentialExtractor( _options.rootDir );
2255 for_( it, collector.repos.begin(), collector.repos.end() )
2261 TriBool toBeEnabled( indeterminate );
2262 DBG <<
"Service request to " << (it->enabled()?
"enable":
"disable") <<
" service repo " << it->alias() << endl;
2264 if ( options_r.testFlag( RefreshService_restoreStatus ) )
2266 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() << endl;
2278 DBG <<
"User request to enable service repo " << it->alias() << endl;
2284 serviceModified =
true;
2288 DBG <<
"User request to disable service repo " << it->alias() << endl;
2289 toBeEnabled =
false;
2293 RepoInfoList::iterator oldRepo( findAlias( it->alias(), oldRepos ) );
2294 if ( oldRepo == oldRepos.end() )
2299 if ( ! indeterminate(toBeEnabled) )
2300 it->setEnabled( (
bool ) toBeEnabled );
2302 DBG <<
"Service adds repo " << it->alias() <<
" " << (it->enabled()?
"enabled":
"disabled") << endl;
2303 addRepository( *it );
2308 bool oldRepoModified =
false;
2310 if ( indeterminate(toBeEnabled) )
2314 if ( oldRepo->enabled() == it->enabled() )
2315 toBeEnabled = it->enabled();
2316 else if (options_r.testFlag( RefreshService_restoreStatus ) )
2318 toBeEnabled = it->enabled();
2319 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() <<
" forces " << (toBeEnabled?
"enabled":
"disabled") << endl;
2323 const auto & last = service.
repoStates().find( oldRepo->alias() );
2324 if ( last == service.
repoStates().end() || last->second.enabled != it->enabled() )
2325 toBeEnabled = it->enabled();
2328 toBeEnabled = oldRepo->enabled();
2329 DBG <<
"User modified service repo " << it->alias() <<
" may stay " << (toBeEnabled?
"enabled":
"disabled") << endl;
2335 if ( toBeEnabled == oldRepo->enabled() )
2337 DBG <<
"Service repo " << it->alias() <<
" stays " << (oldRepo->enabled()?
"enabled":
"disabled") << endl;
2339 else if ( toBeEnabled )
2341 DBG <<
"Service repo " << it->alias() <<
" gets enabled" << endl;
2342 oldRepo->setEnabled(
true );
2343 oldRepoModified =
true;
2347 DBG <<
"Service repo " << it->alias() <<
" gets disabled" << endl;
2348 oldRepo->setEnabled(
false );
2349 oldRepoModified =
true;
2355 if ( oldRepo->rawName() != it->rawName() )
2357 DBG <<
"Service repo " << it->alias() <<
" gets new NAME " << it->rawName() << endl;
2358 oldRepo->setName( it->rawName() );
2359 oldRepoModified =
true;
2363 if ( oldRepo->autorefresh() != it->autorefresh() )
2365 DBG <<
"Service repo " << it->alias() <<
" gets new AUTOREFRESH " << it->autorefresh() << endl;
2366 oldRepo->setAutorefresh( it->autorefresh() );
2367 oldRepoModified =
true;
2371 if ( oldRepo->priority() != it->priority() )
2373 DBG <<
"Service repo " << it->alias() <<
" gets new PRIORITY " << it->priority() << endl;
2374 oldRepo->setPriority( it->priority() );
2375 oldRepoModified =
true;
2381 urlCredentialExtractor.extract( newUrls );
2382 if ( oldRepo->rawBaseUrls() != newUrls )
2384 DBG <<
"Service repo " << it->alias() <<
" gets new URLs " << newUrls << endl;
2385 oldRepo->setBaseUrls( std::move(newUrls) );
2386 oldRepoModified =
true;
2396 oldRepo->getRawGpgChecks( ogpg[0], ogpg[1], ogpg[2] );
2397 it-> getRawGpgChecks( ngpg[0], ngpg[1], ngpg[2] );
2398#define Z_CHKGPG(I,N) \
2399 if ( ! sameTriboolState( ogpg[I], ngpg[I] ) ) \
2401 DBG << "Service repo " << it->alias() << " gets new "#N"Check " << ngpg[I] << endl; \
2402 oldRepo->set##N##Check( ngpg[I] ); \
2403 oldRepoModified = true; \
2412 if ( oldRepoModified )
2414 modifyRepository( oldRepo->alias(), *oldRepo );
2423 serviceModified =
true;
2430 serviceModified =
true;
2437 if ( service.
ttl() )
2440 serviceModified =
true;
2443 if ( serviceModified )
2446 modifyService( service.
alias(), service );
2450 if ( uglyHack.first )
2452 throw( uglyHack.second );
2458 void RepoManager::Impl::modifyService(
const std::string & oldAlias,
const ServiceInfo & newService )
2460 MIL <<
"Going to modify service " << oldAlias << endl;
2471 const ServiceInfo & oldService = getService(oldAlias);
2474 if( location.
empty() )
2484 std::ofstream file(location.
c_str());
2485 for_(it, tmpSet.begin(), tmpSet.end())
2487 if( *it != oldAlias )
2488 it->dumpAsIniOn(file);
2497 UrlCredentialExtractor( _options.rootDir ).collect( service.
url() );
2501 if ( oldAlias != service.
alias()
2504 std::vector<RepoInfo> toModify;
2505 getRepositoriesInService(oldAlias, std::back_inserter(toModify));
2506 for_( it, toModify.begin(), toModify.end() )
2513 const auto & last = service.
repoStates().find( it->alias() );
2515 it->setEnabled( last->second.enabled );
2518 it->setEnabled(
false );
2521 if ( oldAlias != service.
alias() )
2522 it->setService(service.
alias());
2524 modifyRepository(it->alias(), *it);
2538 if ( access.doesFileExist(
"/repo/repoindex.xml") )
2541 catch (
const media::MediaException &e )
2561 void RepoManager::Impl::refreshGeoIPData ()
2566 MIL <<
"GeoIp disabled via ZConfig, not refreshing the GeoIP information." << std::endl;
2572 static auto lastCheck = std::chrono::steady_clock::time_point::min();
2573 if ( lastCheck != std::chrono::steady_clock::time_point::min()
2574 && (std::chrono::steady_clock::now() - lastCheck) < std::chrono::hours(24) )
2577 lastCheck = std::chrono::steady_clock::now();
2582 MIL <<
"Unable to create cache directory for GeoIP." << std::endl;
2586 if ( !
PathInfo(geoIPCache).userMayRWX() ) {
2587 MIL <<
"No access rights for the GeoIP cache directory." << std::endl;
2597 auto age = std::chrono::system_clock::now() - std::chrono::system_clock::from_time_t( pi.
mtime() );
2598 if ( age < std::chrono::hours(24) )
2601 MIL <<
"Removing GeoIP file for " << entry.
name <<
" since it's older than 24hrs." << std::endl;
2608 std::for_each( hosts.begin(), hosts.end(), [ & ](
const std::string &hostname ) {
2611 if ( zypp::PathInfo( geoIPCache / hostname ).isExist() ) {
2612 MIL <<
"Skipping GeoIP request for " << hostname <<
" since a valid cache entry exists." << std::endl;
2616 MIL <<
"Query GeoIP for " << hostname << std::endl;
2621 url.setHost(hostname);
2622 url.setScheme(
"https");
2627 MIL <<
"Ignoring invalid GeoIP hostname: " << hostname << std::endl;
2639 MIL <<
"Failed to query GeoIP from hostname: " << hostname << std::endl;
2642 if ( !file->empty() ) {
2644 constexpr auto writeHostToFile = [](
const Pathname &fName,
const std::string &host ){
2646 out.open( fName.
asString(), std::ios_base::trunc );
2647 if ( out.is_open() ) {
2648 out << host << std::endl;
2650 MIL <<
"Failed to create/open GeoIP cache file " << fName << std::endl;
2654 std::string geoipMirror;
2657 if ( reader.seekToNode( 1,
"host" ) ) {
2658 const auto &
str = reader.nodeText().asString();
2666 MIL <<
"Storing geoIP redirection: " << hostname <<
" -> " <<
str << std::endl;
2671 MIL <<
"No host entry or empty file returned for GeoIP, remembering for 24hrs" << std::endl;
2675 MIL <<
"Empty or invalid GeoIP file, not requesting again for 24hrs" << std::endl;
2678 writeHostToFile( geoIPCache / hostname, geoipMirror );
2684 MIL <<
"Failed to query GeoIP data." << std::endl;
2695 : _pimpl( new
Impl(opt) )
2702 {
return _pimpl->repoEmpty(); }
2705 {
return _pimpl->repoSize(); }
2708 {
return _pimpl->repoBegin(); }
2711 {
return _pimpl->repoEnd(); }
2714 {
return _pimpl->getRepo( alias ); }
2717 {
return _pimpl->hasRepo( alias ); }
2727 std::string host( url_r.
getHost() );
2728 if ( ! host.empty() )
2740 {
return _pimpl->metadataStatus( info ); }
2743 {
return _pimpl->checkIfToRefreshMetadata( info, url, policy ); }
2746 {
return _pimpl->metadataPath( info ); }
2749 {
return _pimpl->packagesPath( info ); }
2752 {
return _pimpl->refreshMetadata( info, policy, progressrcv ); }
2755 {
return _pimpl->cleanMetadata( info, progressrcv ); }
2758 {
return _pimpl->cleanPackages( info, progressrcv ); }
2761 {
return _pimpl->cacheStatus( info ); }
2764 {
return _pimpl->buildCache( info, policy, progressrcv ); }
2767 {
return _pimpl->cleanCache( info, progressrcv ); }
2770 {
return _pimpl->isCached( info ); }
2773 {
return _pimpl->loadFromCache( info, progressrcv ); }
2776 {
return _pimpl->cleanCacheDirGarbage( progressrcv ); }
2779 {
return _pimpl->probe( url, path ); }
2782 {
return _pimpl->probe( url ); }
2785 {
return _pimpl->addRepository( info, progressrcv ); }
2788 {
return _pimpl->addRepositories( url, progressrcv ); }
2791 {
return _pimpl->removeRepository( info, progressrcv ); }
2794 {
return _pimpl->modifyRepository( alias, newinfo, progressrcv ); }
2797 {
return _pimpl->getRepositoryInfo( alias, progressrcv ); }
2800 {
return _pimpl->getRepositoryInfo( url, urlview, progressrcv ); }
2803 {
return _pimpl->serviceEmpty(); }
2806 {
return _pimpl->serviceSize(); }
2809 {
return _pimpl->serviceBegin(); }
2812 {
return _pimpl->serviceEnd(); }
2815 {
return _pimpl->getService( alias ); }
2818 {
return _pimpl->hasService( alias ); }
2821 {
return _pimpl->probeService( url ); }
2824 {
return _pimpl->addService( alias, url ); }
2827 {
return _pimpl->addService( service ); }
2830 {
return _pimpl->removeService( alias ); }
2833 {
return _pimpl->removeService( service ); }
2836 {
return _pimpl->refreshServices( options_r ); }
2839 {
return _pimpl->refreshService( alias, options_r ); }
2842 {
return _pimpl->refreshService( service, options_r ); }
2845 {
return _pimpl->modifyService( oldAlias, service ); }
2848 {
return _pimpl->refreshGeoIPData(); }
media::MediaAccessId _mid
scoped_ptr< media::CredentialManager > _cmPtr
RepoManager implementation.
std::ostream & operator<<(std::ostream &str, const RepoManager::Impl &obj)
Stream output.
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Progress callback from another progress.
Store and operate on date (time_t).
static const ValueType day
static Date now()
Return the current time.
Integral type with defined initial value when default constructed.
std::string digest()
get hex string representation of the digest
static const std::string & sha1()
sha1
Base class for Exception.
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
std::string asUserString() const
Translated error message as string suitable for the user.
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
std::vector< std::string > Arguments
Writing the zypp history file.
void modifyRepository(const RepoInfo &oldrepo, const RepoInfo &newrepo)
Log certain modifications to a repository.
void addRepository(const RepoInfo &repo)
Log a newly added repository.
void removeRepository(const RepoInfo &repo)
Log recently removed repository.
Maintain [min,max] and counter (value) for progress counting.
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
void name(const std::string &name_r)
Set counter name.
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
What is known about a repository.
Pathname metadataPath() const
Path where this repo metadata was read from.
bool baseUrlsEmpty() const
whether repository urls are available
void setBaseUrl(const Url &url)
Clears current base URL list and adds url.
repo::RepoType type() const
Type of repository,.
urls_size_type baseUrlsSize() const
number of repository urls
Url url() const
Pars pro toto: The first repository url.
urls_const_iterator baseUrlsEnd() const
iterator that points at end of repository urls
void setPackagesPath(const Pathname &path)
set the path where the local packages are stored
virtual std::ostream & dumpAsIniOn(std::ostream &str) const
Write this RepoInfo object into str in a .repo file format.
Pathname path() const
Repository path.
url_set baseUrls() const
The complete set of repository urls.
bool requireStatusWithMediaFile() const
Returns true if this repository requires the media.1/media file to be included in the metadata status...
bool usesAutoMethadataPaths() const
Whether metadataPath uses AUTO% setup.
void setProbedType(const repo::RepoType &t) const
This allows to adjust the RepoType lazy, from NONE to some probed value, even for const objects.
urls_const_iterator baseUrlsBegin() const
iterator that points at begin of repository urls
void setMetadataPath(const Pathname &path)
Set the path where the local metadata is stored.
Pathname packagesPath() const
Path where this repo packages are cached.
transform_iterator< repo::RepoVariablesUrlReplacer, url_set::const_iterator > urls_const_iterator
std::string targetDistribution() const
Distribution for which is this repository meant.
void setType(const repo::RepoType &t)
set the repository type
Track changing files or directories.
static RepoStatus fromCookieFile(const Pathname &path)
Reads the status from a cookie file.
Date timestamp() const
The time the data were changed the last time.
bool empty() const
Whether the status is empty (empty checksum)
void saveToCookieFile(const Pathname &path_r) const
Save the status information to a cookie file.
static const std::string & systemRepoAlias()
Reserved system repository alias @System .
void eraseFromPool()
Remove this Repository from its Pool.
repo::ServiceType type() const
Service type.
Date::Duration ttl() const
Sugested TTL between two metadata auto-refreshs.
void setLrf(Date lrf_r)
Set date of last refresh.
Date lrf() const
Date of last refresh (if known).
bool repoToDisableFind(const std::string &alias_r) const
Whether alias_r is mentioned in ReposToDisable.
bool repoToEnableFind(const std::string &alias_r) const
Whether alias_r is mentioned in ReposToEnable.
const RepoStates & repoStates() const
Access the remembered repository states.
Url url() const
The service url.
void setProbedType(const repo::ServiceType &t) const
Lazy init service type.
std::map< std::string, RepoState > RepoStates
Url rawUrl() const
The service raw url (no variables replaced)
void addRepoToEnable(const std::string &alias_r)
Add alias_r to the set of ReposToEnable.
void clearReposToDisable()
Clear the set of ReposToDisable.
void delRepoToEnable(const std::string &alias_r)
Remove alias_r from the set of ReposToEnable.
virtual std::ostream & dumpAsIniOn(std::ostream &str) const
Writes ServiceInfo to stream in ".service" format.
void setRepoStates(RepoStates newStates_r)
Remember a new set of repository states.
bool reposToDisableEmpty() const
std::string targetDistribution() const
This is register.target attribute of the installed base product.
std::string getScheme() const
Returns the scheme name of the URL.
std::string asCompleteString() const
Returns a complete string representation of the Url object.
std::string asString() const
Returns a default string representation of the Url object.
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
std::string getHost(EEncoding eflag=zypp::url::E_DECODED) const
Returns the hostname or IP from the URL authority.
void setHost(const std::string &host)
Set the hostname or IP in the URL authority.
static bool schemeIsLocal(const std::string &scheme_r)
hd cd dvd dir file iso
bool isValid() const
Verifies the Url.
void setPassword(const std::string &pass, EEncoding eflag=zypp::url::E_DECODED)
Set the password in the URL authority.
static bool schemeIsPlugin(const std::string &scheme_r)
plugin
bool hasCredentialsInAuthority() const
Returns true if username and password are encoded in the authority component.
void setScheme(const std::string &scheme)
Set the scheme name in the URL.
static bool schemeIsDownloading(const std::string &scheme_r)
http https ftp sftp tftp
static bool schemeIsVolatile(const std::string &scheme_r)
cd dvd
unsigned repo_refresh_delay() const
Amount of time in minutes that must pass before another refresh.
const std::vector< std::string > geoipHostnames() const
All hostnames we want to rewrite using the geoip feature.
Pathname builtinRepoSolvfilesPath() const
The builtin config file value.
bool repo_add_probe() const
Whether repository urls should be probed.
Pathname geoipCachePath() const
Path where the geoip caches are kept (/var/cache/zypp/geoip)
static ZConfig & instance()
Singleton ctor.
Pathname builtinRepoPackagesPath() const
The builtin config file value.
Pathname builtinRepoMetadataPath() const
The builtin config file value.
Wrapper class for stat/lstat.
const Pathname & path() const
Return current Pathname.
bool isExist() const
Return whether valid stat info exists.
const std::string & asString() const
Return current Pathname as String.
Pathname extend(const std::string &r) const
Append string r to the last component of the path.
Pathname dirname() const
Return all but the last component od this path.
const char * c_str() const
String representation.
const std::string & asString() const
String representation.
std::string basename() const
Return the last component of this path.
bool empty() const
Test for an empty path.
static Pathname assertprefix(const Pathname &root_r, const Pathname &path_r)
Return path_r prefixed with root_r, unless it is already prefixed.
Provide a new empty temporary directory and recursively delete it when no longer needed.
static TmpDir makeSibling(const Pathname &sibling_r)
Provide a new empty temporary directory as sibling.
Read repository data from a .repo file.
Read service data from a .service file.
Repository already exists and some unique attribute can't be duplicated.
Exception for repository handling.
std::string label() const
Label for use in messages for the user interface.
std::string escaped_alias() const
Same as alias(), just escaped in a way to be a valid file name.
void setFilepath(const Pathname &filename)
set the path to the .repo file
void setAlias(const std::string &alias)
set the repository alias
Pathname filepath() const
File where this repo was read from.
bool enabled() const
If enabled is false, then this repository must be ignored as if does not exists, except when checking...
std::string alias() const
unique identifier for this source.
Thrown when the repo alias is found to be invalid.
thrown when it was impossible to determine an alias for this repo.
thrown when it was impossible to determine one url for this repo.
The repository cache is not built yet so you can't create the repostories from the cache.
thrown when it was impossible to match a repository
thrown when it was impossible to determine this repo type.
Service already exists and some unique attribute can't be duplicated.
Base Exception for service handling.
Thrown when the repo alias is found to be invalid.
Service without alias was used in an operation.
Service has no or invalid url defined.
Service plugin is immutable.
Retrieval of repository list for a service.
Downloader for YUM (rpm-nmd) repositories Encapsulates all the knowledge of which files have to be do...
RepoStatus status(MediaSetAccess &media_r) override
Status of the remote repository.
Lightweight repository attribute value lookup.
void reposErase(const std::string &alias_r)
Remove a Repository named alias_r.
Repository addRepoSolv(const Pathname &file_r, const std::string &name_r)
Load Solvables from a solv-file into a Repository named name_r.
static Pool instance()
Singleton ctor.
static const SolvAttr repositoryToolVersion
xmlTextReader based interface to iterate xml streams.
Repository metadata verification beyond GPG.
String related utilities and Regular expression matching.
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
std::string asString(TInt val, char zero='0', char one='1')
For printing bits.
bool ZYPP_PLUGIN_APPDATA_FORCE_COLLECT()
To trigger appdata refresh unconditionally.
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
int unlink(const Pathname &path)
Like 'unlink'.
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
int touch(const Pathname &path)
Change file's modification and access times.
int exchange(const Pathname &lpath, const Pathname &rpath)
Exchanges two files or directories.
int dirForEachExt(const Pathname &dir_r, const function< bool(const Pathname &, const DirEntry &)> &fnc_r)
Simiar to.
void updateSolvFileIndex(const Pathname &solvfile_r)
Create solv file content digest for zypper bash completion.
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).
std::string numstring(char n, int w=0)
bool regex_match(const std::string &s, smatch &matches, const regex ®ex)
\relates regex \ingroup ZYPP_STR_REGEX \relates regex \ingroup ZYPP_STR_REGEX
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
std::string hexstring(char n, int w=4)
Easy-to use interface to the ZYPP dependency resolver.
std::list< RepoInfo > readRepoFile(const Url &repo_file)
Parses repo_file and returns a list of RepoInfo objects corresponding to repositories found within th...
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
static bool warning(const std::string &msg_r, const UserData &userData_r=UserData())
send warning text
static bool error(const std::string &msg_r, const UserData &userData_r=UserData())
send error text
static RepoManagerOptions makeTestSetup(const Pathname &root_r)
Test setup adjusting all paths to be located below one root_r directory.
Pathname repoSolvCachePath
Pathname rootDir
remembers root_r value for later use
Pathname knownServicesPath
Pathname repoRawCachePath
Pathname repoPackagesCachePath
RepoManagerOptions(const Pathname &root_r=Pathname())
Default ctor following ZConfig global settings.
Functor thats filter RepoInfo by service which it belongs to.
creates and provides information about known sources.
bool hasRepo(const std::string &alias) const
ServiceSet::const_iterator ServiceConstIterator
bool serviceEmpty() const
bool hasService(const std::string &alias) const
RefreshCheckStatus
Possibly return state of checkIfRefreshMEtadata function.
RefreshCheckStatus checkIfToRefreshMetadata(const RepoInfo &info, const Url &url, RawMetadataRefreshPolicy policy)
Impl * clone() const
clone for RWCOW_pointer
void refreshService(const ServiceInfo &service, const RefreshServiceOptions &options_r)
void addRepository(const RepoInfo &info, OPT_PROGRESS)
RepoSet::const_iterator RepoConstIterator
RepoInfo getRepositoryInfo(const Url &url, const url::ViewOption &urlview, OPT_PROGRESS)
void addService(const std::string &alias, const Url &url)
std::string generateFilename(const ServiceInfo &info) const
bool isCached(const RepoInfo &info) const
void cleanPackages(const RepoInfo &info, OPT_PROGRESS, bool isAutoClean=false)
void modifyRepository(const std::string &alias, const RepoInfo &newinfo_r, OPT_PROGRESS)
void loadFromCache(const RepoInfo &info, OPT_PROGRESS)
void refreshMetadata(const RepoInfo &info, RawMetadataRefreshPolicy policy, OPT_PROGRESS)
void removeService(const std::string &alias)
void refreshService(const std::string &alias, const RefreshServiceOptions &options_r)
void buildCache(const RepoInfo &info, CacheBuildPolicy policy, OPT_PROGRESS)
RepoManager(const RepoManagerOptions &options=RepoManagerOptions())
RepoInfo getRepo(const std::string &alias) const
repo::ServiceType probeService(const Url &url) const
RWCOW_pointer< Impl > _pimpl
Pointer to implementation.
RepoInfo getRepositoryInfo(const std::string &alias, OPT_PROGRESS)
void cleanCacheDirGarbage(OPT_PROGRESS)
void addService(const ServiceInfo &service)
void init_knownRepositories()
Pathname metadataPath(const RepoInfo &info) const
ServiceSet::size_type ServiceSizeType
std::set< RepoInfo > RepoSet
RepoInfo typedefs.
Pathname packagesPath(const RepoInfo &info) const
DefaultIntegral< bool, false > _reposDirty
RepoManagerOptions _options
RepoStatus cacheStatus(const RepoInfo &info) const
void touchIndexFile(const RepoInfo &info)
repo::RepoType probeCache(const Pathname &path_r) const
void modifyService(const std::string &oldAlias, const ServiceInfo &newService)
ServiceConstIterator serviceEnd() const
ServiceConstIterator serviceBegin() const
void cleanCache(const RepoInfo &info, OPT_PROGRESS)
repo::RepoType probe(const Url &url, const Pathname &path=Pathname()) const
void removeRepository(const RepoInfo &info, OPT_PROGRESS)
RepoSizeType repoSize() const
void removeService(const ServiceInfo &service)
ServiceSizeType serviceSize() const
RepoSet::size_type RepoSizeType
void saveService(ServiceInfo &service) const
void addRepositories(const Url &url, OPT_PROGRESS)
void cleanMetadata(const RepoInfo &info, OPT_PROGRESS)
ServiceInfo getService(const std::string &alias) const
Pathname generateNonExistingName(const Pathname &dir, const std::string &basefilename) const
void refreshServices(const RefreshServiceOptions &options_r)
RepoConstIterator repoBegin() const
const RepoSet & repos() const
Iterate the known repositories.
void init_knownServices()
Impl(const RepoManagerOptions &opt)
RefreshServiceFlags RefreshServiceOptions
Options tuning RefreshService.
void getRepositoriesInService(const std::string &alias, OutputIterator out) const
std::set< ServiceInfo > ServiceSet
ServiceInfo typedefs.
RepoConstIterator repoEnd() const
void setCacheStatus(const RepoInfo &info, const RepoStatus &status)
RepoStatus metadataStatus(const RepoInfo &info) const
static std::string makeStupidAlias(const Url &url_r=Url())
Some stupid string but suitable as alias for your url if nothing better is available.
std::string generateFilename(const RepoInfo &info) const
PluginRepoverification _pluginRepoverification
Listentry returned by readdir.
Repository type enumeration.
static const RepoType YAST2
static const RepoType RPMMD
static const RepoType NONE
static const RepoType RPMPLAINDIR
Service type enumeration.
static const ServiceType NONE
No service set.
static const ServiceType RIS
Repository Index Service (RIS) (formerly known as 'Novell Update' (NU) service)
static const ServiceType PLUGIN
Plugin services are scripts installed on your system that provide the package manager with repositori...
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Url::asString() view options.
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
#define PL_(MSG1, MSG2, N)