42 const auto &scheme = serviceUrl.
getScheme();
43 if ( !root.
empty() && (scheme ==
"dir" || scheme ==
"file") ) {
49 template <
class Executor,
class OpType>
50 struct FetchRIMServiceLogic :
public LogicBase<Executor, OpType>
57 using RepoMgrRefType = RepoManagerRef<ZyppContextRefType>;
59 FetchRIMServiceLogic( ZyppContextRefType &&ctx,
zypp::Pathname &&root_r,
ServiceInfo &&service, ProgressObserverRef &&myProgress )
60 : _ctx( std::move(ctx) )
61 , _root_r( std::move(root_r) )
62 , _service( std::move(service) )
63 , _myProgress( std::move(myProgress) )
67 MaybeAsyncRef<expected< std::pair<zypp::ServiceInfo, RepoInfoList> >> execute() {
75 return adaptServiceUrlToChroot( serviceUrl, _root_r );
78 |
and_then( [
this](
auto mediaHandle ) {
return _ctx->provider()->provide( mediaHandle,
"repo/repoindex.xml",
ProvideFileSpec() ); } )
79 |
and_then( [
this](
auto provideResult ) {
82 zypp::RepoInfoList repos;
86 _service.setProbedTtl( reader.
ttl() );
102 ZyppContextRefType _ctx;
105 ProgressObserverRef _myProgress;
109 template <
class Executor,
class OpType>
110 struct FetchPluginServiceLogic :
public LogicBase<Executor, OpType>
117 using RepoMgrRefType = RepoManagerRef<ZyppContextRefType>;
120 FetchPluginServiceLogic( ZyppContextRefType &&ctx,
zypp::Pathname &&root_r,
ServiceInfo &&service, ProgressObserverRef &&myProgress )
121 : _ctx( std::move(ctx) )
122 , _root_r( std::move(root_r) )
123 , _service( std::move(service) )
124 , _myProgress( std::move(myProgress) )
128 MaybeAsyncRef<Ret> execute() {
136 return executor()->runPlugin( std::move(stripped) )
137 |
and_then( [
this](
int exitCode ) {
139 if ( exitCode != 0 ) {
142 ERR <<
"Capture plugin error:[" << std::endl << _stderrBuf << std::endl <<
']' << std::endl;
147 zypp::RepoInfoList repos;
150 std::stringstream buffer( _stdoutBuf );
155 return Ret::error( std::current_exception () );
161 ZyppContextRefType _ctx;
164 ProgressObserverRef _myProgress;
165 std::string _stdoutBuf;
166 std::string _stderrBuf;
170 struct SyncFetchPluginService : FetchPluginServiceLogic<SyncFetchPluginService, SyncOp< expected< std::pair<zypp::ServiceInfo, RepoInfoList> >>>
172 using FetchPluginServiceLogic::FetchPluginServiceLogic;
175 std::stringstream buffer;
179 args.push_back(
"/bin/sh" );
180 args.push_back(
"-c" );
181 args.push_back( command );
185 _stdoutBuf = buffer.str();
187 int retCode = prog.
close();
188 if ( retCode != 0 ) {
200 struct ASyncFetchPluginService : FetchPluginServiceLogic<ASyncFetchPluginService, AsyncOp< expected< std::pair<zypp::ServiceInfo, RepoInfoList> >>>
202 using FetchPluginServiceLogic::FetchPluginServiceLogic;
206 const char *args[] = {
214 pluginProcess->setChroot ( _root_r );
217 if ( !pluginProcess->start( args ) || !pluginProcess->isRunning () ) {
221 return std::move(pluginProcess)
223 | [
this]( ProcessRef proc ) {
return finalize( std::move(proc) ); };
227 if ( proc->isRunning () ) {
228 proc->stop ( SIGKILL );
233 if ( proc->exitStatus() != 0 ) {
246 if ( service.
type() == zypp::repo::ServiceType::PLUGIN )
247 return ASyncFetchPluginService::run( std::move(ctx), std::move(root_r), std::move(service), std::move(myProgress) );
254 if ( service.
type() == zypp::repo::ServiceType::PLUGIN )
255 return SyncFetchPluginService::run( std::move(ctx), std::move(root_r), std::move(service), std::move(myProgress) );
263 template<
typename ContextRefType>
266 constexpr bool isAsync = std::is_same_v<ContextRefType, ContextRef>;
271 |
and_then( [ctx]( MediaHandle medium ) {
return ctx->provider()->provide( medium,
"/repo/repoindex.xml",
ProvideFileSpec().setCheckExistsOnly()); } )
277 std::rethrow_exception( result.
error() );
278 }
catch (
const zypp::media::MediaFileNotFoundException &e ) {
280 }
catch (
const zypp::media::MediaException &e ) {
287 catch (
const zypp::Exception &e ) {
297 enew.remember( std::current_exception() );
308 return probeServiceLogic( std::move(ctx),
url );
313 return probeServiceLogic( std::move(ctx),
url );
317 template <
class Executor,
class OpType>
318 struct RefreshServiceLogic :
public LogicBase<Executor, OpType>
325 using RepoMgrRefType = RepoManagerRef<ZyppContextRefType>;
329 : _repoMgr(
std::move(repoMgr) )
330 , _service(
std::move(info) )
334 MaybeAsyncRef<expected<void>> probeServiceIfNeeded() {
336 if ( _service.type() == zypp::repo::ServiceType::NONE ) {
338 return probeServiceType( _repoMgr->zyppContext(), adaptServiceUrlToChroot( _service.url(), _repoMgr->options().rootDir ) )
340 _service.setProbedType( type );
341 _serviceModified =
true;
349 MaybeAsyncRef<Ret> execute() {
358 MIL <<
"Going to refresh service '" << _service.alias() <<
"', url: " << _service.url() <<
", opts: " << _options << std::endl;
363 zypp::Date lrf = _service.lrf();
369 if ( (lrf+=_service.ttl()) > now )
371 MIL <<
"Skip: '" << _service.alias() <<
"' metadata valid until " << lrf << std::endl;
376 WAR <<
"Force: '" << _service.alias() <<
"' metadata last refresh in the future: " << lrf << std::endl;
382 return probeServiceIfNeeded ()
392 | [
this]( expected<std::pair<zypp::ServiceInfo, RepoInfoList>> serviceReposExp ) {
394 if ( !serviceReposExp ) {
396 std::rethrow_exception( serviceReposExp.error() );
398 }
catch (
const zypp::repo::ServicePluginInformalException & e ) {
407 std::pair<zypp::ServiceInfo, RepoInfoList> serviceRepos = serviceReposExp.is_valid() ? std::move( serviceReposExp.get() ) : std::make_pair( _service,
RepoInfoList{} );
410 std::string servicesTargetDistro = _repoMgr->options().servicesTargetDistro;
411 if ( servicesTargetDistro.empty() ) {
412 servicesTargetDistro = zypp::Target::targetDistribution( zypp::Pathname() );
414 DBG <<
"ServicesTargetDistro: " << servicesTargetDistro << std::endl;
417 RepoCollector
collector( servicesTargetDistro );
418 std::for_each( serviceRepos.second.begin(), serviceRepos.second.end(), [&](
const auto &r ){ collector.collect(r); } );
420 if ( _service.ttl () != serviceRepos.first.ttl () ) {
422 if ( !serviceRepos.first.ttl() )
423 serviceRepos.first.setLrf( zypp::Date() );
425 _serviceModified =
true;
429 _service = serviceRepos.first;
440 it->setAlias(
zypp::str::form(
"%s:%s", _service.alias().c_str(), it->alias().c_str() ) );
442 it->setService( _service.alias() );
445 newRepoStates[it->alias()] = *it;
453 if ( !it->path().empty() )
455 if ( it->path() !=
"/" )
460 if ( it->baseUrlsEmpty() )
462 zypp::Url url( _service.rawUrl() );
465 it->setBaseUrl( std::move(url) );
467 else if ( !path.
empty() )
470 for ( zypp::Url & url : urls )
474 it->setBaseUrls( std::move(urls) );
482 _repoMgr->getRepositoriesInService( _service.alias(), std::back_inserter( oldRepos ) );
486 for_( oldRepo, oldRepos.begin(), oldRepos.end() )
490 if ( oldRepo->enabled() )
493 const auto & last = _service.repoStates().find( oldRepo->alias() );
494 if ( last != _service.repoStates().end() && ! last->second.enabled )
496 DBG <<
"Service removes user enabled repo " << oldRepo->alias() << std::endl;
497 _service.addRepoToEnable( oldRepo->alias() );
498 _serviceModified =
true;
501 DBG <<
"Service removes enabled repo " << oldRepo->alias() << std::endl;
504 DBG <<
"Service removes disabled repo " << oldRepo->alias() << std::endl;
506 auto remRes = _repoMgr->removeRepository( *oldRepo );
507 if ( !remRes )
return Ret::error( remRes.error() );
514 zypp::UrlCredentialExtractor urlCredentialExtractor( _repoMgr->options().rootDir );
522 DBG <<
"Service request to " << (it->enabled()?
"enable":
"disable") <<
" service repo " << it->alias() << std::endl;
526 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() << std::endl;
531 _service.delRepoToEnable( it->alias() );
536 if ( _service.repoToEnableFind( it->alias() ) )
538 DBG <<
"User request to enable service repo " << it->alias() << std::endl;
543 _service.delRepoToEnable( it->alias() );
544 _serviceModified =
true;
546 else if ( _service.repoToDisableFind( it->alias() ) )
548 DBG <<
"User request to disable service repo " << it->alias() << std::endl;
553 RepoInfoList::iterator oldRepo(
findAlias( it->alias(), oldRepos ) );
554 if ( oldRepo == oldRepos.end() )
559 if ( ! indeterminate(toBeEnabled) )
560 it->setEnabled( (
bool ) toBeEnabled );
562 DBG <<
"Service adds repo " << it->alias() <<
" " << (it->enabled()?
"enabled":
"disabled") << std::endl;
563 const auto &addRes = _repoMgr->addRepository( *it );
564 if (!addRes)
return Ret::error( addRes.error() );
569 bool oldRepoModified =
false;
571 if ( indeterminate(toBeEnabled) )
575 if ( oldRepo->enabled() == it->enabled() )
576 toBeEnabled = it->enabled();
579 toBeEnabled = it->enabled();
580 DBG <<
"Opt RefreshService_restoreStatus " << it->alias() <<
" forces " << (toBeEnabled?
"enabled":
"disabled") << std::endl;
584 const auto & last = _service.repoStates().find( oldRepo->alias() );
585 if ( last == _service.repoStates().end() || last->second.enabled != it->enabled() )
586 toBeEnabled = it->enabled();
589 toBeEnabled = oldRepo->enabled();
590 DBG <<
"User modified service repo " << it->alias() <<
" may stay " << (toBeEnabled?
"enabled":
"disabled") << std::endl;
596 if ( toBeEnabled == oldRepo->enabled() )
598 DBG <<
"Service repo " << it->alias() <<
" stays " << (oldRepo->enabled()?
"enabled":
"disabled") << std::endl;
600 else if ( toBeEnabled )
602 DBG <<
"Service repo " << it->alias() <<
" gets enabled" << std::endl;
603 oldRepo->setEnabled(
true );
604 oldRepoModified =
true;
608 DBG <<
"Service repo " << it->alias() <<
" gets disabled" << std::endl;
609 oldRepo->setEnabled(
false );
610 oldRepoModified =
true;
616 if ( oldRepo->rawName() != it->rawName() )
618 DBG <<
"Service repo " << it->alias() <<
" gets new NAME " << it->rawName() << std::endl;
619 oldRepo->setName( it->rawName() );
620 oldRepoModified =
true;
624 if ( oldRepo->autorefresh() != it->autorefresh() )
626 DBG <<
"Service repo " << it->alias() <<
" gets new AUTOREFRESH " << it->autorefresh() << std::endl;
627 oldRepo->setAutorefresh( it->autorefresh() );
628 oldRepoModified =
true;
632 if ( oldRepo->priority() != it->priority() )
634 DBG <<
"Service repo " << it->alias() <<
" gets new PRIORITY " << it->priority() << std::endl;
635 oldRepo->setPriority( it->priority() );
636 oldRepoModified =
true;
642 urlCredentialExtractor.extract( newUrls );
643 if ( oldRepo->rawBaseUrls() != newUrls )
645 DBG <<
"Service repo " << it->alias() <<
" gets new URLs " << newUrls << std::endl;
646 oldRepo->setBaseUrls( std::move(newUrls) );
647 oldRepoModified =
true;
653 if ( _service.type() == zypp::repo::ServiceType::PLUGIN )
657 oldRepo->getRawGpgChecks( ogpg[0], ogpg[1], ogpg[2] );
658 it-> getRawGpgChecks( ngpg[0], ngpg[1], ngpg[2] );
659 #define Z_CHKGPG(I,N) \
660 if ( ! sameTriboolState( ogpg[I], ngpg[I] ) ) \
662 DBG << "Service repo " << it->alias() << " gets new "#N"Check " << ngpg[I] << std::endl; \
663 oldRepo->set##N##Check( ngpg[I] ); \
664 oldRepoModified = true; \
673 if ( oldRepo->rawGpgKeyUrls() != it->rawGpgKeyUrls() )
675 DBG <<
"Service repo " << it->alias() <<
" gets new GPGKEY url " << it->rawGpgKeyUrls() << std::endl;
676 oldRepo->setGpgKeyUrls( it->rawGpgKeyUrls() );
677 oldRepoModified =
true;
681 if ( oldRepo->rawCfgMirrorlistUrl() != it->rawCfgMirrorlistUrl() )
683 DBG <<
"Service repo " << it->alias() <<
" gets new MIRRORLIST url " << it->rawCfgMirrorlistUrl() << std::endl;
684 oldRepo->setMirrorlistUrl( it->rawCfgMirrorlistUrl() );
685 oldRepoModified =
true;
689 if ( oldRepo->rawCfgMetalinkUrl() != it->rawCfgMetalinkUrl() )
691 DBG <<
"Service repo " << it->alias() <<
" gets new METALINK url " << it->rawCfgMetalinkUrl() << std::endl;
692 oldRepo->setMetalinkUrl( it->rawCfgMetalinkUrl() );
693 oldRepoModified =
true;
697 if ( oldRepoModified )
699 auto modRes = _repoMgr->modifyRepository( oldRepo->alias(), *oldRepo );
700 if ( !modRes )
return Ret::error( modRes.error() );
706 if ( ! _service.reposToDisableEmpty() )
708 _service.clearReposToDisable();
709 _serviceModified =
true;
713 if ( _service.repoStates() != newRepoStates )
715 _service.setRepoStates( std::move(newRepoStates) );
716 _serviceModified =
true;
721 if ( _service.type() != zypp::repo::ServiceType::PLUGIN )
723 if ( _service.ttl() )
726 _serviceModified =
true;
729 if ( _serviceModified )
732 auto modRes = _repoMgr->modifyService( _service.alias(), _service );
733 if ( !modRes )
return Ret::error( modRes.error() );
737 if ( _informalError ) {
738 return Ret::error( std::make_exception_ptr (_informalError.value()) );
746 RepoMgrRefType _repoMgr;
747 zypp::ServiceInfo _service;
753 bool _serviceModified =
false;
759 std::optional<zypp::repo::ServicePluginInformalException> _informalError;