12#include <solv/solvversion.h>
14#include <zypp-core/base/Regex.h>
15#include <zypp-core/fs/PathInfo.h>
19#include <zypp/base/LogTools.h>
33 namespace zypp_readonly_hack {
43 inline void cleanupNonRepoMetadataFolders(
const Pathname & cachePath_r,
44 const Pathname & defaultCachePath_r,
45 const std::list<std::string> & repoEscAliases_r )
47 if ( cachePath_r != defaultCachePath_r )
50 std::list<std::string> entries;
54 std::set<std::string> oldfiles;
55 set_difference( entries.begin(), entries.end(), repoEscAliases_r.begin(), repoEscAliases_r.end(),
56 std::inserter( oldfiles, oldfiles.end() ) );
62 for (
const std::string & old : oldfiles )
66 pi( cachePath_r/old );
78 std::string filename( alias_r );
83 MIL <<
"generating filename for " << stem_r <<
" [" << alias_r <<
"] : '" << filename <<
"'" << endl;
96 <<
"' distribution (current distro is '"
102 repos.push_back(repo);
108 MIL <<
"repo file: " << file << endl;
111 return std::move(collector.
repos);
116 MIL <<
"directory " << dir << endl;
117 std::list<RepoInfo> repos;
118 bool nonroot( geteuid() != 0 );
119 if ( nonroot && !
PathInfo(dir).userMayRX() )
125 std::list<Pathname> entries;
132 str::regex allowedRepoExt(
"^\\.repo(_[0-9]+)?$");
133 for ( std::list<Pathname>::const_iterator it = entries.begin(); it != entries.end(); ++it )
144 repos.insert( repos.end(), tmp.begin(), tmp.end() );
163 : _options(
std::move(opt))
186 switch ( repokind.
toEnum() )
189 status =
RepoStatus( productdatapath/
"repodata/repomd.xml");
191 status = status &&
RepoStatus( mediarootpath/
"media.1/media" );
195 status =
RepoStatus( productdatapath/
"content" ) &&
RepoStatus( mediarootpath/
"media.1/media" );
209 if ( ! status.
empty() )
223 progress.
sendTo(progressfnc);
232 progress.
sendTo(progressfnc);
249 MIL <<
"going to probe the cached repo at " << path_r << endl;
253 if (
PathInfo(path_r/
"/repodata/repomd.xml").isFile() )
255 else if (
PathInfo(path_r/
"/content").isFile() )
257 else if (
PathInfo(path_r).isDir() )
260 MIL <<
"Probed cached type " << ret <<
" at " << path_r << endl;
266 MIL <<
"Going to clean up garbage in cache dirs" << endl;
269 progress.
sendTo(progressrcv);
272 std::list<Pathname> cachedirs;
277 for_( dir, cachedirs.begin(), cachedirs.end() )
281 std::list<Pathname> entries;
286 unsigned sdircount = entries.size();
287 unsigned sdircurrent = 1;
288 for_( subdir, entries.begin(), entries.end() )
293 if ( subdir->basename() == r->escaped_alias() )
294 { found =
true;
break; }
299 progress.
set( progress.
val() + sdircurrent * 100 / sdircount );
304 progress.
set( progress.
val() + 100 );
312 progress.
sendTo(progressrcv);
315 MIL <<
"Removing raw metadata cache for " << info.
alias() << endl;
326 if ( !
PathInfo(solvfile).isExist() )
335 if ( toolversion != LIBSOLV_TOOLVERSION ) {
352 MIL <<
"Saving repo in " << repofile << endl;
354 std::ofstream file(repofile.
c_str());
361 tosave.dumpAsIniOn(file);
362 tosave.setFilepath(repofile);
388 MIL <<
"Going to delete repo " << info.
alias() << endl;
395 if ( (!info.
alias().empty()) && ( info.
alias() != (*it).alias() ) )
411 if ( filerepos.size() == 0
412 ||(filerepos.size() == 1 && filerepos.front().alias() == todelete.
alias() ) )
416 if ( ! ( ret == 0 || ret == ENOENT ) )
421 MIL << todelete.
alias() <<
" successfully deleted." << endl;
439 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
440 fit != filerepos.end();
443 if ( (*fit).alias() != todelete.
alias() )
444 (*fit).dumpAsIniOn(file);
458 MIL << todelete.
alias() <<
" successfully deleted." << endl;
502 for ( std::list<RepoInfo>::const_iterator fit = filerepos.begin();
503 fit != filerepos.end();
508 if ( (*fit).alias() != toedit.
alias() )
509 (*fit).dumpAsIniOn(file);
538 MIL <<
"repo " << alias <<
" modified" << endl;
545 if ( it !=
repos().end() )
557 for_( urlit, (*it).baseUrlsBegin(), (*it).baseUrlsEnd() )
559 if ( (*urlit).asString(urlview) == url.
asString(urlview) )
585 MIL <<
"added service " << toSave.
alias() << endl;
592 MIL <<
"Going to delete service " << alias << endl;
597 if( location.
empty() )
606 if ( tmpSet.size() == 1 )
613 MIL << alias <<
" successfully deleted." << endl;
619 std::ofstream file(location.
c_str());
626 for_(it, tmpSet.begin(), tmpSet.end())
628 if( it->alias() != alias )
629 it->dumpAsIniOn(file);
632 MIL << alias <<
" successfully deleted from file " << location << endl;
646 MIL <<
"Going to modify service " << oldAlias << endl;
660 if( location.
empty() )
670 std::ofstream file(location.
c_str());
671 for_(it, tmpSet.begin(), tmpSet.end())
673 if( *it != oldAlias )
674 it->dumpAsIniOn(file);
687 if ( oldAlias != service.
alias()
690 std::vector<RepoInfo> toModify;
692 for_( it, toModify.begin(), toModify.end() )
699 const auto & last = service.
repoStates().find( it->alias() );
701 it->setEnabled( last->second.enabled );
704 it->setEnabled(
false );
707 if ( oldAlias != service.
alias() )
708 it->setService(service.
alias());
725 MIL <<
"saving service in " << servfile << endl;
727 std::ofstream file( servfile.
c_str() );
734 MIL <<
"done" << endl;
753 const std::string & basefilename )
const
755 std::string final_filename = basefilename;
757 while (
PathInfo(dir + final_filename).isExist() )
762 return dir +
Pathname(final_filename);
778 switch ( repokind.
toEnum() )
781 p =
Pathname(productdatapath +
"/repodata/repomd.xml");
785 p =
Pathname(productdatapath +
"/content");
789 p =
Pathname(productdatapath +
"/cookie");
809 std::list<Pathname> entries;
819 for_(it, entries.begin(), entries.end() )
835 inline void cleanupNonRepoMetadtaFolders(
const Pathname & cachePath_r,
836 const Pathname & defaultCachePath_r,
837 const std::list<std::string> & repoEscAliases_r )
842 if ( cachePath_r != defaultCachePath_r )
845 std::list<std::string> entries;
849 std::set<std::string> oldfiles;
850 set_difference( entries.begin(), entries.end(), repoEscAliases_r.begin(), repoEscAliases_r.end(),
851 std::inserter( oldfiles, oldfiles.end() ) );
857 for (
const std::string & old : oldfiles )
861 pi( cachePath_r/old );
873 MIL <<
"start construct known repos" << endl;
877 std::list<std::string> repoEscAliases;
878 std::list<RepoInfo> orphanedRepos;
889 const std::string & serviceAlias( repoInfo.service() );
890 if ( ! ( serviceAlias.empty() ||
hasService( serviceAlias ) ) )
892 WAR <<
"Schedule orphaned service repo for deletion: " << repoInfo << endl;
893 orphanedRepos.push_back( repoInfo );
897 repoEscAliases.push_back(repoInfo.escaped_alias());
901 if ( ! orphanedRepos.empty() )
903 for (
const auto & repoInfo : orphanedRepos )
905 MIL <<
"Delete orphaned service repo " << repoInfo.alias() << endl;
911 % repoInfo.alias() );
929 repoEscAliases.sort();
943 MIL <<
"end construct known repos" << endl;
948 if ( info.
alias().empty() )
952 if ( info.
alias()[0] ==
'.')
954 info,
_(
"Repository alias cannot start with dot.")));
Progress callback from another progress.
static const ValueType day
static Date now()
Return the current time.
Base class for Exception.
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
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.
bool toMax()
Set counter value to current max value (unless no range).
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.
bool toMin()
Set counter value to current min value.
bool set(value_type val_r)
Set new counter value.
What is known about a repository.
bool baseUrlsEmpty() const
whether repository urls are available
repo::RepoType type() const
Type of repository,.
void setBaseUrl(Url url)
Clears current base URL list and adds url.
void setPackagesPath(const Pathname &path)
set the path where the local packages are stored
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...
std::ostream & dumpAsIniOn(std::ostream &str) const override
Write this RepoInfo object into str in a .repo file format.
void setMetadataPath(const Pathname &path)
Set the path where the local metadata is stored.
std::string targetDistribution() const
Distribution for which is this repository meant.
Track changing files or directories.
static RepoStatus fromCookieFile(const Pathname &path)
Reads the status from a cookie file.
bool empty() const
Whether the status is empty (empty checksum)
static const std::string & systemRepoAlias()
Reserved system repository alias @System .
void eraseFromPool()
Remove this Repository from its Pool.
Functor collecting ServiceInfos into a ServiceSet.
repo::ServiceType type() const
Service type.
const RepoStates & repoStates() const
Access the remembered repository states.
Url url() const
The service url.
std::ostream & dumpAsIniOn(std::ostream &str) const override
Writes ServiceInfo to stream in ".service" format.
std::string asString() const
Returns a default string representation of the Url object.
Pathname builtinRepoSolvfilesPath() const
The builtin config file value.
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.
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.
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.
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.
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
Service already exists and some unique attribute can't be duplicated.
Base Exception for service handling.
Service plugin is immutable.
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
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.
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.
Easy-to use interface to the ZYPP dependency resolver.
Pathname rawcache_path_for_repoinfo(const RepoManagerOptions &opt, const RepoInfo &info)
Calculates the raw cache path for a repository, this is usually /var/cache/zypp/alias.
void assert_alias(const RepoInfo &info)
Pathname solv_path_for_repoinfo(const RepoManagerOptions &opt, const RepoInfo &info)
Calculates the solv cache path for a repository.
std::list< RepoInfo > repositories_in_file(const Pathname &file)
Reads RepoInfo's from a repo file.
bool autoPruneInDir(const Pathname &path_r)
bsc#1204956: Tweak to prevent auto pruning package caches.
Pathname packagescache_path_for_repoinfo(const RepoManagerOptions &opt, const RepoInfo &info)
Calculates the packages cache path for a repository.
std::list< RepoInfo > repositories_in_dir(const Pathname &dir)
List of RepoInfo's from a directory.
Pathname rawproductdata_path_for_repoinfo(const RepoManagerOptions &opt, const RepoInfo &info)
Calculates the raw product metadata path for a repository, this is inside the raw cache dir,...
void assert_urls(const RepoInfo &info)
std::string filenameFromAlias(const std::string &alias_r, const std::string &stem_r)
Generate a related filename from a repo/service infos alias.
Iterator findAlias(const std::string &alias_r, Iterator begin_r, Iterator end_r)
Find alias_r in repo/service container.
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
Simple callback to collect the results.
bool collect(const RepoInfo &repo)
RepoInfo getRepositoryInfo(const std::string &alias)
RepoSet::const_iterator RepoConstIterator
void cleanCache(const RepoInfo &info, OPT_PROGRESS)
void removeService(const std::string &alias)
void loadFromCache(const RepoInfo &info, OPT_PROGRESS)
RepoConstIterator repoEnd() const
static void touchIndexFile(const RepoInfo &info, const RepoManagerOptions &options)
bool hasService(const std::string &alias) const
void removeRepositoryImpl(const RepoInfo &info, OPT_PROGRESS)
void init_knownRepositories()
void cleanPackages(const RepoInfo &info, OPT_PROGRESS, bool isAutoClean=false)
virtual ~RepoManagerBaseImpl()
virtual void removeRepository(const RepoInfo &info, OPT_PROGRESS)=0
bool hasRepo(const std::string &alias) const
void getRepositoriesInService(const std::string &alias, OutputIterator out) const
std::set< ServiceInfo > ServiceSet
ServiceInfo typedefs.
Pathname generateNonExistingName(const Pathname &dir, const std::string &basefilename) const
Generate a non existing filename in a directory, using a base name.
void modifyRepository(const std::string &alias, const RepoInfo &newinfo_r, OPT_PROGRESS)
static repo::RepoType probeCache(const Pathname &path_r)
Probe Metadata in a local cache directory.
void cleanMetadata(const RepoInfo &info, OPT_PROGRESS)
void modifyService(const std::string &oldAlias, const ServiceInfo &newService)
static RepoStatus metadataStatus(const RepoInfo &info, const RepoManagerOptions &options)
RepoManagerBaseImpl(RepoManagerOptions &&opt)
void saveService(ServiceInfo &service) const
RepoManagerOptions _options
void init_knownServices()
ServiceInfo getService(const std::string &alias) const
RepoConstIterator repoBegin() const
void cleanCacheDirGarbage(OPT_PROGRESS)
bool isCached(const RepoInfo &info) const
void addService(const ServiceInfo &service)
void addProbedRepository(const RepoInfo &info, repo::RepoType probedType)
const RepoSet & repos() const
std::string generateFilename(const RepoInfo &info) const
Pathname repoSolvCachePath
Pathname rootDir
remembers root_r value for later use
Pathname knownServicesPath
Pathname repoRawCachePath
Pathname repoPackagesCachePath
Repository type enumeration.
static const RepoType YAST2
static const RepoType RPMMD
static const RepoType NONE
static const RepoType RPMPLAINDIR
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_THROW(EXCPT)
Drops a logline and throws the Exception.