15 #include <zypp-core/ng/pipelines/MTry> 16 #include <zypp-core/ng/io/Process> 24 #include <zypp/ng/Context> 28 #undef ZYPP_BASE_LOGGER_LOGGROUP 29 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::repomanager" 40 const auto &scheme = serviceUrl.
getScheme();
41 if ( !root.
empty() && (scheme ==
"dir" || scheme ==
"file") ) {
47 struct FetchRIMServiceLogic
50 FetchRIMServiceLogic( ContextRef &&ctx,
zypp::Pathname &&root_r,
ServiceInfo &&service, ProgressObserverRef &&myProgress )
51 :
_ctx( std::move(ctx) )
58 MaybeAwaitable<expected< std::pair<zypp::ServiceInfo, RepoInfoList> >> execute() {
66 return adaptServiceUrlToChroot( serviceUrl,
_root_r );
69 |
and_then( [
this](
auto mediaHandle ) {
return _ctx->provider()->provide( mediaHandle,
"repo/repoindex.xml",
ProvideFileSpec() ); } )
70 |
and_then( [
this](
auto provideResult ) {
74 auto callback = [&](
const zypp::RepoInfo &r) { repos.push_back(r);
return true; };
77 _service.setProbedTtl( reader.ttl() );
99 struct FetchPluginServiceLogic
102 using Ret = expected<std::pair<zypp::ServiceInfo, RepoInfoList>>;
104 FetchPluginServiceLogic( ContextRef &&ctx,
zypp::Pathname &&root_r,
ServiceInfo &&service, ProgressObserverRef &&myProgress )
105 :
_ctx( std::move(ctx) )
112 MaybeAwaitable<Ret> execute() {
120 return runPlugin( std::move(stripped) )
121 |
and_then( [
this](
int exitCode ) {
123 if ( exitCode != 0 ) {
126 ERR <<
"Capture plugin error:[" << std::endl <<
_stderrBuf << std::endl <<
']' << std::endl;
132 auto callback = [&](
const zypp::RepoInfo &r) { repos.push_back(r);
return true; };
139 return Ret::error( std::current_exception () );
145 #ifdef ZYPP_ENABLE_ASYNC 146 AsyncOpRef<expected<int>> runPlugin( std::string command ) {
149 const char *args[] = {
157 pluginProcess->setChroot (
_root_r );
160 if ( !pluginProcess->start( args ) || !pluginProcess->isRunning () ) {
161 return makeReadyTask ( finalize( std::move(pluginProcess) ) );
164 co_return co_await ( std::move(pluginProcess)
166 | [
this]( ProcessRef proc ) {
return finalize( std::move(proc) ); } );
169 expected<int> finalize( ProcessRef proc ) {
170 if ( proc->isRunning () ) {
171 proc->stop ( SIGKILL );
176 if ( proc->exitStatus() != 0 ) {
183 expected<int> runPlugin( std::string command ) {
185 std::stringstream buffer;
189 args.push_back(
"/bin/sh" );
190 args.push_back(
"-c" );
191 args.push_back( command );
197 int retCode = prog.close();
198 if ( retCode != 0 ) {
222 if ( service.
type() == zypp::repo::ServiceType::PLUGIN ) {
223 FetchPluginServiceLogic impl( std::move(ctx), std::move(root_r), std::move(service), std::move(myProgress) );
224 zypp_co_return zypp_co_await( impl.execute() );
226 FetchRIMServiceLogic impl( std::move(ctx), std::move(root_r), std::move(service), std::move(myProgress) );
227 zypp_co_return zypp_co_await( impl.execute() );
237 |
and_then( [ctx]( MediaHandle medium ) {
return ctx->provider()->provide( medium,
"/repo/repoindex.xml",
ProvideFileSpec().setCheckExistsOnly()); } )
243 std::rethrow_exception( result.
error() );
263 enew.
remember( std::current_exception() );
273 struct RefreshServiceLogic
284 MaybeAwaitable<expected<void>> probeServiceIfNeeded() {
286 if (
_service.type() == zypp::repo::ServiceType::NONE ) {
299 MaybeAwaitable<Ret> execute() {
321 MIL <<
"Skip: '" <<
_service.alias() <<
"' metadata valid until " << lrf << std::endl;
322 return makeReadyTask( Ret::success() );
326 WAR <<
"Force: '" <<
_service.alias() <<
"' metadata last refresh in the future: " << lrf << std::endl;
332 return probeServiceIfNeeded ()
342 | [
this]( expected<std::pair<zypp::ServiceInfo, RepoInfoList>> serviceReposExp ) {
344 if ( !serviceReposExp ) {
346 std::rethrow_exception( serviceReposExp.error() );
357 std::pair<zypp::ServiceInfo, RepoInfoList> serviceRepos = serviceReposExp.is_valid() ? std::move( serviceReposExp.get() ) : std::make_pair(
_service,
RepoInfoList{} );
360 std::string servicesTargetDistro =
_repoMgr->options().servicesTargetDistro;
361 if ( servicesTargetDistro.empty() ) {
364 DBG <<
"ServicesTargetDistro: " << servicesTargetDistro << std::endl;
367 RepoCollector
collector( servicesTargetDistro );
368 std::for_each( serviceRepos.second.begin(), serviceRepos.second.end(), [&](
const auto &r ){
collector.collect(r); } );
370 if (
_service.ttl () != serviceRepos.first.ttl () ) {
372 if ( !serviceRepos.first.ttl() )
395 newRepoStates[it->alias()] = *it;
403 if ( !it->path().empty() )
405 if ( it->path() !=
"/" )
410 if ( it->baseUrlsEmpty() )
415 it->setBaseUrl( std::move(url) );
417 else if ( !path.
empty() )
422 url.setPathName( url.getPathName() / path );
424 it->setBaseUrls( std::move(urls) );
432 _repoMgr->getRepositoriesInService(
_service.alias(), std::back_inserter( oldRepos ) );
436 for_( oldRepo, oldRepos.begin(), oldRepos.end() )
440 if ( oldRepo->enabled() )
443 const auto & last =
_service.repoStates().find( oldRepo->alias() );
444 if ( last !=
_service.repoStates().end() && ! last->second.enabled )
446 DBG <<
"Service removes user enabled repo " << oldRepo->alias() << std::endl;
447 _service.addRepoToEnable( oldRepo->alias() );
451 DBG <<
"Service removes enabled repo " << oldRepo->alias() << std::endl;
454 DBG <<
"Service removes disabled repo " << oldRepo->alias() << std::endl;
456 auto remRes =
_repoMgr->removeRepository( *oldRepo );
457 if ( !remRes )
return Ret::error( remRes.error() );
472 DBG <<
"Service request to " << (it->enabled()?
"enable":
"disable") <<
" service repo " << it->alias() << std::endl;
476 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() << std::endl;
481 _service.delRepoToEnable( it->alias() );
486 if (
_service.repoToEnableFind( it->alias() ) )
488 DBG <<
"User request to enable service repo " << it->alias() << std::endl;
493 _service.delRepoToEnable( it->alias() );
496 else if (
_service.repoToDisableFind( it->alias() ) )
498 DBG <<
"User request to disable service repo " << it->alias() << std::endl;
503 RepoInfoList::iterator oldRepo(
findAlias( it->alias(), oldRepos ) );
504 if ( oldRepo == oldRepos.end() )
509 if ( ! indeterminate(toBeEnabled) )
510 it->setEnabled( (
bool ) toBeEnabled );
512 DBG <<
"Service adds repo " << it->alias() <<
" " << (it->enabled()?
"enabled":
"disabled") << std::endl;
513 const auto &addRes =
_repoMgr->addRepository( *it );
514 if (!addRes)
return Ret::error( addRes.error() );
519 bool oldRepoModified =
false;
521 if ( indeterminate(toBeEnabled) )
525 if ( oldRepo->enabled() == it->enabled() )
526 toBeEnabled = it->enabled();
529 toBeEnabled = it->enabled();
530 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() <<
" forces " << (toBeEnabled?
"enabled":
"disabled") << std::endl;
534 const auto & last =
_service.repoStates().find( oldRepo->alias() );
535 if ( last ==
_service.repoStates().end() || last->second.enabled != it->enabled() )
536 toBeEnabled = it->enabled();
539 toBeEnabled = oldRepo->enabled();
540 DBG <<
"User modified service repo " << it->alias() <<
" may stay " << (toBeEnabled?
"enabled":
"disabled") << std::endl;
546 if ( toBeEnabled == oldRepo->enabled() )
548 DBG <<
"Service repo " << it->alias() <<
" stays " << (oldRepo->enabled()?
"enabled":
"disabled") << std::endl;
550 else if ( toBeEnabled )
552 DBG <<
"Service repo " << it->alias() <<
" gets enabled" << std::endl;
553 oldRepo->setEnabled(
true );
554 oldRepoModified =
true;
558 DBG <<
"Service repo " << it->alias() <<
" gets disabled" << std::endl;
559 oldRepo->setEnabled(
false );
560 oldRepoModified =
true;
566 if ( oldRepo->rawName() != it->rawName() )
568 DBG <<
"Service repo " << it->alias() <<
" gets new NAME " << it->rawName() << std::endl;
569 oldRepo->setName( it->rawName() );
570 oldRepoModified =
true;
574 if ( oldRepo->autorefresh() != it->autorefresh() )
576 DBG <<
"Service repo " << it->alias() <<
" gets new AUTOREFRESH " << it->autorefresh() << std::endl;
577 oldRepo->setAutorefresh( it->autorefresh() );
578 oldRepoModified =
true;
582 if ( oldRepo->priority() != it->priority() )
584 DBG <<
"Service repo " << it->alias() <<
" gets new PRIORITY " << it->priority() << std::endl;
585 oldRepo->setPriority( it->priority() );
586 oldRepoModified =
true;
592 urlCredentialExtractor.extract( newUrls );
593 if ( oldRepo->rawBaseUrls() != newUrls )
595 DBG <<
"Service repo " << it->alias() <<
" gets new URLs " << newUrls << std::endl;
596 oldRepo->setBaseUrls( std::move(newUrls) );
597 oldRepoModified =
true;
603 if (
_service.type() == zypp::repo::ServiceType::PLUGIN )
607 oldRepo->getRawGpgChecks( ogpg[0], ogpg[1], ogpg[2] );
608 it-> getRawGpgChecks( ngpg[0], ngpg[1], ngpg[2] );
609 #define Z_CHKGPG(I,N) \ 610 if ( ! sameTriboolState( ogpg[I], ngpg[I] ) ) \ 612 DBG << "Service repo " << it->alias() << " gets new "#N"Check " << ngpg[I] << std::endl; \ 613 oldRepo->set##N##Check( ngpg[I] ); \ 614 oldRepoModified = true; \ 623 if ( oldRepo->rawGpgKeyUrls() != it->rawGpgKeyUrls() )
625 DBG <<
"Service repo " << it->alias() <<
" gets new GPGKEY url " << it->rawGpgKeyUrls() << std::endl;
626 oldRepo->setGpgKeyUrls( it->rawGpgKeyUrls() );
627 oldRepoModified =
true;
631 if ( oldRepo->rawCfgMirrorlistUrl() != it->rawCfgMirrorlistUrl() )
633 DBG <<
"Service repo " << it->alias() <<
" gets new MIRRORLIST url " << it->rawCfgMirrorlistUrl() << std::endl;
634 oldRepo->setMirrorlistUrl( it->rawCfgMirrorlistUrl() );
635 oldRepoModified =
true;
639 if ( oldRepo->rawCfgMetalinkUrl() != it->rawCfgMetalinkUrl() )
641 DBG <<
"Service repo " << it->alias() <<
" gets new METALINK url " << it->rawCfgMetalinkUrl() << std::endl;
642 oldRepo->setMetalinkUrl( it->rawCfgMetalinkUrl() );
643 oldRepoModified =
true;
647 if ( oldRepoModified )
649 auto modRes =
_repoMgr->modifyRepository( oldRepo->alias(), *oldRepo );
650 if ( !modRes )
return Ret::error( modRes.error() );
656 if ( !
_service.reposToDisableEmpty() )
663 if (
_service.repoStates() != newRepoStates )
665 _service.setRepoStates( std::move(newRepoStates) );
671 if (
_service.type() != zypp::repo::ServiceType::PLUGIN )
683 if ( !modRes )
return Ret::error( modRes.error() );
688 return Ret::error( std::make_exception_ptr (
_informalError.value()) );
691 return Ret::success( );
715 RefreshServiceLogic impl( std::move(repoMgr), std::move(info), std::move(options) );
716 zypp_co_return zypp_co_await ( impl.execute() );
std::string getScheme() const
Returns the scheme name of the URL.
std::string targetDistribution() const
This is register.target attribute of the installed base product.
Force restoring repo enabled/disabled status.
std::optional< zypp::repo::ServicePluginInformalException > _informalError
void setQueryParam(const std::string ¶m, const std::string &value)
Set or add value for the specified query parameter.
Reads through a repoindex.xml file and collects repositories.
std::string asString(const Patch::Category &obj)
relates: Patch::Category string representation.
SignalProxy< void(int)> sigFinished()
RefreshServiceFlags RefreshServiceOptions
Options tuning RefreshService.
ExternalProgram extended to offer reading programs stderr.
Force refresh even if TTL is not reached.
MaybeAwaitable< expected< void > > refreshService(RepoManagerRef repoMgr, ServiceInfo info, zypp::RepoManagerFlags::RefreshServiceOptions options)
Collector< TOutputIterator > collector(TOutputIterator iter_r)
relates: Collector Convenience constructor.
std::list< RepoInfo > RepoInfoList
relates: RepoInfo
MaybeAwaitable< expected< zypp::repo::ServiceType > > probeServiceType(ContextRef ctx, const zypp::Url &url)
What is known about a repository.
static expected< std::decay_t< Type >, Err > make_expected_success(Type &&t)
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
static expected error(ConsParams &&...params)
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
expected< void > assert_url(const ServiceInfo &info)
Interface of repoindex.xml file reader.
zypp::RepoInfoList RepoInfoList
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
void remember(const Exception &old_r)
Store an other Exception as history.
bool empty() const
Test for an empty path.
void setPathName(const std::string &path, EEncoding eflag=zypp::url::E_DECODED)
Set the path name.
bool foundAliasIn(const std::string &alias_r, Iterator begin_r, Iterator end_r)
Check if alias_r is present in repo/service container.
Store and operate on date (time_t).
std::string asString() const
Returns a default string representation of the Url object.
Service type enumeration.
expected< void > assert_alias(const RepoInfo &info)
Read repository data from a .repo file.
std::vector< std::string > Arguments
static expected success(ConsParams &&...params)
zypp::ServiceInfo ServiceInfo
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
MaybeAwaitable< expected< std::pair< zypp::ServiceInfo, RepoInfoList > > > fetchRepoListfromService(ContextRef ctx, zypp::Pathname root_r, ServiceInfo service, ProgressObserverRef myProgress)
Base class for Exception.
Exception for repository handling.
static Date now()
Return the current time.
std::string getPathName(EEncoding eflag=zypp::url::E_DECODED) const
Returns the path name from the URL.
Iterator findAlias(const std::string &alias_r, Iterator begin_r, Iterator end_r)
Find alias_r in repo/service container.
std::map< std::string, RepoState > RepoStates
ResultType and_then(const expected< T, E > &exp, Function &&f)
auto mtry(F &&f, Args &&...args)
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.
zypp::RepoManagerFlags::RefreshServiceOptions RefreshServiceOptions
static Pathname stripprefix(const Pathname &root_r, const Pathname &path_r)
Return path_r with any root_r dir prefix striped.
repo::ServiceType type() const
Service type.
ProgressObserverRef _myProgress
RepoManager::RefreshServiceOptions _options
const std::string & msg() const
Return the message string provided to the ctor.