15 #include <zypp-core/zyppng/pipelines/MTry> 16 #include <zypp-core/zyppng/pipelines/Await> 17 #include <zypp-core/zyppng/io/Process> 25 #include <zypp/ng/Context> 30 #undef ZYPP_BASE_LOGGER_LOGGROUP 31 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::repomanager" 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) )
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 ) {
83 auto callback = [&](
const zypp::RepoInfo &r) { repos.push_back(r);
return true; };
86 _service.setProbedTtl( reader.ttl() );
109 template <
class Executor,
class OpType>
110 struct FetchPluginServiceLogic :
public LogicBase<Executor, OpType>
117 using RepoMgrRefType = RepoManagerRef<ZyppContextRefType>;
118 using Ret = expected<std::pair<zypp::ServiceInfo, RepoInfoList>>;
120 FetchPluginServiceLogic( ZyppContextRefType &&ctx,
zypp::Pathname &&root_r,
ServiceInfo &&service, ProgressObserverRef &&myProgress )
121 :
_ctx( std::move(ctx) )
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;
148 auto callback = [&](
const zypp::RepoInfo &r) { repos.push_back(r);
return true; };
155 return Ret::error( std::current_exception () );
161 ZyppContextRefType
_ctx;
170 struct SyncFetchPluginService : FetchPluginServiceLogic<SyncFetchPluginService, SyncOp< expected< std::pair<zypp::ServiceInfo, RepoInfoList> >>>
172 using FetchPluginServiceLogic::FetchPluginServiceLogic;
173 expected<int> runPlugin( std::string command ) {
175 std::stringstream buffer;
179 args.push_back(
"/bin/sh" );
180 args.push_back(
"-c" );
181 args.push_back( command );
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;
203 AsyncOpRef<expected<int>> runPlugin( std::string command ) {
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) ); };
226 expected<int> finalize( ProcessRef 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()); } )
272 | [url]( expected<ProvideRes> result ) {
277 std::rethrow_exception( result.error() );
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>;
334 MaybeAsyncRef<expected<void>> probeServiceIfNeeded() {
336 if (
_service.type() == zypp::repo::ServiceType::NONE ) {
349 MaybeAsyncRef<Ret> execute() {
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() );
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() ) {
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() )
437 for_( it, collector.repos.begin(), collector.repos.end() )
445 newRepoStates[it->alias()] = *it;
453 if ( !it->path().empty() )
455 if ( it->path() !=
"/" )
460 if ( it->baseUrlsEmpty() )
465 it->setBaseUrl( std::move(url) );
467 else if ( !path.
empty() )
474 it->setBaseUrls( std::move(urls) );
482 _repoMgr->getRepositoriesInService(
_service.alias(), std::back_inserter( oldRepos ) );
486 for_( oldRepo, oldRepos.begin(), oldRepos.end() )
488 if ( !
foundAliasIn( oldRepo->alias(), collector.repos ) )
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() );
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() );
515 for_( it, collector.repos.begin(), collector.repos.end() )
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() );
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() )
689 if (
_service.repoStates() != newRepoStates )
691 _service.setRepoStates( std::move(newRepoStates) );
697 if (
_service.type() != zypp::repo::ServiceType::PLUGIN )
709 if ( !modRes )
return Ret::error( modRes.error() );
714 return Ret::error( std::make_exception_ptr (
_informalError.value()) );
717 return Ret::success( );
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.
static constexpr RefreshServiceBit RefreshService_restoreStatus
boost::logic::tribool TriBool
3-state boolean logic (true, false and indeterminate).
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.
RepoManagerFlags::RefreshServiceFlags RefreshServiceOptions
Options tuning RefreshService.
SignalProxy< void(int)> sigFinished()
AsyncOpRef< expected< zypp::repo::ServiceType > > probeServiceType(ContextRef ctx, const zypp::Url &url)
RefreshServiceFlags RefreshServiceOptions
Options tuning RefreshService.
ExternalProgram extended to offer reading programs stderr.
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.
What is known about a repository.
static expected< std::decay_t< Type >, Err > make_expected_success(Type &&t)
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.
zypp::RepoManager::RefreshServiceOptions _options
expected< void > assert_url(const ServiceInfo &info)
Interface of repoindex.xml file reader.
zypp::RepoInfoList RepoInfoList
AsyncOpRef< expected< std::pair< zypp::ServiceInfo, RepoInfoList > > > fetchRepoListfromService(ContextRef ctx, zypp::Pathname root_r, ServiceInfo service, ProgressObserverRef myProgress)
void remember(const Exception &old_r)
Store an other Exception as history.
std::string asString(TInt val, char zero='0', char one='1')
For printing bits.
Exp mtry(F &&f, Args &&...args)
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.
RepoManagerRef< SyncContextRef > SyncRepoManagerRef
expected< void > assert_alias(const RepoInfo &info)
int close() override
Wait for the progamm to complete.
#define ZYPP_ENABLE_LOGIC_BASE(Executor, OpType)
static constexpr RefreshServiceBit RefreshService_forceRefresh
Read repository data from a .repo file.
typename conditional< B, T, F >::type conditional_t
std::conditional_t< isAsync, AsyncOpRef< T >, T > makeReadyResult(T &&result)
std::vector< std::string > Arguments
static expected success(ConsParams &&...params)
zypp::ServiceInfo ServiceInfo
bool stderrGetUpTo(std::string &retval_r, const char delim_r, bool returnDelim_r=false)
Read data up to delim_r from stderr (nonblocking).
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
std::shared_ptr< AsyncOp< T > > AsyncOpRef
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.
AsyncOpRef< expected< void > > refreshService(AsyncRepoManagerRef repoMgr, ServiceInfo info, zypp::RepoManagerFlags::RefreshServiceOptions options)
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
RepoManagerRef< ContextRef > AsyncRepoManagerRef
ResultType and_then(const expected< T, E > &exp, Function &&f)
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.
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
const std::string & msg() const
Return the message string provided to the ctor.