13 #include <zypp-core/zyppng/pipelines/MTry> 14 #include <zypp-media/MediaException> 15 #include <zypp-media/ng/Provide> 16 #include <zypp-media/ng/ProvideSpec> 18 #include <zypp/ng/Context> 29 template <
class Executor,
class OpType>
30 struct ProbeRepoLogic :
public LogicBase<Executor, OpType>
37 using ProvideType =
typename remove_smart_ptr_t<ZyppContextRefType>::ProvideType;
38 using MediaHandle =
typename ProvideType::MediaHandle;
39 using ProvideRes =
typename ProvideType::Res;
41 ProbeRepoLogic(ZyppContextRefType zyppCtx, MediaHandle &&medium,
zypp::Pathname &&path, std::optional<zypp::Pathname> &&targetPath )
48 MaybeAsyncRef<expected<zypp::repo::RepoType>> execute( ) {
49 const auto &url =
_medium.baseUrl();
50 MIL <<
"going to probe the repo type at " << url <<
" (" <<
_path <<
")" << std::endl;
54 MIL <<
"Probed type NONE (not exists) at " << url <<
" (" <<
_path <<
")" << std::endl;
64 std::shared_ptr<ProvideType> providerRef =
_zyppContext->provider();
70 return providerRef->provide(
_medium,
_path/
"repodata/repomd.xml", ProvideFileSpec().setCheckExistsOnly( !
_targetPath.has_value() ) )
71 | and_then( maybeCopyResultToDest(
"repodata/repomd.xml") )
74 | or_else( [
this, providerRef]( std::exception_ptr err ) {
76 std::rethrow_exception (err);
81 DBG <<
"problem checking for repodata/repomd.xml file" << std::endl;
86 return makeReadyResult( expected<zypp::repo::RepoType>::error( std::current_exception() ) );
88 return providerRef->provide(
_medium,
_path/
"content", ProvideFileSpec().setCheckExistsOnly( !
_targetPath.has_value() ) )
89 | and_then( maybeCopyResultToDest(
"content") )
93 | or_else( [
this]( std::exception_ptr err ) {
96 std::rethrow_exception (err);
101 DBG <<
"problem checking for content file" << std::endl;
107 return expected<zypp::repo::RepoType>::error(
ZYPP_EXCPT_PTR(e) );
110 return expected<zypp::repo::RepoType>::error( std::current_exception() );
113 const auto &url =
_medium.baseUrl();
116 if ( ! ( url.schemeIsDownloading() || url.schemeIsPlugin() ) ) {
120 MIL <<
"Probed type RPMPLAINDIR at " << url <<
" (" <<
_path <<
")" << std::endl;
128 MIL <<
"Probed type NONE at " << url <<
" (" <<
_path <<
")" << std::endl;
139 auto maybeCopyResultToDest ( std::string &&subPath ) {
140 return [
this, subPath = std::move(subPath)]( ProvideRes file ) -> MaybeAsyncRef<expected<void>> {
142 MIL <<
"Target path is set, copying " << file.file() <<
" to " << *
_targetPath/subPath << std::endl;
143 return std::move(file)
147 return makeReadyResult( expected<void>::success() );
177 template<
typename Executor,
class OpType>
178 struct CheckIfToRefreshMetadataLogic :
public LogicBase<Executor, OpType> {
184 using ZyppContextRefType =
typename RefreshContextRefType::element_type::ContextRefType;
185 using ZyppContextType =
typename RefreshContextRefType::element_type::ContextType;
186 using ProvideType =
typename ZyppContextType::ProvideType;
187 using MediaHandle =
typename ProvideType::MediaHandle;
190 CheckIfToRefreshMetadataLogic( RefreshContextRefType refCtx, MediaHandle &&medium, ProgressObserverRef progressObserver )
196 MaybeAsyncRef<expected<repo::RefreshCheckStatus>> execute( ) {
198 MIL <<
"Going to CheckIfToRefreshMetadata" << std::endl;
202 | and_then( [
this](){
206 MIL <<
"Check if to refresh repo " <<
_refreshContext->repoInfo().alias() <<
" at " <<
_medium.baseUrl() <<
" (" << info.type() <<
")" << std::endl;
214 if ( oldstatus.
empty() ) {
215 MIL <<
"No cached metadata, going to refresh" << std::endl;
219 if (
_medium.baseUrl().schemeIsVolatile() ) {
220 MIL <<
"Never refresh CD/DVD" << std::endl;
225 MIL <<
"Forced refresh!" << std::endl;
229 if (
_medium.baseUrl().schemeIsLocal() ) {
241 if ( oldstatus == cachestatus ) {
244 const auto refDelay =
_refreshContext->zyppContext()->config().repo_refresh_delay();
245 if ( diff < refDelay ) {
247 WAR <<
"Repository '" << info.alias() <<
"' was refreshed in the future!" << std::endl;
250 MIL <<
"Repository '" << info.alias()
251 <<
"' has been refreshed less than repo.refresh.delay (" 253 <<
") minutes ago. Advising to skip refresh" << std::endl;
259 MIL <<
"Metadata and solv cache don't match. Check data on server..." << std::endl;
267 return makeReadyResult( expected<zypp::repo::RepoType>::success(repokind) );
277 if ( oldstatus == newstatus ) {
278 MIL <<
"repo has not changed" << std::endl;
283 MIL <<
"repo has changed, going to refresh" << std::endl;
284 MIL <<
"Old status: " << oldstatus <<
" New Status: " << newstatus << std::endl;
313 template<
typename Executor,
class OpType>
314 struct RefreshMetadataLogic :
public LogicBase<Executor, OpType>{
321 using ZyppContextRefType =
typename RefreshContextRefType::element_type::ContextRefType;
322 using ZyppContextType =
typename RefreshContextRefType::element_type::ContextType;
323 using ProvideType =
typename ZyppContextType::ProvideType;
324 using MediaHandle =
typename ProvideType::MediaHandle;
328 using DlContextRefType = std::shared_ptr<DlContextType>;
330 RefreshMetadataLogic( RefreshContextRefType refCtx, MediaHandle &&medium, ProgressObserverRef progressObserver )
335 MIL <<
"Constructor called" << std::endl;
338 MaybeAsyncRef<expected<RefreshContextRefType>> execute() {
348 MIL <<
"RefreshCheckStatus returned: " << status << std::endl;
353 return makeReadyResult ( expected<RefreshContextRefType>::success( std::move(
_refreshContext) ) );
355 MIL <<
"Going to refresh metadata from " <<
_medium.baseUrl() << std::endl;
365 if ( info.type() != repokind ) {
368 info.setProbedType( repokind );
378 return makeReadyResult( expected<DlContextRefType>::error( std::move(exception) ));
382 dlContext->setPluginRepoverification(
_refreshContext->pluginRepoverification() );
387 | and_then([
this]( DlContextRefType && ) {
396 return expected<RefreshContextRefType>::success( std::move(
_refreshContext) );
410 refreshGeoIPData( info.baseUrls() );
413 RepoException rexception( info,
PL_(
"Valid metadata not found at specified URL",
414 "Valid metadata not found at specified URLs",
415 info.baseUrlsSize() ) );
418 media::ScopedDisableMediaChangeReport guard( info.baseUrlsSize() > 1 );
420 for ( RepoInfo::urls_const_iterator it = info.baseUrlsBegin(); it != info.baseUrlsEnd(); ++it )
431 MIL <<
"Going to refresh metadata from " << url << endl;
434 repo::RepoType repokind = info.type();
436 repo::RepoType probed = probe( *it, info.path() );
443 if ( ( repokind.toEnum() == RepoType::RPMMD_e ) ||
444 ( repokind.toEnum() == RepoType::YAST2_e ) )
447 shared_ptr<repo::Downloader> downloader_ptr;
449 MIL <<
"Creating downloader for [ " << info.alias() <<
" ]" << endl;
451 if ( repokind.toEnum() == RepoType::RPMMD_e ) {
452 downloader_ptr.reset(
new yum::Downloader(info, mediarootpath ));
453 if ( _pluginRepoverification.checkIfNeeded() )
454 downloader_ptr->setPluginRepoverification( _pluginRepoverification );
457 downloader_ptr.reset(
new susetags::Downloader(info, mediarootpath) );
465 for_( it, repoBegin(), repoEnd() )
468 if ( PathInfo(cachepath).isExist() )
469 downloader_ptr->addCachePath(cachepath);
473 downloader_ptr->download( media, tmpdir.path() );
475 else if ( repokind.toEnum() == RepoType::RPMPLAINDIR_e )
478 MediaMounter media( url );
479 RepoStatus newstatus = RepoStatus( media.getPathName( info.path() ) );
481 Pathname productpath( tmpdir.path() / info.path() );
483 newstatus.saveToCookieFile( productpath/
"cookie" );
499 catch (
const Exception &e )
502 ERR <<
"Trying another url..." << endl;
507 if (it == info.baseUrlsBegin())
508 rexception.remember(e);
510 rexception.addHistory( e.asUserString() );
514 ERR <<
"No more urls..." << endl;
530 namespace RepoManagerWorkflow {
expected< repo::SyncRefreshContextRef > refreshMetadata(repo::SyncRefreshContextRef refCtx, SyncMediaHandle medium, ProgressObserverRef progressObserver)
RefreshContextRefType _refreshContext
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
AsyncOpRef< expected< repo::AsyncDownloadContextRef > > download(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle, ProgressObserverRef progressObserver=nullptr)
bool empty() const
Whether the status is empty (empty checksum)
refresh is delayed due to settings
constexpr std::string_view Url("url")
int exchange(const Pathname &lpath, const Pathname &rpath)
Exchanges two files or directories.
thrown when it was impossible to determine this repo type.
RepoStatus cacheStatus(const RepoInfo &info) const
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
RefreshCheckStatus
Possibly return state of checkIfRefreshMEtadata function.
A ProvideRes object is a reference counted ownership of a resource in the cache provided by a Provide...
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
zypp::Pathname _mediarootpath
const char * c_str() const
String representation.
What is known about a repository.
std::optional< zypp::Pathname > _targetPath
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
ProgressObserverRef _progress
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
ZyppContextRefType _zyppContext
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 remember(const Exception &old_r)
Store an other Exception as history.
zypp::repo::RepoException _error
void assert_alias(const RepoInfo &info)
#define ZYPP_ENABLE_LOGIC_BASE(Executor, OpType)
AsyncOpRef< expected< repo::RefreshCheckStatus > > checkIfToRefreshMetadata(repo::AsyncRefreshContextRef refCtx, ProvideMediaHandle medium, ProgressObserverRef progressObserver=nullptr)
typename conditional< B, T, F >::type conditional_t
static const RepoType NONE
void resetDispose()
Set no dispose function.
bool isTmpRepo(const RepoInfo &info_r)
Whether repo is not under RM control and provides its own methadata paths.
static const RepoType RPMMD
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
static const RepoType YAST2
static void touchIndexFile(const RepoInfo &info, const RepoManagerOptions &options)
AsyncOpRef< expected< zypp::RepoStatus > > repoStatus(repo::AsyncDownloadContextRef dl, ProvideMediaHandle mediaHandle)
Base class for Exception.
void assert_urls(const RepoInfo &info)
Date timestamp() const
The time the data were changed the last time.
Exception for repository handling.
static Date now()
Return the current time.
#define PL_(MSG1, MSG2, N)
AsyncOpRef< expected< zypp::repo::RepoType > > probeRepoType(ContextRef ctx, ProvideMediaHandle medium, zypp::Pathname path, std::optional< zypp::Pathname > targetPath={})
Wrapper class for ::stat/::lstat.
static const RepoType RPMPLAINDIR
Track changing files or directories.
static RepoStatus metadataStatus(const RepoInfo &info, const RepoManagerOptions &options)
Repository type enumeration.