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_onlyRequires         ( 
true )
 
   90    , _applyDefault_allowDowngrade       ( 
true )
 
   91    , _applyDefault_allowNameChange      ( 
true )
 
   92    , _applyDefault_allowArchChange      ( 
true )
 
   93    , _applyDefault_allowVendorChange    ( 
true )
 
   94    , _applyDefault_dupAllowDowngrade    ( 
true )
 
   95    , _applyDefault_dupAllowNameChange   ( 
true )
 
   96    , _applyDefault_dupAllowArchChange   ( 
true )
 
   97    , _applyDefault_dupAllowVendorChange ( 
true )
 
  100    _satResolver = 
new SATResolver(_pool, satPool.get());
 
  110{ 
return _satResolver->get(); }
 
  115  MIL << 
"setDefaultSolverFlags all=" << all_r << endl;
 
  119#define ZOLV_FLAG_DEFAULT( ZSETTER, ZGETTER )        \ 
  120  if ( all_r || _applyDefault_##ZGETTER ) ZSETTER( indeterminate ) 
  133#undef ZOLV_FLAG_TRIBOOL 
  149#define ZOLV_FLAG_TRIBOOL( ZSETTER, ZGETTER, ZVARDEFAULT, ZVARNAME )                    \ 
  150    void Resolver::ZSETTER( TriBool state_r )                                           \ 
  151    { _applyDefault_##ZGETTER = indeterminate(state_r);                                 \ 
  152      bool newval = _applyDefault_##ZGETTER ? ZVARDEFAULT : bool(state_r);              \ 
  153      if ( ZVARNAME != newval ) {                                                       \ 
  154        DBG << #ZGETTER << ": changed from " << (bool)ZVARNAME << " to " << newval << endl;\ 
  158    bool Resolver::ZGETTER() const                                                      \ 
  159    { return ZVARNAME; }                                                                \ 
 
  163#define ZOLV_FLAG_SATSOLV( ZSETTER, ZGETTER, ZVARDEFAULT, ZVARNAME )                    \ 
  164    ZOLV_FLAG_TRIBOOL( ZSETTER, ZGETTER, ZVARDEFAULT, _satResolver->ZVARNAME ) 
 
  175ZOLV_FLAG_SATSOLV( dupSetAllowNameChange   ,dupAllowNameChange   ,
ZConfig::instance().solver_dupAllowNameChange()   ,_dup_allownamechange   )
 
  177ZOLV_FLAG_SATSOLV( dupSetAllowVendorChange ,dupAllowVendorChange ,
ZConfig::instance().solver_dupAllowVendorChange() ,_dup_allowvendorchange )
 
  178#undef ZOLV_FLAG_SATSOLV 
  179#undef ZOLV_FLAG_TRIBOOL 
  190      _extra_requires.clear();
 
  191      _extra_conflicts.clear();
 
  194    _isInstalledBy.clear();
 
  196    _satifiedByInstalled.clear();
 
  197    _installedSatisfied.clear();
 
 
  201{ 
return _satResolver->problematicUpdateItems(); }
 
  203void Resolver::addExtraRequire( 
const Capability & capability )
 
  204{ _extra_requires.insert (capability); }
 
  206void Resolver::removeExtraRequire( 
const Capability & capability )
 
  207{ _extra_requires.erase (capability); }
 
  209void Resolver::addExtraConflict( 
const Capability & capability )
 
  210{ _extra_conflicts.insert (capability); }
 
  212void Resolver::removeExtraConflict( 
const Capability & capability )
 
  213{ _extra_conflicts.erase (capability); }
 
  215void Resolver::removeQueueItem( 
const SolverQueueItem_Ptr& item )
 
  218    for (SolverQueueItemList::const_iterator iter = _added_queue_items.begin();
 
  219         iter != _added_queue_items.end(); iter++) {
 
  221            _added_queue_items.remove(*iter);
 
  227        _removed_queue_items.push_back (item);
 
  228        _removed_queue_items.unique ();
 
  232void Resolver::addQueueItem( 
const SolverQueueItem_Ptr& item )
 
  235    for (SolverQueueItemList::const_iterator iter = _removed_queue_items.begin();
 
  236         iter != _removed_queue_items.end(); iter++) {
 
  238            _removed_queue_items.remove(*iter);
 
  244        _added_queue_items.push_back (item);
 
  245        _added_queue_items.unique ();
 
  249void Resolver::addWeak( 
const PoolItem & item )
 
  250{ _addWeak.push_back( item ); }
 
  294    const char *val = ::getenv(
"ZYPP_FULLLOG");
 
 
  302        Testcase testcase( 
"/var/log/YaST2/autoTestcase" );
 
 
 
  321    MIL << 
"*** undo ***" << endl;
 
  329    _removed_queue_items.clear();
 
  330    _added_queue_items.clear();
 
  335void Resolver::solverInit()
 
  338    MIL << 
"-------------- Calling SAT Solver -------------------" << endl;
 
  341    _satResolver->setDistupgrade                (_upgradeMode);
 
  342    _satResolver->setUpdatesystem               (_updateMode);
 
  343    _satResolver->setFixsystem                  ( isVerifyingMode() );
 
  344    _satResolver->setSolveSrcPackages           ( solveSrcPackages() );
 
  345    _satResolver->setIgnorealreadyrecommended   ( ignoreAlreadyRecommended() );
 
  355    _isInstalledBy.clear();
 
  357    _satifiedByInstalled.clear();
 
  358    _installedSatisfied.clear();
 
  363  DBG << 
"Resolver::verifySystem()" << endl;
 
  367                 resfilter::ByTransact( ),                      
 
  368                 std::ref(resetting) );
 
  369  return resolvePool();
 
  377  return resolvePool();
 
  384  return _satResolver->resolvePool(_extra_requires, _extra_conflicts, _addWeak, _upgradeRepos );
 
  392  return _satResolver->doUpdate();
 
  401    for (SolverQueueItemList::const_iterator iter = _removed_queue_items.begin();
 
  402         iter != _removed_queue_items.end(); iter++) {
 
  403        for (SolverQueueItemList::const_iterator iterQueue = queue.begin(); iterQueue != queue.end(); iterQueue++) {
 
  404            if ( (*iterQueue)->cmp(*iter) == 0) {
 
  405                MIL << 
"remove from queue" << *iter;
 
  406                queue.remove(*iterQueue);
 
  412    for (SolverQueueItemList::const_iterator iter = _added_queue_items.begin();
 
  413         iter != _added_queue_items.end(); iter++) {
 
  415        for (SolverQueueItemList::const_iterator iterQueue = queue.begin(); iterQueue != queue.end(); iterQueue++) {
 
  416            if ( (*iterQueue)->cmp(*iter) == 0) {
 
  422            MIL << 
"add to queue" << *iter;
 
  423            queue.push_back(*iter);
 
  429    _removed_queue_items.clear();
 
  430    _added_queue_items.clear();
 
  432    return _satResolver->resolveQueue(queue, _addWeak);
 
  439  ret.autoInstalled( _satResolver->autoInstalled() );
 
  449  MIL << 
"Resolver::problems()" << endl;
 
  450  return _satResolver->problems();
 
  455  for ( 
const ProblemSolution_Ptr& solution : solutions )
 
  457    if ( ! applySolution( *solution ) )
 
  462bool Resolver::applySolution( 
const ProblemSolution & solution )
 
  465  DBG << 
"apply solution " << solution << endl;
 
  466  for ( 
const SolutionAction_Ptr& action : solution.actions() )
 
  468    if ( ! action->execute( *
this ) )
 
  470      WAR << 
"apply solution action failed: " << action << endl;
 
  480void Resolver::collectResolverInfo()
 
  483         && _isInstalledBy.empty()
 
  484         && _installs.empty()) {
 
  487        PoolItemList itemsToInstall = _satResolver->resultItemsToInstall();
 
  489        for (PoolItemList::const_iterator instIter = itemsToInstall.begin();
 
  490             instIter != itemsToInstall.end(); instIter++) {
 
  492            for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::REQUIRES).begin(); capIt != (*instIter)->dep (Dep::REQUIRES).end(); ++capIt)
 
  494                sat::WhatProvides possibleProviders(*capIt);
 
  495                for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
 
  500                    bool alreadySetForInstallation = 
false;
 
  501                    ItemCapKindMap::const_iterator pos = _isInstalledBy.find(provider);
 
  502                    while (pos != _isInstalledBy.end()
 
  503                           && pos->first == provider
 
  505                        alreadySetForInstallation = 
true;
 
  506                        ItemCapKind capKind = pos->second;
 
  507                        if (capKind.item() == *instIter)  found = 
true;
 
  512                        && provider.status().isToBeInstalled()) {
 
  513                        if (provider.status().isBySolver()) {
 
  514                            ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::REQUIRES, !alreadySetForInstallation );
 
  515                            _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
 
  518                            ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::REQUIRES, 
false );
 
  519                            _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
 
  521                        ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::REQUIRES, !alreadySetForInstallation );
 
  522                        _installs.insert (make_pair( *instIter, capKindisInstalledBy));
 
  525                    if (provider.status().staysInstalled()) { 
 
  526                        ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::REQUIRES, 
false );
 
  527                        _satifiedByInstalled.insert (make_pair( *instIter, capKindisInstalledBy));
 
  529                        ItemCapKind installedSatisfied( *instIter, *capIt, Dep::REQUIRES, 
false );
 
  530                        _installedSatisfied.insert (make_pair( provider, installedSatisfied));
 
  535            if (!(_satResolver->onlyRequires())) {
 
  537                for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::RECOMMENDS).begin(); capIt != (*instIter)->dep (Dep::RECOMMENDS).end(); ++capIt)
 
  539                    sat::WhatProvides possibleProviders(*capIt);
 
  540                    for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
 
  545                        bool alreadySetForInstallation = 
false;
 
  546                        ItemCapKindMap::const_iterator pos = _isInstalledBy.find(provider);
 
  547                        while (pos != _isInstalledBy.end()
 
  548                               && pos->first == provider
 
  550                            alreadySetForInstallation = 
true;
 
  551                            ItemCapKind capKind = pos->second;
 
  552                            if (capKind.item() == *instIter)  found = 
true;
 
  557                            && provider.status().isToBeInstalled()) {
 
  558                            if (provider.status().isBySolver()) {
 
  559                                ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::RECOMMENDS, !alreadySetForInstallation );
 
  560                                _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
 
  563                                ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::RECOMMENDS, 
false );
 
  564                                _isInstalledBy.insert (make_pair( provider, capKindisInstalledBy));
 
  566                            ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::RECOMMENDS, !alreadySetForInstallation );
 
  567                            _installs.insert (make_pair( *instIter, capKindisInstalledBy));
 
  570                        if (provider.status().staysInstalled()) { 
 
  571                            ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::RECOMMENDS, 
false );
 
  572                            _satifiedByInstalled.insert (make_pair( *instIter, capKindisInstalledBy));
 
  574                            ItemCapKind installedSatisfied( *instIter, *capIt, Dep::RECOMMENDS, 
false );
 
  575                            _installedSatisfied.insert (make_pair( provider, installedSatisfied));
 
  581                for (Capabilities::const_iterator capIt = (*instIter)->dep (Dep::SUPPLEMENTS).begin(); capIt != (*instIter)->dep (Dep::SUPPLEMENTS).end(); ++capIt)
 
  583                    sat::WhatProvides possibleProviders(*capIt);
 
  584                    for_( iter, possibleProviders.begin(), possibleProviders.end() ) {
 
  588                        bool alreadySetForInstallation = 
false;
 
  589                        ItemCapKindMap::const_iterator pos = _isInstalledBy.find(*instIter);
 
  590                        while (pos != _isInstalledBy.end()
 
  591                               && pos->first == *instIter
 
  593                            alreadySetForInstallation = 
true;
 
  594                            ItemCapKind capKind = pos->second;
 
  595                            if (capKind.item() == provider)  found = 
true;
 
  600                            && instIter->status().isToBeInstalled()) {
 
  601                            if (instIter->status().isBySolver()) {
 
  602                                ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::SUPPLEMENTS, !alreadySetForInstallation );
 
  603                                _isInstalledBy.insert (make_pair( *instIter, capKindisInstalledBy));
 
  606                                ItemCapKind capKindisInstalledBy( provider, *capIt, Dep::SUPPLEMENTS, 
false );
 
  607                                _isInstalledBy.insert (make_pair( *instIter, capKindisInstalledBy));
 
  609                            ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::SUPPLEMENTS, !alreadySetForInstallation );
 
  610                            _installs.insert (make_pair( provider, capKindisInstalledBy));
 
  613                        if (instIter->status().staysInstalled()) { 
 
  614                            ItemCapKind capKindisInstalledBy( *instIter, *capIt, Dep::SUPPLEMENTS, !alreadySetForInstallation );
 
  615                            _satifiedByInstalled.insert (make_pair( provider, capKindisInstalledBy));
 
  617                            ItemCapKind installedSatisfied( provider, *capIt, Dep::SUPPLEMENTS, 
false );
 
  618                            _installedSatisfied.insert (make_pair( *instIter, installedSatisfied));
 
  631    collectResolverInfo();
 
  633    for (ItemCapKindMap::const_iterator iter = _isInstalledBy.find(item); iter != _isInstalledBy.end();) {
 
  634        ItemCapKind info = iter->second;
 
  635        PoolItem iterItem = iter->first;
 
  636        if (iterItem == item) {
 
  641            iter = _isInstalledBy.end();
 
  650    collectResolverInfo();
 
  652    for (ItemCapKindMap::const_iterator iter = _installs.find(item); iter != _installs.end();) {
 
  653        ItemCapKind info = iter->second;
 
  654        PoolItem iterItem = iter->first;
 
  655        if (iterItem == item) {
 
  660            iter = _installs.end();
 
  669    collectResolverInfo();
 
  671    for (ItemCapKindMap::const_iterator iter = _satifiedByInstalled.find(item); iter != _satifiedByInstalled.end();) {
 
  672        ItemCapKind info = iter->second;
 
  673        PoolItem iterItem = iter->first;
 
  674        if (iterItem == item) {
 
  679            iter = _satifiedByInstalled.end();
 
  688    collectResolverInfo();
 
  690    for (ItemCapKindMap::const_iterator iter = _installedSatisfied.find(item); iter != _installedSatisfied.end();) {
 
  691        ItemCapKind info = iter->second;
 
  692        PoolItem iterItem = iter->first;
 
  693        if (iterItem == item) {
 
  698            iter = _installedSatisfied.end();
 
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
_onlyRequires dupAllowDowngrade
std::list< ItemCapKind > ItemCapKindList
ZOLV_FLAG_SATSOLV(setCleandepsOnRemove, cleandepsOnRemove, ZConfig::instance().solver_cleandepsOnRemove(), _cleandepsOnRemove) ZOLV_FLAG_SATSOLV(setOnlyRequires
_onlyRequires _dup_allowdowngrade dupAllowArchChange
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
#define for_(IT, BEG, END)
Convenient for-loops using iterator.