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 ( oldRepoModified )
 
  675                auto modRes = _repoMgr->modifyRepository( oldRepo->alias(), *oldRepo );
 
  676                if ( !modRes ) 
return Ret::error( modRes.error() );
 
  682          if ( ! _service.reposToDisableEmpty() )
 
  684            _service.clearReposToDisable();
 
  685            _serviceModified = 
true;
 
  689          if ( _service.repoStates() != newRepoStates )
 
  691            _service.setRepoStates( std::move(newRepoStates) );
 
  692            _serviceModified = 
true;
 
  697          if ( _service.type() != zypp::repo::ServiceType::PLUGIN )
 
  699            if ( _service.ttl() )
 
  702              _serviceModified =  
true; 
 
  705            if ( _serviceModified )
 
  708              auto modRes = _repoMgr->modifyService( _service.alias(), _service );
 
  709              if ( !modRes ) 
return Ret::error( modRes.error() );
 
  713          if ( _informalError ) {
 
  714            return Ret::error( std::make_exception_ptr (_informalError.value()) );
 
  722      RepoMgrRefType    _repoMgr;
 
  723      zypp::ServiceInfo _service;
 
  729      bool _serviceModified = 
false;
 
  735      std::optional<zypp::repo::ServicePluginInformalException> _informalError;