14#include <zypp-core/zyppng/io/Process>
15#include <zypp-core/zyppng/pipelines/MTry>
16#include <zypp-core/zyppng/pipelines/Algorithm>
17#include <zypp-media/MediaException>
18#include <zypp-media/ng/Provide>
19#include <zypp-media/ng/ProvideSpec>
24#include <zypp/ng/Context>
33#undef ZYPP_BASE_LOGGER_LOGGROUP
34#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::repomanager"
42 template <
class Executor,
class OpType>
43 struct ProbeRepoLogic :
public LogicBase<Executor, OpType>
51 using MediaHandle =
typename ProvideType::MediaHandle;
58 ,
_path(std::move(path))
63 const auto &url =
_medium.baseUrl();
64 MIL <<
"going to probe the repo type at " << url <<
" (" <<
_path <<
")" << std::endl;
68 MIL <<
"Probed type NONE (not exists) at " << url <<
" (" <<
_path <<
")" << std::endl;
93 std::rethrow_exception (err);
98 DBG <<
"problem checking for repodata/repomd.xml file" << std::endl;
113 std::rethrow_exception (err);
118 DBG <<
"problem checking for content file" << std::endl;
130 const auto &url =
medium.baseUrl();
133 if ( ! ( url.schemeIsDownloading() || url.schemeIsPlugin() ) ) {
137 MIL <<
"Probed type RPMPLAINDIR at " << url <<
" (" <<
_path <<
")" << std::endl;
145 MIL <<
"Probed type NONE at " << url <<
" (" <<
_path <<
")" << std::endl;
161 return std::move(file)
179 template <
class RefreshContextRef>
185 return probeRepoType( ctx, std::forward<decltype(mediaHandle)>(mediaHandle), path );
212 template <
class ZyppContextRef>
218 DBG <<
"reading repo file " <<
repoFileUrl <<
", local path: " <<
local.file() << std::endl;
236 template<
typename Executor,
class OpType>
237 struct CheckIfToRefreshMetadataLogic :
public LogicBase<Executor, OpType> {
243 using ZyppContextRefType =
typename RefreshContextRefType::element_type::ContextRefType;
244 using ZyppContextType =
typename RefreshContextRefType::element_type::ContextType;
245 using ProvideType =
typename ZyppContextType::ProvideType;
247 using MediaHandle =
typename ProvideType::MediaHandle;
258 MIL <<
"Going to CheckIfToRefreshMetadata" << std::endl;
264 MIL <<
"Check if to refresh repo " <<
_refreshContext->repoInfo().alias() <<
" at " <<
_medium.baseUrl() <<
" (" << info.type() <<
")" << std::endl;
274 MIL <<
"No cached metadata, going to refresh" << std::endl;
278 if (
_medium.baseUrl().schemeIsVolatile() ) {
279 MIL <<
"Never refresh CD/DVD" << std::endl;
284 MIL <<
"Forced refresh!" << std::endl;
288 if (
_medium.baseUrl().schemeIsLocal() ) {
307 WAR <<
"Repository '" << info.alias() <<
"' was refreshed in the future!" << std::endl;
310 MIL <<
"Repository '" << info.alias()
311 <<
"' has been refreshed less than repo.refresh.delay ("
313 <<
") minutes ago. Advising to skip refresh" << std::endl;
319 MIL <<
"Metadata and solv cache don't match. Check data on server..." << std::endl;
338 MIL <<
"repo has not changed" << std::endl;
343 MIL <<
"repo has changed, going to refresh" << std::endl;
372 template<
typename Executor,
class OpType>
373 struct RefreshMetadataLogic :
public LogicBase<Executor, OpType>{
380 using ZyppContextRefType =
typename RefreshContextRefType::element_type::ContextRefType;
381 using ZyppContextType =
typename RefreshContextRefType::element_type::ContextType;
382 using ProvideType =
typename ZyppContextType::ProvideType;
383 using MediaHandle =
typename ProvideType::MediaHandle;
388 using DlContextRefType = std::shared_ptr<DlContextType>;
403 MIL <<
"RefreshCheckStatus returned: " << status << std::endl;
417 MIL <<
"Going to refresh metadata from " <<
_medium.baseUrl() << std::endl;
428 _refreshContext->setProbedType( repokind );
430 info.setProbedType( repokind );
449 |
and_then([
this]( DlContextRefType && ) {
482 template <
class RefreshContextRef>
519 ERR <<
"Giving up..." << std::endl;
523 ERR <<
"Trying another url..." << std::endl;
532 return refCtx->repoInfo().baseUrls()
537 ERR <<
"No more urls..." << std::endl;
557 template <
typename ZyppCtxRef>
struct Repo2SolvOp;
565 MIL <<
"Starting repo2solv for repo " << repo.
alias () << std::endl;
566 auto me = std::make_shared<Repo2SolvOp<ContextRef>>();
567 me->_repo = std::move(repo);
572 std::vector<const char *>
argsIn;
573 argsIn.reserve ( args.size() );
574 std::for_each( args.begin (), args.end(), [&](
const std::string &
s ) { argsIn.push_back(s.data()); });
575 argsIn.push_back (
nullptr);
577 if (!
me->_proc->start(
argsIn.data() )) {
590 void procFinished(
int ret ) {
592 while (
_proc->canReadLine() )
633 template<
typename Executor,
class OpType>
634 struct BuildCacheLogic :
public LogicBase<Executor, OpType>{
637 using ZyppContextRefType =
typename RefreshContextRefType::element_type::ContextRefType;
638 using ZyppContextType =
typename RefreshContextRefType::element_type::ContextType;
639 using ProvideType =
typename ZyppContextType::ProvideType;
640 using MediaHandle =
typename ProvideType::MediaHandle;
662 const auto &options =
_refCtx->repoManagerOptions();
665 auto ex = ZYPP_EXCPT_PTR( zypp::Exception (zypp::str::form( _(
"Can't create %s"), options.repoCachePath.c_str()) ) );
666 return expected<RepoStatus>::error( std::move(ex) );
699 const auto &info =
_refCtx->repoInfo();
700 if (
_refCtx->repoManager()->isCached( info ) )
702 MIL << info.alias() <<
" is already cached." << std::endl;
709 MIL << info.alias() <<
" cache is up to date with metadata." << std::endl;
723 MIL << info.alias() <<
" cache rebuild is forced" << std::endl;
734 auto r =
_refCtx->repoManager()->cleanCache(info);
739 MIL << info.alias() <<
" building cache..." << info.type() << std::endl;
778 const auto &info =
_refCtx->repoInfo();
782 case zypp::repo::RepoType::RPMMD_e :
783 case zypp::repo::RepoType::YAST2_e :
784 case zypp::repo::RepoType::RPMPLAINDIR_e :
787 zypp::ManagedFile guard( solvfile, zypp::filesystem::unlink );
789 zypp::ExternalProgram::Arguments cmd;
790#ifdef ZYPP_REPO2SOLV_PATH
791 cmd.push_back( ZYPP_REPO2SOLV_PATH );
793 cmd.push_back( zypp::PathInfo(
"/usr/bin/repo2solv" ).isFile() ?
"repo2solv" :
"repo2solv.sh" );
796 cmd.push_back(
"-o" );
797 cmd.push_back( solvfile.asString() );
798 cmd.push_back(
"-X" );
801 if ( repokind == zypp::repo::RepoType::RPMPLAINDIR )
804 cmd.push_back(
"-R" );
806 std::optional<zypp::Pathname> localPath = forPlainDirs.has_value() ? forPlainDirs->localPath() : zypp::Pathname();
808 return makeReadyResult( expected<void>::error( ZYPP_EXCPT_PTR( zypp::repo::RepoException( zypp::str::Format(_(
"Failed to cache repo %1%")) % _refCtx->repoInfo() ))) );
811 cmd.push_back( (*localPath / info.path().absolutename()).c_str() );
814 cmd.push_back( _productdatapath.asString() );
816 return Repo2SolvOp<ZyppContextRefType>::run( info, std::move(cmd) )
817 | and_then( [this, guard = std::move(guard), solvfile = std::move(solvfile) ]() mutable {
819 guard.resetDispose();
820 return mtry( zypp::sat::updateSolvFileIndex, solvfile );
835 MIL <<
"Commit cache.." << std::endl;
840 |
or_else ( [
this]( std::exception_ptr
e ) {
852 |
and_then( [
this]( MediaHandle handle ) {
881 template<
typename Executor,
class OpType>
882 struct AddRepoLogic :
public LogicBase<Executor, OpType>{
900 MIL <<
"Try adding repo " <<
_info << std::endl;
910 DBG <<
"unknown repository type, probing" << std::endl;
929 MIL <<
"done" << std::endl;
932 |
or_else( [
this]( std::exception_ptr
e) {
934 MIL <<
"done" << std::endl;
958 template<
typename Executor,
class OpType>
959 struct AddReposLogic :
public LogicBase<Executor, OpType>{
975 |
and_then([
this]( std::list<RepoInfo> repos ) {
977 for ( std::list<RepoInfo>::const_iterator
it = repos.begin();
984 if ( (*it).alias() == (*kit).alias() )
986 ERR <<
"To be added repo " << (*it).alias() <<
" conflicts with existing repo " << (*kit).alias() << std::endl;
1006 MIL <<
"Saving " << repos.size() <<
" repo" << ( repos.size() ?
"s" :
"" ) <<
" in " <<
repofile << std::endl;
1008 std::ofstream file(
repofile.c_str());
1015 for ( std::list<RepoInfo>::iterator
it = repos.begin();
1019 MIL <<
"Saving " << (*it).alias() << std::endl;
1027 it->dumpAsIniOn(file);
1029 it->setMetadataPath( *rawCachePath );
1036 MIL <<
"done" << std::endl;
1062 template<
typename Executor,
class OpType>
1063 struct RefreshGeoIpLogic :
public LogicBase<Executor, OpType>{
1069 using ZyppContextType =
typename ZyppContextRefType::element_type;
1070 using ProvideType =
typename ZyppContextType::ProvideType;
1071 using MediaHandle =
typename ProvideType::MediaHandle;
1072 using ProvideRes =
typename ProvideType::Res;
1084 if ( !
_zyppCtx->config().geoipEnabled() ) {
1085 MIL <<
"GeoIp disabled via ZConfig, not refreshing the GeoIP information." << std::endl;
1089 std::vector<std::string>
hosts;
1090 for (
const auto &baseUrl :
_urls ) {
1091 const auto &host = baseUrl.getHost();
1092 if (
zypp::any_of(
_zyppCtx->config().geoipHostnames(), [&host](
const auto &
elem ){ return ( zypp::str::compareCI( host, elem ) == 0 ); } ) ) {
1093 hosts.push_back( host );
1098 if (
hosts.empty() ) {
1099 MIL <<
"No configured geoip URL found, not updating geoip data" << std::endl;
1106 MIL <<
"Unable to create cache directory for GeoIP." << std::endl;
1111 MIL <<
"No access rights for the GeoIP cache directory." << std::endl;
1121 auto age = std::chrono::system_clock::now() - std::chrono::system_clock::from_time_t(
pi.mtime() );
1122 if (
age < std::chrono::hours(24) )
1125 MIL <<
"Removing GeoIP file for " <<
entry.name <<
" since it's older than 24hrs." << std::endl;
1130 auto firstOfCb = [
this]( std::string hostname ) {
1134 MIL <<
"Skipping GeoIP request for " << hostname <<
" since a valid cache entry exists." << std::endl;
1138 MIL <<
"Query GeoIP for " << hostname << std::endl;
1147 MIL <<
"Ignoring invalid GeoIP hostname: " << hostname << std::endl;
1154 |
inspect_err( [hostname](
const std::exception_ptr& ){
MIL <<
"Failed to query GeoIP from hostname: " << hostname << std::endl; } )
1161 out.open(
fName.asString(), std::ios_base::trunc );
1162 if ( out.is_open() ) {
1163 out << host << std::endl;
1165 MIL <<
"Failed to create/open GeoIP cache file " <<
fName << std::endl;
1172 if (
reader.seekToNode( 1,
"host" ) ) {
1173 const auto &
str =
reader.nodeText().asString();
1181 MIL <<
"Storing geoIP redirection: " << hostname <<
" -> " <<
str << std::endl;
1186 MIL <<
"No host entry or empty file returned for GeoIP, remembering for 24hrs" << std::endl;
1190 MIL <<
"Empty or invalid GeoIP file, not requesting again for 24hrs" << std::endl;
1199 return std::move(
hosts)
1204 MIL <<
"Successfully queried GeoIP data." << std::endl;
1208 MIL <<
"Failed to query GeoIP data." << std::endl;
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
reference value() const
Reference to the Tp object.
void resetDispose()
Set no dispose function.
std::string asString() const
static Date now()
Return the current time.
Base class for Exception.
void remember(const Exception &old_r)
Store an other Exception as history.
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 addRepository(const RepoInfo &repo)
Log a newly added repository.
What is known about a repository.
Url url() const
Pars pro toto: The first repository url.
Pathname path() const
Repository path.
Track changing files or directories.
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 setHost(const std::string &host)
Set the hostname or IP in the URL authority.
void setScheme(const std::string &scheme)
Set the scheme name in the URL.
Wrapper class for stat/lstat.
bool isExist() const
Return whether valid stat info exists.
Pathname dirname() const
Return all but the last component od this path.
std::string basename() const
Return the last component of this path.
Repository already exists and some unique attribute can't be duplicated.
Exception for repository handling.
std::string alias() const
unique identifier for this source.
thrown if the user has no permission to update(write) the caches.
thrown when it was impossible to determine this repo type.
xmlTextReader based interface to iterate xml streams.
SignalProxy< void()> sigReadyRead()
SignalProxy< void(int)> sigFinished()
static ProgressObserverRef makeSubTask(ProgressObserverRef parentProgress, float weight=1.0, const std::string &label=std::string(), int steps=100)
static void setup(ProgressObserverRef progress, const std::string &label=std::string(), int steps=100)
static void finish(ProgressObserverRef progress, ProgressObserver::FinishResult result=ProgressObserver::Success)
A ProvideRes object is a reference counted ownership of a resource in the cache provided by a Provide...
The RepoManager class Provides knowledge and methods to maintain repo settings and metadata for a giv...
expected< RepoStatus > cacheStatus(const RepoInfo &info) const
static expected< void > touchIndexFile(const RepoInfo &info, const RepoManagerOptions &options)
static zypp::repo::RepoType probeCache(const zypp::Pathname &path_r)
Probe Metadata in a local cache directory.
static expected< RepoStatus > metadataStatus(const RepoInfo &info, const RepoManagerOptions &options)
static expected success(ConsParams &&...params)
static expected error(ConsParams &&...params)
#define ZYPP_ENABLE_LOGIC_BASE(Executor, OpType)
typename conditional< B, T, F >::type conditional_t
String related utilities and Regular expression matching.
RefreshCheckStatus
Possibly return state of RepoManager::checkIfToRefreshMetadata function.
@ REFRESH_NEEDED
refresh is needed
@ REPO_UP_TO_DATE
repository not changed
@ REPO_CHECK_DELAYED
refresh is delayed due to settings
@ RefreshIfNeededIgnoreDelay
bool provide(const Pathname &delta_r, const Pathname &new_r, const Progress &report_r)
Apply a binary delta to on-disk data to re-create a new rpm.
int unlink(const Pathname &path)
Like 'unlink'.
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
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 form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
std::list< RepoInfo > readRepoFile(const Url &repo_file)
Parses repo_file and returns a list of RepoInfo objects corresponding to repositories found within th...
bool any_of(const Container &c, Fnc &&cb)
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver=nullptr)
AsyncOpRef< expected< zypp::RepoStatus > > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle)
AsyncOpRef< expected< zypp::repo::RepoType > > probeRepoType(ContextRef ctx, AsyncLazyMediaHandle medium, zypp::Pathname path, std::optional< zypp::Pathname > targetPath)
AsyncOpRef< expected< RepoInfo > > addRepository(AsyncRepoManagerRef mgr, RepoInfo info, ProgressObserverRef myProgress)
AsyncOpRef< expected< repo::RefreshCheckStatus > > checkIfToRefreshMetadata(repo::AsyncRefreshContextRef refCtx, LazyMediaHandle< Provide > medium, ProgressObserverRef progressObserver)
AsyncOpRef< expected< std::list< RepoInfo > > > readRepoFile(ContextRef ctx, zypp::Url repoFileUrl)
AsyncOpRef< expected< void > > refreshGeoIPData(ContextRef ctx, RepoInfo::url_set urls)
AsyncOpRef< expected< void > > addRepositories(AsyncRepoManagerRef mgr, zypp::Url url, ProgressObserverRef myProgress)
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)
auto or_else(Fun &&function)
auto and_then(Fun &&function)
auto mtry(Fun &&function)
Exp mtry(F &&f, Args &&...args)
expected< void > assert_urls(const RepoInfo &info)
std::conditional_t< isAsync, AsyncOpRef< T >, T > makeReadyResult(T &&result)
typename remove_smart_ptr< T >::type remove_smart_ptr_t
static expected< std::decay_t< Type >, Err > make_expected_success(Type &&t)
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 firstOf(Transformation &&transformFunc, DefaultType &&def, Predicate &&predicate=detail::ContinueUntilValidPredicate())
RepoManagerRef< SyncContextRef > SyncRepoManagerRef
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.
RepoManagerRef< ContextRef > AsyncRepoManagerRef
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,...
expected< T, E > inspect(expected< T, E > exp, Function &&f)
expected< T, E > inspect_err(expected< T, E > exp, Function &&f)
RepoManagerPtrType _repoMgrRef
ZyppContextRefType _zyppContext
std::optional< zypp::Pathname > _targetPath
zypp::Pathname _productdatapath
RefreshContextRefType _refreshContext
zypp::Pathname _geoIPCache
zypp::repo::RepoException _error
zypp::RepoManagerFlags::CacheBuildPolicy _policy
ProgressObserverRef _progress
RefreshContextRefType _refCtx
ZyppContextRefType _zyppCtx
ProgressObserverRef _myProgress
zypp::Pathname _mediarootpath
ProgressObserverRef _progressObserver
Listentry returned by readdir.
Repository type enumeration.
static const RepoType YAST2
static const RepoType RPMMD
static const RepoType NONE
static const RepoType RPMPLAINDIR
Functor replacing repository variables.
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
auto makeReadyResult(T &&res)
#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_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.