13#include <solv/solvversion.h>
18#include <zypp-core/zyppng/pipelines/MTry>
19#include <zypp-core/zyppng/pipelines/Transform>
20#include <zypp-core/zyppng/ui/ProgressObserver>
42#undef ZYPP_BASE_LOGGER_LOGGROUP
43#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::repomanager"
57 const char *
env =
getenv(
"ZYPP_PLUGIN_APPDATA_FORCE_COLLECT");
68 inline void cleanupNonRepoMetadataFolders(
const zypp::Pathname & cachePath_r,
70 const std::list<std::string> & repoEscAliases_r )
72 if ( cachePath_r != defaultCachePath_r )
75 std::list<std::string> entries;
79 std::set<std::string> oldfiles;
80 set_difference( entries.begin(), entries.end(), repoEscAliases_r.begin(), repoEscAliases_r.end(),
81 std::inserter( oldfiles, oldfiles.end() ) );
87 for (
const std::string & old : oldfiles )
91 pi( cachePath_r/old );
104#define OUTS(V) case zypp::RepoManagerFlags::V: str << #V; break
105 OUTS( RefreshIfNeeded );
106 OUTS( RefreshForced );
107 OUTS( RefreshIfNeededIgnoreDelay );
116#define OUTS(V) case zypp::RepoManagerFlags::V: str << #V; break
117 OUTS( REFRESH_NEEDED );
118 OUTS( REPO_UP_TO_DATE );
119 OUTS( REPO_CHECK_DELAYED );
128#define OUTS(V) case zypp::RepoManagerFlags::V: str << #V; break
129 OUTS( BuildIfNeeded );
139 std::string filename(
alias_r );
144 MIL <<
"generating filename for " <<
stem_r <<
" [" <<
alias_r <<
"] : '" << filename <<
"'" << std::endl;
157 <<
"' distribution (current distro is '"
163 repos.push_back(repo);
170 MIL <<
"repo file: " << file << std::endl;
188 template <
typename ZContextRef>
191 MIL <<
"directory " << dir << std::endl;
192 std::list<RepoInfo> repos;
200 std::list<zypp::Pathname> entries;
208 for ( std::list<zypp::Pathname>::const_iterator
it = entries.begin();
it != entries.end(); ++
it )
219 repos.insert( repos.end(),
tmp.begin(),
tmp.end() );
238 template <
typename ZyppContextRefType>
242 , _pluginRepoverification(
_options.pluginsPath /
"repoverification",
248 template <
typename ZyppContextRefType>
252 if ( ( _reposDirty || env::ZYPP_PLUGIN_APPDATA_FORCE_COLLECT() )
256 std::list<zypp::Pathname> entries;
258 if ( ! entries.empty() )
261 cmd.push_back(
"<" );
262 cmd.push_back(
">" );
263 cmd.push_back(
"PROGRAM" );
264 for (
const auto &
rinfo : repos() )
266 if ( !
rinfo.enabled() )
268 cmd.push_back(
"-R" );
270 cmd.push_back(
"-t" );
271 cmd.push_back(
rinfo.type().asString() );
272 cmd.push_back(
"-p" );
273 cmd.push_back( (
rinfo.metadataPath()/
rinfo.path()).asString() );
276 for_(
it, entries.begin(), entries.end() )
280 if (
pi.isFile() &&
pi.userMayRX() )
283 cmd[2] =
pi.asString();
293 template<
typename ZyppContextRefType>
299 |
and_then( [
this](){
return init_knownRepositories(); } );
302 template<
typename ZyppContextRefType>
308 template <
typename ZyppContextRefType>
362 if ( ! status.
empty() )
372 template <
typename ZyppContextRefType>
375 return metadataStatus( info,
_options );
378 template <
typename ZyppContextRefType>
383 ProgressObserver::setup(
myProgress,
_(
"Cleaning metadata"), 100 );
386 ProgressObserver::setCurrent (
myProgress, 50 );
391 ProgressObserver::finish (
myProgress, ProgressObserver::Error );
397 template <
typename ZyppContextRefType>
401 ProgressObserver::setup(
myProgress,
_(
"Cleaning packages"), 100 );
412 ProgressObserver::finish (
myProgress, ProgressObserver::Error );
424 template <
typename ZyppContextRefType>
427 MIL <<
"going to probe the cached repo at " <<
path_r << std::endl;
438 MIL <<
"Probed cached type " <<
ret <<
" at " <<
path_r << std::endl;
442 template <
typename ZyppContextRefType>
446 MIL <<
"Going to clean up garbage in cache dirs" << std::endl;
465 std::list<zypp::Pathname> entries;
470 if ( !entries.size() )
474 for(
const auto &
subdir : entries )
478 for_(
r, repoBegin(), repoEnd() )
479 if (
subdir.basename() ==
r->escaped_alias() )
480 {
found =
true;
break; }
492 ProgressObserver::finish (
myProgress, ProgressObserver::Error );
499 template <
typename ZyppContextRefType>
503 ProgressObserver::setup(
myProgress,
_(
"Cleaning cache"), 100 );
506 MIL <<
"Removing raw metadata cache for " << info.
alias() << std::endl;
514 ProgressObserver::finish (
myProgress, ProgressObserver::Error );
519 template <
typename ZyppContextRefType>
524 ProgressObserver::setup(
myProgress,
_(
"Loading from cache"), 3 );
551 MIL <<
"Try to handle exception by rebuilding the solv-file" << std::endl;
552 return cleanCache( info, ProgressObserver::makeSubTask(
myProgress ) )
565 ProgressObserver::finish (
myProgress, ProgressObserver::Error );
571 template <
typename ZyppContextRefType>
585 std::ofstream file(
repofile.c_str());
596 reposManip().insert(
tosave);
611 template <
typename ZyppContextRefType>
618 MIL <<
"Going to delete repo " << info.
alias() << std::endl;
620 for(
const auto &repo : repos() )
625 if ( (!info.
alias().empty()) && ( info.
alias() != repo.alias() ) )
651 MIL <<
todelete.alias() <<
" successfully deleted." << std::endl;
663 std::ofstream file(
todelete.filepath().c_str());
669 for ( std::list<RepoInfo>::const_iterator
fit =
filerepos.begin();
673 if ( (*fit).alias() !=
todelete.alias() )
674 (*fit).dumpAsIniOn(file);
683 cleanPackages(
todelete, ProgressObserver::makeSubTask(
myProgress, 0.4 ),
true ).unwrap();
685 MIL <<
todelete.alias() <<
" successfully deleted." << std::endl;
695 ProgressObserver::finish(
myProgress, ProgressObserver::Error );
700 template <
typename ZyppContextRefType>
705 ProgressObserver::setup(
myProgress,
_(
"Modifying repository"), 5 );
717 if (
toedit.filepath().empty())
735 std::ofstream file(
toedit.filepath().c_str());
741 for ( std::list<RepoInfo>::const_iterator
fit =
filerepos.begin();
747 if ( (*fit).alias() !=
toedit.alias() )
748 (*fit).dumpAsIniOn(file);
769 reposManip().erase(
toedit);
777 MIL <<
"repo " << alias <<
" modified" << std::endl;
784 ProgressObserver::finish (
myProgress, ProgressObserver::Error );
789 template <
typename ZyppContextRefType>
794 if (
it != repos().end() )
795 return make_expected_success(*
it);
805 template <
typename ZyppContextRefType>
810 for_(
it, repoBegin(), repoEnd() )
812 for_(
urlit, (*it).baseUrlsBegin(), (*it).baseUrlsEnd() )
815 return make_expected_success(*
it);
827 template<
typename ZyppContextRefType>
832 RepoManagerWorkflow::refreshGeoIPData(
_zyppContext, {url} )
834 |
and_then( [
this, url, policy]( zyppng::repo::RefreshContextRef<ZyppContextRefType> &&
refCtx ) {
842 template<
typename ZyppContextRefType>
850 for(
const auto &repo : repos() ) {
851 if ( info.
alias() == repo.alias() )
865 | [
this, info = info](
auto) { return zyppng::repo::RefreshContext<ZyppContextRefType>::create( _zyppContext, info, shared_this<RepoManager<ZyppContextRefType>>()); }
882 template<
typename ZyppContextRefType>
887 ProgressObserver::setup(
myProgress,
"Refreshing repositories" , 1 );
898 for(
const auto &repo : repos() ) {
899 if ( info.
alias() == repo.alias() )
928 ctx->repoManager()->reposManip();
933 | [ info = info,
subProgress ](
expected<repo::RefreshContextRef<ZyppContextRefType>> result ) {
935 ProgressObserver::finish(
subProgress, ProgressObserver::Success );
938 ProgressObserver::finish(
subProgress, ProgressObserver::Error );
944 ProgressObserver::finish(
myProgress, ProgressObserver::Success );
958 template<
typename ZyppContextRefType>
963 RepoManagerWorkflow::refreshGeoIPData(
_zyppContext, {url} )
965 |
and_then( [
this, path = path](
auto mediaHandle ) {
966 return RepoManagerWorkflow::probeRepoType(
_zyppContext, std::forward<
decltype(mediaHandle)>(mediaHandle), path );
970 template<
typename ZyppContextRefType>
983 template<
typename ZyppContextRefType>
989 template<
typename ZyppContextRefType>
996 template <
typename ZyppContextRefType>
1002 template <
typename ZyppContextRefType>
1010 if ( hasService( service.
alias() ) )
1016 saveService(
toSave ).unwrap();
1017 _services.insert(
toSave );
1022 MIL <<
"added service " <<
toSave.alias() << std::endl;
1031 template<
typename ZyppContextRefType>
1040 template<
typename ZyppContextRefType>
1062 template <
typename ZyppContextRefType>
1066 MIL <<
"Going to delete service " << alias << std::endl;
1068 const ServiceInfo & service = getService( alias );
1071 if( location.
empty() )
1080 if (
tmpSet.size() == 1 )
1087 MIL << alias <<
" successfully deleted." << std::endl;
1093 std::ofstream file(location.
c_str());
1102 if(
it->alias() != alias )
1103 it->dumpAsIniOn(file);
1106 MIL << alias <<
" successfully deleted from file " << location << std::endl;
1111 getRepositoriesInService( alias,
1112 boost::make_function_output_iterator( std::bind( &RepoCollector::collect, &
rcollector, std::placeholders::_1 ) ) );
1115 removeRepository(*rit).unwrap();
1124 template <
typename ZyppContextRefType>
1129 MIL <<
"Going to modify service " << oldAlias << std::endl;
1135 if ( service.
type() == zypp::repo::ServiceType::PLUGIN )
1143 if( location.
empty() )
1153 std::ofstream file(location.
c_str());
1156 if( *
it != oldAlias )
1157 it->dumpAsIniOn(file);
1163 _services.erase(oldAlias);
1164 _services.insert(service);
1170 if ( oldAlias != service.
alias()
1173 std::vector<RepoInfo> toModify;
1174 getRepositoriesInService(oldAlias, std::back_inserter(toModify));
1175 for_(
it, toModify.begin(), toModify.end() )
1182 const auto & last = service.
repoStates().find(
it->alias() );
1184 it->setEnabled( last->second.enabled );
1187 it->setEnabled(
false );
1190 if ( oldAlias != service.
alias() )
1191 it->setService(service.
alias());
1193 modifyRepository(
it->alias(), *
it).unwrap();
1207 template <
typename ZyppContextRefType>
1214 generateFilename( service ) );
1217 MIL <<
"saving service in " <<
servfile << std::endl;
1219 std::ofstream file(
servfile.c_str() );
1226 MIL <<
"done" << std::endl;
1250 template <
typename ZyppContextRefType>
1264 template <
typename ZyppContextRefType>
1306 template<
typename ZyppContextRefType>
1312 template <
typename ZyppContextRefType>
1315 return touchIndexFile( info,
_options );
1318 template <
typename ZyppContextRefType>
1323 std::list<zypp::Pathname> entries;
1333 for_(
it, entries.begin(), entries.end() )
1366 std::list<std::string> entries;
1392 template <
typename ZyppContextRefType>
1397 MIL <<
"start construct known repos" << std::endl;
1410 _reposX.insert( repoInfo );
1413 const std::string &
serviceAlias( repoInfo.service() );
1416 WAR <<
"Schedule orphaned service repo for deletion: " << repoInfo << std::endl;
1429 MIL <<
"Delete orphaned service repo " << repoInfo.alias() << std::endl;
1434 % repoInfo.service()
1435 % repoInfo.alias() );
1437 removeRepository( repoInfo ).unwrap();
1467 MIL <<
"end construct known repos" << std::endl;
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
AutoDispose()
Default Ctor using default constructed value and no dispose function.
static const ValueType day
static Date now()
Return the current time.
Base class for Exception.
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.
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.
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::string targetDistribution() const
Distribution for which is this repository meant.
Track changing files or directories.
static RepoStatus fromCookieFileUseMtime(const Pathname &path)
Reads the status from a cookie file but uses the files mtime.
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.
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.
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 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.
static const SolvAttr repositoryToolVersion
bool error(std::string msg_r, UserData userData_r=UserData())
send error text
bool warning(std::string msg_r, UserData userData_r=UserData())
send warning text
The RepoManager class Provides knowledge and methods to maintain repo settings and metadata for a giv...
std::set< ServiceInfo > ServiceSet
ServiceInfo typedefs.
RepoSet::const_iterator RepoConstIterator
zypp::RepoManagerFlags::RefreshServiceOptions RefreshServiceOptions
Functor collecting ServiceInfos into a ServiceSet.
static expected success(ConsParams &&...params)
static expected< repo::RefreshContextRef< ZyppContextRefType > > create(ZyppContextRefType zyppContext, zypp::RepoInfo info, RepoManagerRef< ContextRefType > repoManager)
String related utilities and Regular expression matching.
RefreshCheckStatus
Possibly return state of RepoManager::checkIfToRefreshMetadata function.
Namespace intended to collect all environment variables we use.
int recursive_rmdir(const Pathname &path)
Like 'rm -r DIR'.
int unlink(const Pathname &path)
Like 'unlink'.
int readdir(std::list< std::string > &retlist_r, const Pathname &path_r, bool dots_r)
Return content of directory via retlist.
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.
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
std::string join(const ParamVec &pvec, const std::string &psep)
Join parameter vector to a string.
std::ostream & operator<<(std::ostream &str, const SerialNumber &obj)
std::string asString(const Patch::Category &obj)
AsyncOpRef< expected< repo::RefreshCheckStatus > > checkIfToRefreshMetadata(repo::AsyncRefreshContextRef refCtx, LazyMediaHandle< Provide > medium, ProgressObserverRef progressObserver)
AsyncOpRef< expected< repo::AsyncRefreshContextRef > > refreshMetadata(repo::AsyncRefreshContextRef refCtx, LazyMediaHandle< Provide > medium, ProgressObserverRef progressObserver)
AsyncOpRef< expected< repo::AsyncRefreshContextRef > > buildCache(repo::AsyncRefreshContextRef refCtx, zypp::RepoManagerFlags::CacheBuildPolicy policy, ProgressObserverRef progressObserver)
bool ZYPP_PLUGIN_APPDATA_FORCE_COLLECT()
To trigger appdata refresh unconditionally.
auto incProgress(ProgressObserverRef progressObserver, double progrIncrease=1.0, std::optional< std::string > newStr={})
Exp mtry(F &&f, Args &&...args)
bool isTmpRepo(const RepoInfo &info_r)
Whether repo is not under RM control and provides its own methadata paths.
expected< void > assert_urls(const RepoInfo &info)
std::list< RepoInfo > repositories_in_dir(ZContextRef zyppContext, const zypp::Pathname &dir)
List of RepoInfo's from a directory.
std::string filenameFromAlias(const std::string &alias_r, const std::string &stem_r)
Generate a related filename from a repo/service infos alias.
expected< zypp::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.
expected< void > assert_alias(const RepoInfo &info)
ResultType or_else(const expected< T, E > &exp, Function &&f)
ResultType and_then(const expected< T, E > &exp, Function &&f)
auto joinPipeline(ContextRef ctx, AsyncOpRef< T > res)
expected< zypp::Pathname > solv_path_for_repoinfo(const RepoManagerOptions &opt, const RepoInfo &info)
Calculates the solv cache path for a repository.
expected< std::list< RepoInfo > > repositories_in_file(const zypp::Pathname &file)
Reads RepoInfo's from a repo file.
Iterator findAlias(const std::string &alias_r, Iterator begin_r, Iterator end_r)
Find alias_r in repo/service container.
std::enable_if_t<!std::is_same_v< void, T >, expected< Container< T >, E > > collect(Container< expected< T, E >, CArgs... > &&in)
expected< zypp::Pathname > packagescache_path_for_repoinfo(const RepoManagerOptions &opt, const RepoInfo &info)
Calculates the packages cache path for a repository.
expected< zypp::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,...
Container< Ret > transform(Container< Msg, CArgs... > &&val, Transformation &&transformation)
expected< T, E > inspect(expected< T, E > exp, Function &&f)
bool autoPruneInDir(const zypp::Pathname &path_r)
bsc#1204956: Tweak to prevent auto pruning package caches.
ZyppContextRefType _zyppContext
zypp::RepoManager::RefreshServiceOptions _options
creates and provides information about known sources.
void cleanCacheDirGarbage(const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Remove any subdirectories of cache directories which no longer belong to any of known repositories.
void cleanMetadata(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Clean local metadata.
void addService(const std::string &alias, const Url &url)
Adds a new service by its alias and URL.
void removeService(const std::string &alias)
Removes service specified by its name.
repo::ServiceType probeService(const Url &url) const
Probe the type or the service.
void cleanCache(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
clean local cache
void refreshServices(const RefreshServiceOptions &options_r=RefreshServiceOptions())
Refreshes all enabled services.
void addRepository(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Adds a repository to the list of known repositories.
void addRepositories(const Url &url, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Adds repositores from a repo file to the list of known repositories.
void refreshMetadata(const RepoInfo &info, RawMetadataRefreshPolicy policy=RefreshIfNeeded, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Refresh local raw cache.
void refreshGeoIp(const RepoInfo::url_set &urls)
void refreshService(const std::string &alias, const RefreshServiceOptions &options_r=RefreshServiceOptions())
Refresh specific service.
void modifyRepository(const std::string &alias, const RepoInfo &newinfo, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Modify repository attributes.
void removeRepository(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Remove the best matching repository from known repos list.
RepoInfo getRepositoryInfo(const std::string &alias, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Find a matching repository info.
RefreshCheckStatus checkIfToRefreshMetadata(const RepoInfo &info, const Url &url, RawMetadataRefreshPolicy policy=RefreshIfNeeded)
Checks whether to refresh metadata for specified repository and url.
void buildCache(const RepoInfo &info, CacheBuildPolicy policy=BuildIfNeeded, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Refresh local cache.
void loadFromCache(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Load resolvables into the pool.
void cleanPackages(const RepoInfo &info, const ProgressData::ReceiverFnc &progressrcv=ProgressData::ReceiverFnc())
Clean local package cache.
RepoStatus metadataStatus(const RepoInfo &info) const
Status of local metadata.
void modifyService(const std::string &oldAlias, const ServiceInfo &service)
Modifies service file (rewrites it with new values) and underlying repositories if needed.
repo::RepoType probe(const Url &url, const Pathname &path) const
Probe repo metadata type.
Repository type enumeration.
static const RepoType YAST2
static const RepoType RPMMD
static const RepoType NONE
static const RepoType RPMPLAINDIR
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Url::asString() view options.
Simple callback to collect the results.
bool collect(const RepoInfo &repo)
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
#define ZYPP_PRIVATE_CONSTR_ARG