21#include <boost/static_assert.hpp>
24#define ZYPP_USE_RESOLVER_INTERNALS
39#define MAXSOLVERRUNS 5
44#undef ZYPP_BASE_LOGGER_LOGGROUP
45#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::solver"
63 os <<
"<resolver>" << endl;
64 #define OUTS(t) os << " " << #t << ":\t" << t << endl;
68 OUTS( _solveSrcPackages );
69 OUTS( _ignoreAlreadyRecommended );
71 return os <<
"<resolver/>";
78 : _pool(std::move(pool))
80 , _poolchanged(_pool.serial() )
81 , _upgradeMode (
false )
82 , _updateMode (
false )
83 , _verifying (
false )
84 , _solveSrcPackages (
false )
85 , _ignoreAlreadyRecommended (
true )
86 , _applyDefault_focus (
true )
87 , _applyDefault_forceResolve (
true )
88 , _applyDefault_cleandepsOnRemove (
true )
89 , _applyDefault_noUpdateProvide (
true )
90 , _applyDefault_onlyRequires (
true )
91 , _applyDefault_allowDowngrade (
true )
92 , _applyDefault_allowNameChange (
true )
93 , _applyDefault_allowArchChange (
true )
94 , _applyDefault_allowVendorChange (
true )
95 , _applyDefault_dupAllowDowngrade (
true )
96 , _applyDefault_dupAllowNameChange (
true )
97 , _applyDefault_dupAllowArchChange (
true )
98 , _applyDefault_dupAllowVendorChange (
true )
101 _satResolver =
new SATResolver(_pool, satPool.get());
111{
return _satResolver->get(); }
116 MIL <<
"setDefaultSolverFlags all=" << all_r << endl;
120#define ZOLV_FLAG_DEFAULT( ZSETTER, ZGETTER ) \
121 if ( all_r || _applyDefault_##ZGETTER ) ZSETTER( indeterminate )
135#undef ZOLV_FLAG_TRIBOOL
151#define ZOLV_FLAG_TRIBOOL( ZSETTER, ZGETTER, ZVARDEFAULT, ZVARNAME ) \
152 void Resolver::ZSETTER( TriBool state_r ) \
153 { _applyDefault_##ZGETTER = indeterminate(state_r); \
154 bool newval = _applyDefault_##ZGETTER ? ZVARDEFAULT : bool(state_r); \
155 if ( ZVARNAME != newval ) { \
156 DBG << #ZGETTER << ": changed from " << (bool)ZVARNAME << " to " << newval << " | " << (_applyDefault_##ZGETTER ? "changed default" : "explicitly set" ) << endl;\
160 bool Resolver::ZGETTER() const \
161 { return ZVARNAME; } \
165#define ZOLV_FLAG_SATSOLV( ZSETTER, ZGETTER, ZVARDEFAULT, ZVARNAME ) \
166 ZOLV_FLAG_TRIBOOL( ZSETTER, ZGETTER, ZVARDEFAULT, _satResolver->ZVARNAME )
179ZOLV_FLAG_SATSOLV( dupSetAllowArchChange ,dupAllowArchChange ,
ZConfig::instance().solver_dupAllowArchChange() ,_dup_allowarchchange )
181#undef ZOLV_FLAG_SATSOLV
182#undef ZOLV_FLAG_TRIBOOL
193 _extra_requires.clear();
194 _extra_conflicts.clear();
197 _isInstalledBy.clear();
199 _satifiedByInstalled.clear();
200 _installedSatisfied.clear();
204{
return _satResolver->problematicUpdateItems(); }
206void Resolver::addExtraRequire(
const Capability & capability )
207{ _extra_requires.insert (capability); }
209void Resolver::removeExtraRequire(
const Capability & capability )
210{ _extra_requires.erase (capability); }
212void Resolver::addExtraConflict(
const Capability & capability )
213{ _extra_conflicts.insert (capability); }
215void Resolver::removeExtraConflict(
const Capability & capability )
216{ _extra_conflicts.erase (capability); }
218void Resolver::removeQueueItem(
const SolverQueueItem_Ptr& item )
221 for (SolverQueueItemList::const_iterator iter = _added_queue_items.begin();
222 iter != _added_queue_items.end(); iter++) {
224 _added_queue_items.remove(*iter);
230 _removed_queue_items.push_back (item);
231 _removed_queue_items.unique ();
235void Resolver::addQueueItem(
const SolverQueueItem_Ptr& item )
238 for (SolverQueueItemList::const_iterator iter = _removed_queue_items.begin();
239 iter != _removed_queue_items.end(); iter++) {
241 _removed_queue_items.remove(*iter);
247 _added_queue_items.push_back (item);
248 _added_queue_items.unique ();
252void Resolver::addWeak(
const PoolItem & item )
253{ _addWeak.push_back( item ); }
297 const char *val = ::getenv(
"ZYPP_FULLLOG");
305 Testcase testcase(
"/var/log/YaST2/autoTestcase" );
324 MIL <<
"*** undo ***" << endl;
332 _removed_queue_items.clear();
333 _added_queue_items.clear();
338void Resolver::solverInit()
341 MIL <<
"-------------- Calling SAT Solver -------------------" << endl;
344 _satResolver->setDistupgrade (_upgradeMode);
345 _satResolver->setUpdatesystem (_updateMode);
346 _satResolver->setFixsystem ( isVerifyingMode() );
347 _satResolver->setSolveSrcPackages ( solveSrcPackages() );
348 _satResolver->setIgnorealreadyrecommended ( ignoreAlreadyRecommended() );
358 _isInstalledBy.clear();
360 _satifiedByInstalled.clear();
361 _installedSatisfied.clear();
366 DBG <<
"Resolver::verifySystem()" << endl;
370 resfilter::ByTransact( ),
371 std::ref(resetting) );
372 return resolvePool();
380 return resolvePool();
387 return _satResolver->resolvePool(_extra_requires, _extra_conflicts, _addWeak, _upgradeRepos );
395 return _satResolver->doUpdate();
404 for (SolverQueueItemList::const_iterator iter = _removed_queue_items.begin();
405 iter != _removed_queue_items.end(); iter++) {
406 for (SolverQueueItemList::const_iterator iterQueue = queue.begin(); iterQueue != queue.end(); iterQueue++) {
407 if ( (*iterQueue)->cmp(*iter) == 0) {
408 MIL <<
"remove from queue" << *iter;
409 queue.remove(*iterQueue);
415 for (SolverQueueItemList::const_iterator iter = _added_queue_items.begin();
416 iter != _added_queue_items.end(); iter++) {
418 for (SolverQueueItemList::const_iterator iterQueue = queue.begin(); iterQueue != queue.end(); iterQueue++) {
419 if ( (*iterQueue)->cmp(*iter) == 0) {
425 MIL <<
"add to queue" << *iter;
426 queue.push_back(*iter);
432 _removed_queue_items.clear();
433 _added_queue_items.clear();
435 return _satResolver->resolveQueue(queue, _addWeak);
442 ret.autoInstalled( _satResolver->autoInstalled() );
452 MIL <<
"Resolver::problems()" << endl;
453 return _satResolver->problems();
458 for (
const ProblemSolution_Ptr& solution : solutions )
460 if ( ! applySolution( *solution ) )
465bool Resolver::applySolution(
const ProblemSolution & solution )
468 DBG <<
"apply solution " << solution << endl;
469 for (
const SolutionAction_Ptr& action : solution.actions() )
471 if ( ! action->execute( *
this ) )
473 WAR <<
"apply solution action failed: " << action << endl;
483void Resolver::collectResolverInfo()
486 && _isInstalledBy.empty()
487 && _installs.empty()) {
490 PoolItemList itemsToInstall = _satResolver->resultItemsToInstall();
492 for (PoolItemList::const_iterator instIter = itemsToInstall.begin();
493 instIter != itemsToInstall.end(); instIter++) {
495 for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::REQUIRES).begin(); capIt != (*instIter)->dep (Dep::REQUIRES).end(); ++capIt)
497 sat::WhatProvides possibleProviders(*capIt);
498 for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
503 bool alreadySetForInstallation =
false;
504 ItemCapKindMap::const_iterator pos = _isInstalledBy.find(provider);
505 while (pos != _isInstalledBy.end()
506 && pos->first == provider
508 alreadySetForInstallation =
true;
509 ItemCapKind capKind = pos->second;
510 if (capKind.item() == *instIter) found =
true;
515 && provider.status().isToBeInstalled()) {
516 if (provider.status().isBySolver()) {
517 ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::REQUIRES, !alreadySetForInstallation );
518 _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
521 ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::REQUIRES,
false );
522 _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
524 ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::REQUIRES, !alreadySetForInstallation );
525 _installs.insert (make_pair( *instIter, capKindisInstalledBy));
528 if (provider.status().staysInstalled()) {
529 ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::REQUIRES,
false );
530 _satifiedByInstalled.insert (make_pair( *instIter, capKindisInstalledBy));
532 ItemCapKind installedSatisfied( *instIter, *capIt, Dep::REQUIRES,
false );
533 _installedSatisfied.insert (make_pair( provider, installedSatisfied));
538 if (!(_satResolver->onlyRequires())) {
540 for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::RECOMMENDS).begin(); capIt != (*instIter)->dep (Dep::RECOMMENDS).end(); ++capIt)
542 sat::WhatProvides possibleProviders(*capIt);
543 for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
548 bool alreadySetForInstallation =
false;
549 ItemCapKindMap::const_iterator pos = _isInstalledBy.find(provider);
550 while (pos != _isInstalledBy.end()
551 && pos->first == provider
553 alreadySetForInstallation =
true;
554 ItemCapKind capKind = pos->second;
555 if (capKind.item() == *instIter) found =
true;
560 && provider.status().isToBeInstalled()) {
561 if (provider.status().isBySolver()) {
562 ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::RECOMMENDS, !alreadySetForInstallation );
563 _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
566 ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::RECOMMENDS,
false );
567 _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
569 ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::RECOMMENDS, !alreadySetForInstallation );
570 _installs.insert (make_pair( *instIter, capKindisInstalledBy));
573 if (provider.status().staysInstalled()) {
574 ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::RECOMMENDS,
false );
575 _satifiedByInstalled.insert (make_pair( *instIter, capKindisInstalledBy));
577 ItemCapKind installedSatisfied( *instIter, *capIt, Dep::RECOMMENDS,
false );
578 _installedSatisfied.insert (make_pair( provider, installedSatisfied));
584 for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::SUPPLEMENTS).begin(); capIt != (*instIter)->dep (Dep::SUPPLEMENTS).end(); ++capIt)
586 sat::WhatProvides possibleProviders(*capIt);
587 for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
591 bool alreadySetForInstallation =
false;
592 ItemCapKindMap::const_iterator pos = _isInstalledBy.find(*instIter);
593 while (pos != _isInstalledBy.end()
594 && pos->first == *instIter
596 alreadySetForInstallation =
true;
597 ItemCapKind capKind = pos->second;
598 if (capKind.item() == provider) found =
true;
603 && instIter->status().isToBeInstalled()) {
604 if (instIter->status().isBySolver()) {
605 ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::SUPPLEMENTS, !alreadySetForInstallation );
606 _isInstalledBy.insert (make_pair( *instIter, capKindisInstalledBy));
609 ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::SUPPLEMENTS,
false );
610 _isInstalledBy.insert (make_pair( *instIter, capKindisInstalledBy));
612 ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::SUPPLEMENTS, !alreadySetForInstallation );
613 _installs.insert (make_pair( provider, capKindisInstalledBy));
616 if (instIter->status().staysInstalled()) {
617 ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::SUPPLEMENTS, !alreadySetForInstallation );
618 _satifiedByInstalled.insert (make_pair( provider, capKindisInstalledBy));
620 ItemCapKind installedSatisfied( provider, *capIt, Dep::SUPPLEMENTS,
false );
621 _installedSatisfied.insert (make_pair( *instIter, installedSatisfied));
634 collectResolverInfo();
636 for (ItemCapKindMap::const_iterator iter = _isInstalledBy.find(item); iter != _isInstalledBy.end();) {
637 ItemCapKind info = iter->second;
638 PoolItem iterItem = iter->first;
639 if (iterItem == item) {
644 iter = _isInstalledBy.end();
653 collectResolverInfo();
655 for (ItemCapKindMap::const_iterator iter = _installs.find(item); iter != _installs.end();) {
656 ItemCapKind info = iter->second;
657 PoolItem iterItem = iter->first;
658 if (iterItem == item) {
663 iter = _installs.end();
672 collectResolverInfo();
674 for (ItemCapKindMap::const_iterator iter = _satifiedByInstalled.find(item); iter != _satifiedByInstalled.end();) {
675 ItemCapKind info = iter->second;
676 PoolItem iterItem = iter->first;
677 if (iterItem == item) {
682 iter = _satifiedByInstalled.end();
691 collectResolverInfo();
693 for (ItemCapKindMap::const_iterator iter = _installedSatisfied.find(item); iter != _installedSatisfied.end();) {
694 ItemCapKind info = iter->second;
695 PoolItem iterItem = iter->first;
696 if (iterItem == item) {
701 iter = _installedSatisfied.end();
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Combining sat::Solvable and ResStatus.
ResStatus & status() const
Returns the current status.
PoolItem find(const sat::Solvable &slv_r) const
Return the corresponding PoolItem.
static ResPool instance()
Singleton ctor.
bool setTransact(bool toTansact_r, TransactByValue causer_r)
Toggle between TRANSACT and KEEP_STATE.
bool resetTransact(TransactByValue causer_r)
Not the same as setTransact( false ).
Dependency resolver interface.
bool resolveQueue(solver::detail::SolverQueueItemList &queue)
Resolve package dependencies:
sat::detail::CSolver * get() const
Expert backdoor.
void setRemoveOrphaned(bool yesno_r)
Set whether to remove unused orphans in 'upgrade' mode.
void setDefaultSolverFlags(bool all_r=true)
Reset all solver flags to the systems default (e.g.
ResolverProblemList problems()
Return the dependency problems found by the last call to resolveDependencies().
sat::Transaction getTransaction()
Return the Transaction computed by the last solver run.
void doUpdate()
Update to newest package.
std::list< PoolItem > problematicUpdateItems() const
Unmaintained packages which does not fit to the updated system (broken dependencies) will be deleted.
void applySolutions(const ProblemSolutionList &solutions)
Apply problem solutions.
Resolver(const ResPool &pool)
Ctor.
solver::detail::ItemCapKindList isInstalledBy(const PoolItem &item)
Gives information about WHO has pused an installation of an given item.
solver::detail::ItemCapKindList installs(const PoolItem &item)
Gives information about WHICH additional items will be installed due the installation of an item.
bool resolvePool()
Resolve package dependencies:
void setFocus(ResolverFocus focus_r)
Define the resolver's general attitude when resolving jobs.
void setRemoveUnneeded(bool yesno_r)
File weak remove jobs for unneeded installed packages.
bool removeOrphaned() const
bool verifySystem()
Resolve package dependencies:
~Resolver() override
Dtor.
bool doUpgrade()
Do an distribution upgrade (DUP).
ResolverFocus focus() const
bool removeUnneeded() const
solver::detail::ItemCapKindList installedSatisfied(const PoolItem &item)
Gives information about WHICH items require an already installed item.
solver::detail::ItemCapKindList satifiedByInstalled(const PoolItem &item)
Gives information about WHICH installed items are requested by the installation of an item.
Interim helper class to collect global options and settings.
ResolverFocus solver_focus() const
The resolver's general attitude when resolving jobs.
static ZConfig & instance()
Singleton ctor.
virtual std::ostream & dumpOn(std::ostream &str) const
Overload to realize std::ostream & operator<<.
static Pool instance()
Singleton ctor.
static constexpr LoadFromPoolType loadFromPool
::s_Solver CSolver
Wrapped libsolv C data type exposed as backdoor.
std::list< SolverQueueItem_Ptr > SolverQueueItemList
_noUpdateProvide _allowvendorchange dupAllowNameChange
ZOLV_FLAG_SATSOLV(setCleandepsOnRemove, cleandepsOnRemove, ZConfig::instance().solver_cleandepsOnRemove(), _cleandepsOnRemove) ZOLV_FLAG_SATSOLV(setNoUpdateProvide
_noUpdateProvide _allowvendorchange _dup_allownamechange dupAllowVendorChange
std::list< ItemCapKind > ItemCapKindList
_noUpdateProvide allowVendorChange
bool strToTrue(const C_Str &str)
Parsing boolean from string.
Easy-to use interface to the ZYPP dependency resolver.
std::list< ProblemSolution_Ptr > ProblemSolutionList
@ Default
Request the standard behavior (as defined in zypp.conf or 'Job').
std::list< ResolverProblem_Ptr > ResolverProblemList
int invokeOnEach(TIterator begin_r, TIterator end_r, TFilter filter_r, TFunction fnc_r)
Iterate through [begin_r,end_r) and invoke fnc_r on each item that passes filter_r.
#define ZOLV_FLAG_SATSOLV(ZSETTER, ZGETTER, ZVARDEFAULT, ZVARNAME)
#define ZOLV_FLAG_DEFAULT(ZSETTER, ZGETTER)
Select PoolItem by transact.
ResStatus::TransactByValue resStatus
DoTransact(const ResStatus::TransactByValue &status)
bool operator()(const PoolItem &item)
Write automatic testcases if ZYPP_FULLLOG=1 is set.
~ScopedAutoTestCaseWriter()
ScopedAutoTestCaseWriter(Resolver &resolver_r)
bool operator()(const PoolItem &item)
UndoTransact(const ResStatus::TransactByValue &status)
ResStatus::TransactByValue resStatus