57 auto maybeCopyResultToDest ( std::string &&subPath ) {
60 MIL <<
"Target path is set, copying " << file.file() <<
" to " << *_targetPath/subPath << std::endl;
61 return std::move(file)
72 : _zyppContext(std::move(zyppCtx))
73 , _medium(std::move(medium))
74 , _path(std::move(path))
75 , _targetPath(std::move(targetPath))
78 MaybeAwaitable<expected<zypp::repo::RepoType>> execute( ) {
79 const auto &
url = _medium.baseUrl();
80 MIL <<
"going to probe the repo type at " <<
url <<
" (" << _path <<
")" << std::endl;
84 MIL <<
"Probed type NONE (not exists) at " <<
url <<
" (" << _path <<
")" << std::endl;
94 std::shared_ptr<Provide> providerRef = _zyppContext->provider();
99 return providerRef->attachMediaIfNeeded( _medium )
100 |
and_then([
this, providerRef]( MediaHandle medium )
103 return providerRef->provide( medium, _path/
"repodata/repomd.xml",
ProvideFileSpec().setCheckExistsOnly( !_targetPath.has_value() ).
setMirrorsAllowed(
false) )
104 |
and_then( maybeCopyResultToDest(
"repodata/repomd.xml") )
106 MIL <<
"Probed type RPMMD at " << medium.baseUrl() <<
" (" << _path <<
")" << std::endl;
110 |
or_else( [
this, providerRef, medium]( std::exception_ptr err ) {
112 std::rethrow_exception (err);
117 DBG <<
"problem checking for repodata/repomd.xml file" << std::endl;
118 _error.remember ( err );
119 _gotMediaError =
true;
125 |
and_then( maybeCopyResultToDest(
"content") )
127 MIL <<
"Probed type RPMMD at " << medium.baseUrl() <<
" (" << _path <<
")" << std::endl;
132 |
or_else( [
this, medium]( std::exception_ptr err ) {
135 std::rethrow_exception (err);
140 DBG <<
"problem checking for content file" << std::endl;
141 _error.remember ( err );
142 _gotMediaError =
true;
152 const auto &
url = medium.baseUrl();
155 if ( ! (
url.schemeIsDownloading() ||
url.schemeIsPlugin() ) ) {
159 MIL <<
"Probed type RPMPLAINDIR at " <<
url <<
" (" << _path <<
")" << std::endl;
167 MIL <<
"Probed type NONE at " <<
url <<
" (" << _path <<
")" << std::endl;
175 ContextRef _zyppContext;
178 std::optional<zypp::Pathname> _targetPath;
181 bool _gotMediaError =
false;
184 auto probeRepoLogic( ContextRef ctx,
RepoInfo repo, std::optional<zypp::Pathname> targetPath)
188 |
and_then( [ctx, path =
repo.path() ](
auto &&mediaHandle ) {
189 return probeRepoType( ctx, std::forward<decltype(mediaHandle)>(mediaHandle), path );
197 ProbeRepoLogic impl( std::move(ctx), std::move(medium), std::move(path), std::move(targetPath) );
198 zypp_co_return zypp_co_await(impl.execute());
201 MaybeAwaitable<expected<zypp::repo::RepoType> >
probeRepoType( ContextRef ctx,
RepoInfo repo, std::optional<zypp::Pathname> targetPath )
203 if constexpr ( ZYPP_IS_ASYNC )
204 return probeRepoLogic( std::move(ctx), std::move(
repo), std::move(targetPath) );
206 return probeRepoLogic( std::move(ctx), std::move(
repo), std::move(targetPath) );
211 auto readRepoFileLogic( ContextRef ctx,
zypp::Url repoFileUrl )
215 |
and_then([repoFileUrl](
auto local ){
216 DBG <<
"reading repo file " << repoFileUrl <<
", local path: " << local.file() << std::endl;
224 return readRepoFileLogic( std::move(ctx), std::move(repoFileUrl) );
229 struct CheckIfToRefreshMetadataLogic {
235 CheckIfToRefreshMetadataLogic( repo::RefreshContextRef refCtx,
LazyMediaHandle &&medium, ProgressObserverRef progressObserver )
236 : _refreshContext(
std::move(refCtx))
237 , _progress(
std::move( progressObserver ))
238 , _medium(
std::move( medium ))
241 MaybeAwaitable<expected<repo::RefreshCheckStatus>> execute( ) {
243 MIL <<
"Going to CheckIfToRefreshMetadata" << std::endl;
248 const auto &info = _refreshContext->repoInfo();
249 MIL <<
"Check if to refresh repo " << _refreshContext->repoInfo().alias() <<
" at " << _medium.baseUrl() <<
" (" << info.type() <<
")" << std::endl;
254 |
and_then( [
this](zypp::RepoStatus oldstatus) {
256 const auto &info = _refreshContext->repoInfo();
258 if ( oldstatus.
empty() ) {
259 MIL <<
"No cached metadata, going to refresh" << std::endl;
263 if ( _medium.baseUrl().schemeIsVolatile() ) {
264 MIL <<
"Never refresh CD/DVD" << std::endl;
269 MIL <<
"Forced refresh!" << std::endl;
273 if ( _medium.baseUrl().schemeIsLocal() ) {
286 if ( oldstatus == *cachestatus ) {
289 const auto refDelay = _refreshContext->zyppContext()->config().repo_refresh_delay();
290 if ( diff < refDelay ) {
292 WAR <<
"Repository '" << info.alias() <<
"' was refreshed in the future!" << std::endl;
295 MIL <<
"Repository '" << info.alias()
296 <<
"' has been refreshed less than repo.refresh.delay ("
298 <<
") minutes ago. Advising to skip refresh" << std::endl;
304 MIL <<
"Metadata and solv cache don't match. Check data on server..." << std::endl;
308 return info.type() | [
this]( zypp::repo::RepoType repokind ) {
311 return probeRepoType( _refreshContext->zyppContext(), _medium, _refreshContext->repoInfo().path() );
313 } |
and_then([
this, oldstatus]( zypp::repo::RepoType repokind ) {
316 _refreshContext->repoInfo().setProbedType( repokind );
318 auto dlContext = std::make_shared<repo::DownloadContext>( _refreshContext->zyppContext(), _refreshContext->repoInfo(), _refreshContext->targetDir() );
320 |
and_then( [
this, dlContext, oldstatus]( zypp::RepoStatus newstatus ){
322 if ( oldstatus == newstatus ) {
323 MIL <<
"repo has not changed" << std::endl;
328 MIL <<
"repo has changed, going to refresh" << std::endl;
329 MIL <<
"Old status: " << oldstatus <<
" New Status: " << newstatus << std::endl;
338 repo::RefreshContextRef _refreshContext;
339 ProgressObserverRef _progress;
340 LazyMediaHandle _medium;
346 CheckIfToRefreshMetadataLogic impl( std::move(refCtx), std::move(medium), std::move(progressObserver) );
347 zypp_co_return zypp_co_await(impl.execute());
353 struct RefreshMetadataLogic {
361 using DlContextRefType = std::shared_ptr<DlContextType>;
363 RefreshMetadataLogic( repo::RefreshContextRef refCtx,
LazyMediaHandle &&medium, ProgressObserverRef progressObserver )
364 : _refreshContext(
std::move(refCtx))
365 , _progress (
std::move( progressObserver ) )
366 , _medium (
std::move( medium ) )
369 MaybeAwaitable<expected<repo::RefreshContextRef>> execute() {
376 MIL <<
"RefreshCheckStatus returned: " << status << std::endl;
384 if (
zypp::IamNotRoot() && not zypp::PathInfo(_refreshContext->rawCachePath().dirname()).userMayWX() ) {
385 WAR <<
"No permision to write cache " << zypp::PathInfo(_refreshContext->rawCachePath().dirname()) << std::endl;
386 auto exception =
ZYPP_EXCPT_PTR( zypp::repo::RepoNoPermissionException( _refreshContext->repoInfo() ) );
390 MIL <<
"Going to refresh metadata from " << _medium.baseUrl() << std::endl;
395 return probeRepoType ( _refreshContext->zyppContext(), _medium, _refreshContext->repoInfo().path() )
396 |
and_then([
this]( zypp::repo::RepoType repokind ) {
398 auto &info = _refreshContext->repoInfo();
400 if ( info.type() != repokind ) {
401 _refreshContext->setProbedType( repokind );
403 info.setProbedType( repokind );
410 const zypp::Pathname &mediarootpath = _refreshContext->rawCachePath();
416 auto dlContext = std::make_shared<DlContextType>( _refreshContext->zyppContext(), _refreshContext->repoInfo(), _refreshContext->targetDir() );
417 dlContext->setPluginRepoverification( _refreshContext->pluginRepoverification() );
422 |
and_then([
this]( DlContextRefType && ) {
426 _refreshContext->saveToRawCache();
436 repo::RefreshContextRef _refreshContext;
437 ProgressObserverRef _progress;
438 LazyMediaHandle _medium;
439 zypp::Pathname _mediarootpath;
446 RefreshMetadataLogic impl( std::move(refCtx), std::move(medium), std::move(progressObserver));
447 zypp_co_return zypp_co_await(impl.execute());
451 auto refreshMetadataLogic( repo::RefreshContextRef refCtx, ProgressObserverRef progressObserver)
459 : rexception { info_r,
_(
"Failed to retrieve new repository metadata.") }
463 if ( rexception.historyEmpty() ) {
464 rexception.remember( old_r );
469 zypp::repo::RepoException rexception;
472 auto helper = std::make_shared<ExHelper>( ExHelper{ refCtx->repoInfo() } );
475 auto refreshPipeline = [ refCtx, progressObserver ]( zypp::MirroredOrigin origin ){
476 return refCtx->zyppContext()->provider()->prepareMedia( origin, zyppng::ProvideMediaSpec() )
477 |
and_then( [ refCtx , progressObserver](
auto mediaHandle )
mutable {
return refreshMetadata ( std::move(refCtx), std::move(mediaHandle), progressObserver ); } );
481 auto predicate = [ info = refCtx->repoInfo(), helper ](
const expected<repo::RefreshContextRef> &res ) ->
bool{
485 }
catch (
const zypp::repo::RepoNoPermissionException &e ) {
487 ERR <<
"Giving up..." << std::endl;
488 helper->remember( e );
490 }
catch (
const zypp::Exception &e ) {
491 ERR <<
"Trying another url..." << std::endl;
492 helper->remember( e );
501 return refCtx->repoInfo().repoOrigins()
503 | [helper]( expected<repo::RefreshContextRef> result ) {
506 ERR <<
"No more urls..." << std::endl;
515 MaybeAwaitable<expected<repo::RefreshContextRef> >
refreshMetadata( repo::RefreshContextRef refCtx, ProgressObserverRef progressObserver) {
516 return refreshMetadataLogic ( std::move(refCtx), std::move(progressObserver) );
522#ifdef ZYPP_ENABLE_ASYNC
530 , _args(
std::move(args)) { }
532 bool await_ready() const noexcept {
return false; }
534 expected<void> await_resume() {
539 void await_suspend( std::coroutine_handle<> cont )
541 MIL <<
"Starting repo2solv for repo " << _repo.alias () << std::endl;
542 _cont = std::move(cont);
543 _proc = Process::create();
544 _proc->connect( &Process::sigFinished, *me, &Repo2SolvOp::procFinished );
545 _proc->connect( &Process::sigReadyRead, *me, &Repo2SolvOp::readyRead );
547 std::vector<const char *> argsIn;
548 argsIn.reserve ( args.size() );
549 std::for_each( args.begin (), args.end(), [&](
const std::string &s ) { argsIn.push_back(s.data()); });
550 argsIn.push_back (
nullptr);
551 me->_proc->setOutputChannelMode ( Process::Merged );
552 if (!me->_proc->start( argsIn.data() )) {
553 setReady( expected<void>::error(
ZYPP_EXCPT_PTR(zypp::repo::RepoException ( me->_repo,
_(
"Failed to cache repo ( unable to start repo2solv ).") ))) );
558 const ByteArray &data = _proc->readLine();
559 const std::string &line = data.
asString();
564 void procFinished(
int ret ) {
566 while ( _proc->canReadLine() )
570 zypp::repo::RepoException ex( _repo,
zypp::str::form(
_(
"Failed to cache repo (%d)."), ret ));
571 ex.addHistory( zypp::str::Str() << _proc->executedCommand() << std::endl << _errdetail << _proc->execError() );
575 setReady( expected<void>::success() );
578 void setReady( expected<void> &&val ) {
579 _result = std::move(val);
585 zypp::RepoInfo _repo;
587 std::string _errdetail;
588 std::coroutine_handle<> _cont;
589 std::optional<expected<void>> _result;
593 MIL <<
"Starting repo2solv for repo " << repo.
alias () << std::endl;
594 co_return co_await Repo2SolvOp{ std::move(repo), std::move(args) };
599 std::string errdetail;
601 for ( std::string output( prog.receiveLine() ); output.length(); output = prog.receiveLine() ) {
602 WAR <<
" " << output;
606 int ret = prog.close();
609 zypp::repo::RepoException ex(repo,
zypp::str::form(
_(
"Failed to cache repo (%d)."), ret ));
610 ex.addHistory( zypp::str::Str() << prog.command() << std::endl << errdetail << prog.execError() );
617 struct BuildCacheLogic {
620 : _refCtx( std::move(refCtx) )
622 , _progressObserver( std::move(progressObserver) )
625 MaybeAwaitable<expected<repo::RefreshContextRef>> execute() {
636 const auto &options = _refCtx->repoManagerOptions();
647 if ( raw_metadata_status.
empty() )
653 zypp::Pathname mediarootParent { _mediarootpath.dirname() };
656 && (
zypp::IamRoot() || zypp::PathInfo(mediarootParent).userMayWX() ) ) {
663 WAR <<
"No permission to write raw cache " << mediarootParent << std::endl;
664 auto exception =
ZYPP_EXCPT_PTR( zypp::repo::RepoNoPermissionException( _refCtx->repoInfo() ) );
672 bool needs_cleaning =
false;
673 const auto &info = _refCtx->repoInfo();
674 if ( _refCtx->repoManager()->isCached( info ) )
676 MIL << info.alias() <<
" is already cached." << std::endl;
681 if ( *cache_status == raw_metadata_status )
683 MIL << info.alias() <<
" cache is up to date with metadata." << std::endl;
687 return makeReadyTask(
689 |
and_then([]( zypp::Pathname base ){
690 if ( ! zypp::PathInfo(base/
"solv.idx").isExist() )
697 MIL << info.alias() <<
" cache rebuild is forced" << std::endl;
701 needs_cleaning =
true;
708 auto r = _refCtx->repoManager()->cleanCache(info);
713 MIL << info.alias() <<
" building cache..." << info.type() << std::endl;
727 zypp::Exception ex(
zypp::str::form(
_(
"Can't create cache at %s - no writing permissions."), base->c_str()) );
731 zypp::Pathname solvfile = *base /
"solv";
734 zypp::repo::RepoType repokind = info.type();
737 switch ( repokind.
toEnum() )
747 MIL <<
"repo type is " << repokind << std::endl;
749 return mountIfRequired( repokind, info )
750 |
and_then([
this, repokind, solvfile = std::move(solvfile) ]( std::optional<ProvideMediaHandle> forPlainDirs )
mutable {
752 const auto &info = _refCtx->repoInfo();
754 switch ( repokind.
toEnum() )
764#ifdef ZYPP_REPO2SOLV_PATH
765 cmd.push_back( ZYPP_REPO2SOLV_PATH );
767 cmd.push_back( zypp::PathInfo(
"/usr/bin/repo2solv" ).isFile() ?
"repo2solv" :
"repo2solv.sh" );
770 cmd.push_back(
"-o" );
771 cmd.push_back( solvfile.
asString() );
772 cmd.push_back(
"-X" );
778 cmd.push_back(
"-R" );
780 std::optional<zypp::Pathname> localPath = forPlainDirs.has_value() ? forPlainDirs->localPath() : zypp::Pathname();
785 cmd.push_back( (*localPath / info.path().absolutename()).c_str() );
788 cmd.push_back( _productdatapath.asString() );
790 return repo2Solv( info, std::move(cmd) )
791 |
and_then( [guard = std::move(guard), solvfile = std::move(solvfile) ]()
mutable {
793 guard.resetDispose();
803 |
and_then([
this, raw_metadata_status](){
805 return _refCtx->repoManager()->setCacheStatus( _refCtx->repoInfo(), raw_metadata_status );
809 MIL <<
"Commit cache.." << std::endl;
814 |
or_else ( [
this]( std::exception_ptr e ) {
821 MaybeAwaitable<expected<std::optional<ProvideMediaHandle>>> mountIfRequired ( zypp::repo::RepoType repokind, zypp::RepoInfo info ) {
825 return _refCtx->zyppContext()->provider()->attachMedia( info.
url(), ProvideMediaSpec() )
826 |
and_then( []( ProvideMediaHandle handle ) {
827 return makeReadyTask(
make_expected_success( std::optional<ProvideMediaHandle>( std::move(handle)) ));
832 repo::RefreshContextRef _refCtx;
834 ProgressObserverRef _progressObserver;
836 zypp::Pathname _mediarootpath;
837 zypp::Pathname _productdatapath;
843 BuildCacheLogic impl( std::move(refCtx), policy, std::move(progressObserver));
844 zypp_co_return zypp_co_await ( impl.execute () );
851 struct AddRepoLogic {
853 AddRepoLogic( RepoManagerRef &&repoMgrRef,
RepoInfo &&info, ProgressObserverRef &&myProgress,
const zypp::TriBool & forcedProbe )
854 : _repoMgrRef(
std::move(repoMgrRef) )
855 , _doProbeUrl(
zypp::indeterminate(forcedProbe) ? _repoMgrRef->options().probe :
bool(forcedProbe) )
856 , _info(
std::move(info) )
857 , _myProgress (
std::move(myProgress) )
860 MaybeAwaitable<expected<RepoInfo> > execute() {
866 MIL <<
"Try adding repo " << _info << std::endl;
870 if ( _repoMgrRef->repos().find(_info) != _repoMgrRef->repos().end() )
876 DBG <<
"unknown repository type, probing" << std::endl;
879 |
and_then([
this]( zypp::repo::RepoType probedtype ) {
892 |
and_then( [
this](
RepoInfo tosave ){
return _repoMgrRef->addProbedRepository( tosave, tosave.
type() ); })
895 MIL <<
"done" << std::endl;
898 |
or_else( [
this]( std::exception_ptr e) {
900 MIL <<
"done" << std::endl;
906 RepoManagerRef _repoMgrRef;
909 ProgressObserverRef _myProgress;
915 AddRepoLogic impl( std::move(mgr), std::move(info), std::move(myProgress), forcedProbe );
916 zypp_co_return zypp_co_await ( impl.execute () );
921 struct AddReposLogic {
922 AddReposLogic( RepoManagerRef &&repoMgrRef,
zypp::Url &&
url, ProgressObserverRef &&myProgress )
923 : _repoMgrRef(
std::move(repoMgrRef) )
925 , _myProgress (
std::move(myProgress) )
928 MaybeAwaitable<expected<void>> execute() {
933 |
and_then([
this]( std::list<RepoInfo> repos ) {
935 for ( std::list<RepoInfo>::const_iterator it = repos.begin();
940 for_ ( kit, _repoMgrRef->repoBegin(), _repoMgrRef->repoEnd() )
942 if ( (*it).alias() == (*kit).alias() )
944 ERR <<
"To be added repo " << (*it).alias() <<
" conflicts with existing repo " << (*kit).alias() << std::endl;
950 std::string filename = zypp::Pathname(_url.getPathName()).basename();
951 if ( filename == zypp::Pathname() )
957 const auto &options = _repoMgrRef->options();
962 zypp::Pathname repofile = _repoMgrRef->generateNonExistingName( options.knownReposPath, filename );
964 MIL <<
"Saving " << repos.size() <<
" repo" << ( repos.size() ?
"s" :
"" ) <<
" in " << repofile << std::endl;
966 std::ofstream file(repofile.
c_str());
973 for ( std::list<RepoInfo>::iterator it = repos.begin();
977 MIL <<
"Saving " << (*it).alias() << std::endl;
985 it->dumpAsIniOn(file);
986 it->setFilepath(repofile);
987 it->setMetadataPath( *rawCachePath );
988 it->setPackagesPath( *pckCachePath );
989 _repoMgrRef->reposManip().insert(*it);
991 zypp::HistoryLog( _repoMgrRef->options().rootDir).addRepository(*it);
994 MIL <<
"done" << std::endl;
1000 RepoManagerRef _repoMgrRef;
1002 ProgressObserverRef _myProgress;
1009 AddReposLogic impl( std::move(mgr), std::move(
url), std::move(myProgress) );
1010 zypp_co_return zypp_co_await ( impl.execute () );
1016 struct RefreshGeoIpLogic {
1023 : _zyppCtx(
std::move(zyppCtx) )
1024 , _origins(
std::move(origins) )
1027 MaybeAwaitable<expected<void>> execute() {
1031 if ( !_zyppCtx->config().geoipEnabled() ) {
1032 MIL <<
"GeoIp disabled via ZConfig, not refreshing the GeoIP information." << std::endl;
1036 std::vector<std::string> hosts;
1037 for (
const zypp::MirroredOrigin &origin : _origins ){
1038 if ( !origin.schemeIsDownloading () )
1041 for (
const auto &originEndpoint : origin ) {
1042 const auto &host = originEndpoint.url().getHost();
1043 if (
zypp::any_of( _zyppCtx->config().geoipHostnames(), [&host](
const auto &elem ){ return ( zypp::str::compareCI( host, elem ) == 0 ); } ) ) {
1044 hosts.push_back( host );
1050 if ( hosts.empty() ) {
1051 MIL <<
"No configured geoip URL found, not updating geoip data" << std::endl;
1055 _geoIPCache = _zyppCtx->config().geoipCachePath();
1058 MIL <<
"Unable to create cache directory for GeoIP." << std::endl;
1062 if (
zypp::IamNotRoot() && not zypp::PathInfo(_geoIPCache).userMayRWX() ) {
1063 MIL <<
"No access rights for the GeoIP cache directory." << std::endl;
1072 zypp::PathInfo pi( dir/entry.
name );
1073 auto age = std::chrono::system_clock::now() - std::chrono::system_clock::from_time_t( pi.mtime() );
1074 if ( age < std::chrono::hours(24) )
1077 MIL <<
"Removing GeoIP file for " << entry.
name <<
" since it's older than 24hrs." << std::endl;
1082 auto firstOfCb = [
this]( std::string hostname ) {
1085 if ( zypp::PathInfo( _geoIPCache / hostname ).isExist() ) {
1086 MIL <<
"Skipping GeoIP request for " << hostname <<
" since a valid cache entry exists." << std::endl;
1087 return makeReadyTask(
false);
1090 MIL <<
"Query GeoIP for " << hostname << std::endl;
1097 }
catch(
const zypp::Exception &e ) {
1099 MIL <<
"Ignoring invalid GeoIP hostname: " << hostname << std::endl;
1100 return makeReadyTask(
false);
1104 return _zyppCtx->provider()->attachMedia( url, ProvideMediaSpec() )
1105 |
and_then( [
this]( MediaHandle provideHdl ) {
return _zyppCtx->provider()->provide( provideHdl,
"/geoip", ProvideFileSpec() ); })
1106 |
inspect_err( [hostname](
const std::exception_ptr& ){
MIL <<
"Failed to query GeoIP from hostname: " << hostname << std::endl; } )
1107 |
and_then( [hostname,
this]( ProvideRes provideRes ) {
1111 constexpr auto writeHostToFile = [](
const zypp::Pathname &fName,
const std::string &host ){
1113 out.open( fName.
asString(), std::ios_base::trunc );
1114 if ( out.is_open() ) {
1115 out << host << std::endl;
1117 MIL <<
"Failed to create/open GeoIP cache file " << fName << std::endl;
1121 std::string geoipMirror;
1123 zypp::xml::Reader reader( provideRes.
file() );
1124 if ( reader.seekToNode( 1,
"host" ) ) {
1125 const auto &str = reader.nodeText().asString();
1133 MIL <<
"Storing geoIP redirection: " << hostname <<
" -> " << str << std::endl;
1138 MIL <<
"No host entry or empty file returned for GeoIP, remembering for 24hrs" << std::endl;
1140 }
catch (
const zypp::Exception &e ) {
1142 MIL <<
"Empty or invalid GeoIP file, not requesting again for 24hrs" << std::endl;
1145 writeHostToFile( _geoIPCache / hostname, geoipMirror );
1148 | []( expected<void> res ) {
return res.
is_valid(); };
1151 return std::move(hosts)
1152 |
firstOf( std::move(firstOfCb),
false, zyppng::detail::ContinueUntilValidPredicate() )
1153 | [](
bool foundGeoIP ) {
1156 MIL <<
"Successfully queried GeoIP data." << std::endl;
1160 MIL <<
"Failed to query GeoIP data." << std::endl;
1161 return expected<void>::error( std::make_exception_ptr( zypp::Exception(
"No valid geoIP url found" )) );
1167 ContextRef _zyppCtx;
1168 zypp::MirroredOriginSet _origins;
1169 zypp::Pathname _geoIPCache;
1177 zypp_co_return zypp_co_await ( impl.execute () );
1182 RefreshGeoIpLogic impl( std::move(ctx), std::move(origins) );
1183 zypp_co_return zypp_co_await ( impl.execute () );