1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
4 * Copyright (C) 2000-2002 Ximian, Inc.
5 * Copyright (C) 2005 SUSE Linux Products GmbH
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 #include "zypp/solver/detail/Helper.h"
23 #include "zypp/base/String.h"
24 #include "zypp/Capability.h"
25 #include "zypp/ResStatus.h"
26 #include "zypp/VendorAttr.h"
27 #include "zypp/base/Logger.h"
28 #include "zypp/base/String.h"
29 #include "zypp/base/Gettext.h"
30 #include "zypp/base/Algorithm.h"
31 #include "zypp/ResPool.h"
32 #include "zypp/ResFilters.h"
33 #include "zypp/ZConfig.h"
34 #include "zypp/sat/SATResolver.h"
35 #include "zypp/sat/Pool.h"
36 #include "zypp/sat/WhatProvides.h"
37 #include "zypp/solver/detail/ProblemSolutionCombi.h"
40 #include "satsolver/repo_solv.h"
41 #include "satsolver/poolarch.h"
42 #include "satsolver/evr.h"
43 #include "satsolver/poolvendor.h"
44 #include "satsolver/policy.h"
47 /////////////////////////////////////////////////////////////////////////
49 { ///////////////////////////////////////////////////////////////////////
50 ///////////////////////////////////////////////////////////////////////
52 { /////////////////////////////////////////////////////////////////////
53 /////////////////////////////////////////////////////////////////////
55 { ///////////////////////////////////////////////////////////////////
59 IMPL_PTR_TYPE(SATResolver);
61 static PoolItemSet triggeredSolution; // only the latest state of an item is interesting
62 // for the pool. Documents already inserted items.
64 //---------------------------------------------------------------------------
65 // Callbacks for SAT policies
66 //---------------------------------------------------------------------------
68 int vendorCheck (Pool *pool, Solvable *solvable1, Solvable *solvable2) {
69 // DBG << "vendorCheck: " << id2str(pool, solvable1->vendor) << " <--> " << id2str(pool, solvable1->vendor) << endl;
70 return VendorAttr::instance().equivalent(id2str(pool, solvable1->vendor), id2str(pool, solvable2->vendor)) ? 0:1;
75 itemToString (PoolItem item, bool shortVersion)
80 if (item->kind() != ResTraits<zypp::Package>::kind)
81 os << item->kind() << ':';
84 os << '-' << item->edition();
85 if (item->arch() != "") {
86 os << '.' << item->arch();
88 Repository s = item->repository();
90 string alias = s.info().alias();
92 && alias != "@system")
94 os << '[' << s.info().alias() << ']';
102 //---------------------------------------------------------------------------
105 SATResolver::dumpOn( std::ostream & os ) const
107 return os << "<resolver/>";
110 //---------------------------------------------------------------------------
112 SATResolver::SATResolver (const ResPool & pool, Pool *SATPool)
117 , _allowdowngrade(false)
118 , _allowarchchange(false)
119 , _allowvendorchange(false)
120 , _allowuninstall(false)
121 , _updatesystem(false)
122 , _allowvirtualconflicts(false)
123 , _noupdateprovide(false)
124 , _dosplitprovides(false)
125 , _onlyRequires(ZConfig::instance().solver_onlyRequires())
131 SATResolver::~SATResolver()
135 //---------------------------------------------------------------------------
139 SATResolver::pool (void) const
146 SATResolver::addPoolItemToInstall (PoolItem item)
149 for (PoolItemList::const_iterator iter = _items_to_remove.begin();
150 iter != _items_to_remove.end(); iter++) {
152 _items_to_remove.remove(*iter);
158 _items_to_install.push_back (item);
159 _items_to_install.unique ();
165 SATResolver::addPoolItemsToInstallFromList (PoolItemList & rl)
167 for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
168 addPoolItemToInstall (*iter);
174 SATResolver::addPoolItemToRemove (PoolItem item)
177 for (PoolItemList::const_iterator iter = _items_to_install.begin();
178 iter != _items_to_install.end(); iter++) {
180 _items_to_install.remove(*iter);
186 _items_to_remove.push_back (item);
187 _items_to_remove.unique ();
193 SATResolver::addPoolItemsToRemoveFromList (PoolItemList & rl)
195 for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
196 addPoolItemToRemove (*iter);
201 SATResolver::addPoolItemToLock (PoolItem item)
203 _items_to_lock.push_back (item);
204 _items_to_lock.unique ();
208 //---------------------------------------------------------------------------
210 // copy marked item from solution back to pool
211 // if data != NULL, set as APPL_LOW (from establishPool())
214 SATSolutionToPool (PoolItem item, const ResStatus & status, const ResStatus::TransactByValue causer)
217 if (triggeredSolution.find(item) != triggeredSolution.end()) {
218 _XDEBUG("SATSolutionToPool(" << item << ") is already in the pool --> skip");
223 triggeredSolution.insert(item);
225 // resetting transaction only
226 item.status().resetTransact (causer);
230 if (status.isToBeInstalled()) {
231 r = item.status().setToBeInstalled (causer);
232 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") install !" << r);
234 else if (status.isToBeUninstalledDueToUpgrade()) {
235 r = item.status().setToBeUninstalledDueToUpgrade (causer);
236 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") upgrade !" << r);
238 else if (status.isToBeUninstalled()) {
239 r = item.status().setToBeUninstalled (causer);
240 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") remove !" << r);
242 else if (status.isRecommended()) {
243 item.status().setRecommended(true);
244 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") recommended !" << r);
246 else if (status.isSuggested()) {
247 item.status().setSuggested(true);
248 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") suggested !" << r);
250 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") unchanged !");
256 //----------------------------------------------------------------------------
257 // helper functions for distupgrade
258 //----------------------------------------------------------------------------
260 bool SATResolver::doesObsoleteItem (PoolItem candidate, PoolItem installed) {
261 Solvable *sCandidate = _SATPool->solvables + candidate.satSolvable().id();
262 ::_Repo *installedRepo = sat::Pool::instance().systemRepo().get();
264 Id p, *pp, obsolete, *obsoleteIt;
266 if ((!installedRepo || sCandidate->repo != installedRepo) && sCandidate->obsoletes) {
267 obsoleteIt = sCandidate->repo->idarraydata + sCandidate->obsoletes;
268 while ((obsolete = *obsoleteIt++) != 0)
270 for (pp = pool_whatprovides(_SATPool, obsolete) ; (p = *pp++) != 0; ) {
271 if (p > 0 && installed.satSolvable().id() == (sat::detail::SolvableIdType)p) {
272 MIL << candidate << " obsoletes " << installed << endl;
281 //----------------------------------------------------------------------------
282 //----------------------------------------------------------------------------
284 //----------------------------------------------------------------------------
285 //----------------------------------------------------------------------------
287 //----------------------------------------------------------------------------
288 // Helper functions for the ZYPP-Pool
289 //----------------------------------------------------------------------------
292 //------------------------------------------------------------------------------------------------------------
293 // This function loops over the pool and grabs all items
294 // It clears all previous bySolver() states also
296 // Every toBeInstalled is passed to zypp::solver:detail::Resolver.addPoolItemToInstall()
297 // Every toBeUninstalled is passed to zypp::solver:detail::Resolver.addPoolItemToRemove()
299 // Solver results must be written back to the pool.
300 //------------------------------------------------------------------------------------------------------------
303 struct SATCollectTransact : public resfilter::PoolItemFilterFunctor
305 SATResolver & resolver;
307 SATCollectTransact (SATResolver & r)
311 bool operator()( PoolItem item ) // only transacts() items go here
313 ResStatus status = item.status();
314 bool by_solver = (status.isBySolver() || status.isByApplLow());
317 _XDEBUG("Resetting " << item );
318 item.status().resetTransact( ResStatus::APPL_LOW );// clear any solver/establish transactions
319 return true; // back out here, dont re-queue former solver result
322 if (status.isToBeInstalled()) {
323 resolver.addPoolItemToInstall(item); // -> install!
325 else if (status.isToBeUninstalled()) {
326 resolver.addPoolItemToRemove(item); // -> remove !
328 else if (status.isLocked()
331 resolver.addPoolItemToLock (item);
339 //----------------------------------------------------------------------------
340 //----------------------------------------------------------------------------
342 //----------------------------------------------------------------------------
343 //----------------------------------------------------------------------------
346 class CheckIfUpdate : public resfilter::PoolItemFilterFunctor
352 : is_updated( false )
355 // check this item will be installed
357 bool operator()( PoolItem item )
359 if (item.status().isToBeInstalled())
370 SATResolver::resolvePool(const CapabilitySet & requires_caps,
371 const CapabilitySet & conflict_caps)
373 SATCollectTransact info (*this);
375 MIL << "SATResolver::resolvePool()" << endl;
381 queue_free( &(_jobQueue) );
384 queue_init( &_jobQueue );
385 _items_to_install.clear();
386 _items_to_remove.clear();
387 _items_to_lock.clear();
389 invokeOnEach ( _pool.begin(), _pool.end(),
390 functor::functorRef<bool,PoolItem>(info) );
392 for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
395 Id id = (*iter)->satSolvable().id();
397 ERR << "Install: " << *iter << " not found" << endl;
399 MIL << "Install " << *iter << " with the SAT-Pool ID: " << id << endl;
400 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE );
401 queue_push( &(_jobQueue), id );
404 for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
405 sat::detail::IdType ident( (*iter)->satSolvable().ident().id() );
406 MIL << "Delete " << *iter << " with the string ID: " << ident << endl;
407 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_NAME );
408 queue_push( &(_jobQueue), ident);
411 for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
412 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE_PROVIDES );
413 queue_push( &(_jobQueue), iter->id() );
414 MIL << "Requires " << *iter << endl;
417 for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
418 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_PROVIDES);
419 queue_push( &(_jobQueue), iter->id() );
420 MIL << "Conflicts " << *iter << endl;
423 for (PoolItemList::const_iterator iter = _items_to_lock.begin(); iter != _items_to_lock.end(); iter++) {
424 sat::detail::SolvableIdType ident( (*iter)->satSolvable().id() );
425 if (iter->status().isInstalled()) {
426 MIL << "Lock installed item " << *iter << " with the string ID: " << ident << endl;
427 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE );
428 queue_push( &(_jobQueue), ident );
430 MIL << "Lock NOT installed item " << *iter << " with the string ID: " << ident << endl;
431 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE );
432 queue_push( &(_jobQueue), ident );
436 _solv = solver_create( _SATPool, sat::Pool::instance().systemRepo().get() );
437 _solv->vendorCheckCb = &vendorCheck;
438 _solv->fixsystem = _fixsystem;
439 _solv->updatesystem = _updatesystem;
440 _solv->allowdowngrade = _allowdowngrade;
441 _solv->allowuninstall = _allowuninstall;
442 _solv->allowarchchange = _allowarchchange;
443 _solv->dosplitprovides = _dosplitprovides;
444 _solv->noupdateprovide = _noupdateprovide;
445 _solv->dontinstallrecommended = _onlyRequires;
447 sat::Pool::instance().prepare();
450 MIL << "Starting solving...." << endl;
451 solver_solve( _solv, &(_jobQueue) );
452 MIL << "....Solver end" << endl;
454 // copying solution back to zypp pool
455 //-----------------------------------------
457 if (_solv->problems.count > 0 )
459 ERR << "Solverrun finished with an ERROR" << endl;
463 /* solvables to be installed */
464 for (int i = 0; i < _solv->decisionq.count; i++)
467 p = _solv->decisionq.elements[i];
468 if (p < 0 || !sat::Solvable(p))
470 if (sat::Solvable(p).repository().get() == _solv->installed)
473 PoolItem poolItem = _pool.find (sat::Solvable(p));
475 SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
477 ERR << "id " << p << " not found in ZYPP pool." << endl;
481 /* solvables to be erased */
482 for (int i = _solv->installed->start; i < _solv->installed->start + _solv->installed->nsolvables; i++)
484 if (_solv->decisionmap[i] > 0)
487 PoolItem poolItem = _pool.find (sat::Solvable(i));
489 // Check if this is an update
491 invokeOnEach( _pool.byIdentBegin( poolItem ),
492 _pool.byIdentEnd( poolItem ),
493 resfilter::ByUninstalled(), // ByUninstalled
494 functor::functorRef<bool,PoolItem> (info) );
496 if (info.is_updated) {
497 SATSolutionToPool (poolItem, ResStatus::toBeUninstalledDueToUpgrade , ResStatus::SOLVER);
499 SATSolutionToPool (poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER);
502 ERR << "id " << i << " not found in ZYPP pool." << endl;
506 /* solvables which are recommended */
507 for (int i = 0; i < _solv->recommendations.count; i++)
510 p = _solv->recommendations.elements[i];
511 if (p < 0 || !sat::Solvable(p))
514 PoolItem poolItem = _pool.find (sat::Solvable(p));
516 SATSolutionToPool (poolItem, ResStatus::recommended, ResStatus::SOLVER);
518 ERR << "id " << p << " not found in ZYPP pool." << endl;
522 /* solvables which are suggested */
523 for (int i = 0; i < _solv->suggestions.count; i++)
526 p = _solv->suggestions.elements[i];
527 if (p < 0 || !sat::Solvable(p))
530 PoolItem poolItem = _pool.find (sat::Solvable(p));
532 SATSolutionToPool (poolItem, ResStatus::suggested, ResStatus::SOLVER);
534 ERR << "id " << p << " not found in ZYPP pool." << endl;
541 queue_free( &(_jobQueue) );
543 MIL << "SATResolver::resolvePool() done" << endl;
548 bool SATResolver::doUpdate()
550 MIL << "SATResolver::doUpdate()" << endl;
556 queue_free( &(_jobQueue) );
559 queue_init( &_jobQueue );
561 _solv = solver_create( _SATPool, sat::Pool::instance().systemRepo().get() );
562 _solv->vendorCheckCb = &vendorCheck;
564 _solv->updatesystem = true;
565 _solv->dontinstallrecommended = true; // #FIXME dontinstallrecommended maybe set to false if it works correctly
567 sat::Pool::instance().prepare();
570 MIL << "Starting solving...." << endl;
571 solver_solve( _solv, &(_jobQueue) );
572 MIL << "....Solver end" << endl;
574 // copying solution back to zypp pool
575 //-----------------------------------------
577 /* solvables to be installed */
578 for (int i = 0; i < _solv->decisionq.count; i++)
581 p = _solv->decisionq.elements[i];
582 if (p < 0 || !sat::Solvable(p))
584 if (sat::Solvable(p).repository().get() == _solv->installed)
587 PoolItem poolItem = _pool.find (sat::Solvable(p));
589 SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
591 ERR << "id " << p << " not found in ZYPP pool." << endl;
595 /* solvables to be erased */
596 for (int i = _solv->installed->start; i < _solv->installed->start + _solv->installed->nsolvables; i++)
598 if (_solv->decisionmap[i] > 0)
601 PoolItem poolItem = _pool.find (sat::Solvable(i));
603 // Check if this is an update
605 invokeOnEach( _pool.byIdentBegin( poolItem ),
606 _pool.byIdentEnd( poolItem ),
607 resfilter::ByUninstalled(), // ByUninstalled
608 functor::functorRef<bool,PoolItem> (info) );
610 if (info.is_updated) {
611 SATSolutionToPool (poolItem, ResStatus::toBeUninstalledDueToUpgrade , ResStatus::SOLVER);
613 SATSolutionToPool (poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER);
616 ERR << "id " << i << " not found in ZYPP pool." << endl;
623 queue_free( &(_jobQueue) );
625 MIL << "SATResolver::doUpdate() done" << endl;
631 //----------------------------------------------------------------------------
632 //----------------------------------------------------------------------------
634 //----------------------------------------------------------------------------
635 //----------------------------------------------------------------------------
637 //----------------------------------------------------------------------------
639 //----------------------------------------------------------------------------
641 struct FindPackage : public resfilter::ResObjectFilterFunctor
643 ProblemSolutionCombi *problemSolution;
644 TransactionKind action;
645 FindPackage (ProblemSolutionCombi *p, const TransactionKind act)
646 : problemSolution (p)
651 bool operator()( PoolItem p)
653 problemSolution->addSingleAction (p, action);
659 string SATResolver::SATprobleminfoString(Id problem, string &detail)
662 Pool *pool = _solv->pool;
664 Id dep, source, target;
667 probr = solver_findproblemrule(_solv, problem);
668 switch (solver_problemruleinfo(_solv, &(_jobQueue), probr, &dep, &source, &target))
670 case SOLVER_PROBLEM_UPDATE_RULE:
671 s = pool_id2solvable(pool, source);
672 ret = str::form (_("problem with installed package %s"), solvable2str(pool, s));
674 case SOLVER_PROBLEM_JOB_RULE:
675 ret = str::form (_("conflicting requests"));
677 case SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP:
678 ret = str::form (_("nothing provides requested %s"), dep2str(pool, dep));
680 case SOLVER_PROBLEM_NOT_INSTALLABLE:
681 s = pool_id2solvable(pool, source);
682 ret = str::form (_("%s is not installable"), solvable2str(pool, s));
684 case SOLVER_PROBLEM_NOTHING_PROVIDES_DEP:
685 s = pool_id2solvable(pool, source);
686 ret = str::form (_("nothing provides %s needed by %s"), dep2str(pool, dep), solvable2str(pool, s));
688 case SOLVER_PROBLEM_SAME_NAME:
689 s = pool_id2solvable(pool, source);
690 s2 = pool_id2solvable(pool, target);
691 ret = str::form (_("cannot install both %s and %s"), solvable2str(pool, s), solvable2str(pool, s2));
693 case SOLVER_PROBLEM_PACKAGE_CONFLICT:
694 s = pool_id2solvable(pool, source);
695 s2 = pool_id2solvable(pool, target);
696 ret = str::form (_("%s conflicts with %s provided by %s"), solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2));
698 case SOLVER_PROBLEM_PACKAGE_OBSOLETES:
699 s = pool_id2solvable(pool, source);
700 s2 = pool_id2solvable(pool, target);
701 ret = str::form (_("%s obsoletes %s provided by %s"), solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2));
703 case SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE:
704 s = pool_id2solvable(pool, source);
706 sat::WhatProvides possibleProviders(cap);
708 // check, if a provider will be deleted
709 typedef list<PoolItem> ProviderList;
710 ProviderList providerlistInstalled, providerlistUninstalled;
711 for_( iter1, possibleProviders.begin(), possibleProviders.end() ) {
712 PoolItem provider1 = ResPool::instance().find( *iter1 );
713 // find pair of an installed/uninstalled item with the same NVR
715 for_( iter2, possibleProviders.begin(), possibleProviders.end() ) {
716 PoolItem provider2 = ResPool::instance().find( *iter2 );
717 if (compareByNVR (provider1.resolvable(),provider2.resolvable()) == 0
718 && (provider1.status().isInstalled() && provider2.status().isUninstalled()
719 || provider2.status().isInstalled() && provider1.status().isUninstalled())) {
725 if (provider1.status().isInstalled())
726 providerlistInstalled.push_back(provider1);
728 providerlistUninstalled.push_back(provider1);
732 ret = str::form (_("%s requires %s, but this requirement cannot be provided"), solvable2str(pool, s), dep2str(pool, dep));
733 if (providerlistInstalled.size() > 0) {
734 detail += _("deleted providers: ");
735 for (ProviderList::const_iterator iter = providerlistInstalled.begin(); iter != providerlistInstalled.end(); iter++) {
736 if (iter == providerlistInstalled.begin())
737 detail += itemToString (*iter, false);
739 detail += "\n " + itemToString (*iter, false);
742 if (providerlistUninstalled.size() > 0) {
743 if (detail.size() > 0)
744 detail += _("\nuninstallable providers: ");
746 detail = _("uninstallable providers: ");
747 for (ProviderList::const_iterator iter = providerlistUninstalled.begin(); iter != providerlistUninstalled.end(); iter++) {
748 if (iter == providerlistUninstalled.begin())
749 detail += itemToString (*iter, false);
751 detail += "\n " + itemToString (*iter, false);
761 SATResolver::problems ()
763 ResolverProblemList resolverProblems;
764 if (_solv && _solv->problems.count) {
765 Pool *pool = _solv->pool;
768 Id problem, solution, element;
771 MIL << "Encountered problems! Here are the solutions:\n" << endl;
774 while ((problem = solver_next_problem(_solv, problem)) != 0) {
775 MIL << "Problem " << pcnt++ << ":" << endl;
776 MIL << "====================================" << endl;
778 string whatString = SATprobleminfoString (problem,detail);
779 MIL << whatString << endl;
780 MIL << "------------------------------------" << endl;
781 ResolverProblem_Ptr resolverProblem = new ResolverProblem (whatString, detail);
783 while ((solution = solver_next_solution(_solv, problem, solution)) != 0) {
785 ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi(resolverProblem);
786 while ((element = solver_next_solutionelement(_solv, problem, solution, element, &p, &rp)) != 0) {
788 /* job, rp is index into job queue */
789 what = _jobQueue.elements[rp];
790 switch (_jobQueue.elements[rp-1])
792 case SOLVER_INSTALL_SOLVABLE: {
793 s = pool->solvables + what;
794 PoolItem poolItem = _pool.find (sat::Solvable(what));
796 if (_solv->installed && s->repo == _solv->installed) {
797 problemSolution->addSingleAction (poolItem, REMOVE);
798 string description = str::form (_("do not keep %s installed"), solvable2str(pool, s) );
799 MIL << description << endl;
800 problemSolution->addDescription (description);
802 problemSolution->addSingleAction (poolItem, REMOVE);
803 string description = str::form (_("do not install %s"), solvable2str(pool, s));
804 MIL << description << endl;
805 problemSolution->addDescription (description);
808 ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << id2str(pool, s->name) << "-"
809 << id2str(pool, s->evr) << "." << id2str(pool, s->arch) << endl;
813 case SOLVER_ERASE_SOLVABLE: {
814 s = pool->solvables + what;
815 PoolItem poolItem = _pool.find (sat::Solvable(what));
817 if (_solv->installed && s->repo == _solv->installed) {
818 problemSolution->addSingleAction (poolItem, KEEP);
819 string description = str::form (_("keep %s"), solvable2str(pool, s));
820 MIL << description << endl;
821 problemSolution->addDescription (description);
823 problemSolution->addSingleAction (poolItem, INSTALL);
824 string description = str::form (_("do not forbid installation of %s"), solvable2str(pool, s));
825 MIL << description << endl;
826 problemSolution->addDescription (description);
829 ERR << "SOLVER_ERASE_SOLVABLE: No item found for " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." <<
830 id2str(pool, s->arch) << endl;
834 case SOLVER_INSTALL_SOLVABLE_NAME:
836 FindPackage info (problemSolution, KEEP);
837 IdString ident( what );
838 invokeOnEach( _pool.byIdentBegin( ident ),
839 _pool.byIdentEnd( ident ),
840 resfilter::ByUninstalled (),
841 functor::functorRef<bool,PoolItem> (info) );
842 string description = str::form (_("do not install %s"), ident.c_str() );
843 MIL << description << endl;
844 problemSolution->addDescription (description);
847 case SOLVER_ERASE_SOLVABLE_NAME:
849 FindPackage info (problemSolution, KEEP);
850 IdString ident( what );
851 invokeOnEach( _pool.byIdentBegin( ident ),
852 _pool.byIdentEnd( ident ),
853 functor::chain (resfilter::ByInstalled (), // ByInstalled
854 resfilter::ByTransact ()), // will be deinstalled
855 functor::functorRef<bool,PoolItem> (info) );
856 string description = str::form (_("keep %s"), ident.c_str());
857 MIL << description << endl;
858 problemSolution->addDescription (description);
861 case SOLVER_INSTALL_SOLVABLE_PROVIDES:
864 FOR_PROVIDES(p, pp, what);
866 PoolItem poolItem = _pool.find (sat::Solvable(p));
867 if (poolItem.status().isToBeInstalled()
868 || poolItem.status().staysUninstalled())
869 problemSolution->addSingleAction (poolItem, KEEP);
871 string description = str::form (_("do not ask to install a solvable providing %s"), dep2str(pool, what));
872 MIL << description << endl;
873 problemSolution->addDescription (description);
876 case SOLVER_ERASE_SOLVABLE_PROVIDES:
879 FOR_PROVIDES(p, pp, what);
881 PoolItem poolItem = _pool.find (sat::Solvable(p));
882 if (poolItem.status().isToBeUninstalled()
883 || poolItem.status().staysInstalled())
884 problemSolution->addSingleAction (poolItem, KEEP);
886 string description = str::form (_("do not ask to delete all solvables providing %s"), dep2str(pool, what));
887 MIL << description << endl;
888 problemSolution->addDescription (description);
891 case SOLVER_INSTALL_SOLVABLE_UPDATE:
893 PoolItem poolItem = _pool.find (sat::Solvable(what));
894 s = pool->solvables + what;
896 if (_solv->installed && s->repo == _solv->installed) {
897 problemSolution->addSingleAction (poolItem, KEEP);
898 string description = str::form (_("do not install most recent version of %s"), solvable2str(pool, s));
899 MIL << description << endl;
900 problemSolution->addDescription (description);
902 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE " << poolItem << " is not selected for installation" << endl;
905 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE: No item found for " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." <<
906 id2str(pool, s->arch) << endl;
911 MIL << "- do something different" << endl;
912 ERR << "No valid solution available" << endl;
916 /* policy, replace p with rp */
917 s = pool->solvables + p;
918 sd = rp ? pool->solvables + rp : 0;
920 PoolItem itemFrom = _pool.find (sat::Solvable(p));
925 PoolItem itemTo = _pool.find (sat::Solvable(rp));
926 if (itemFrom && itemTo) {
927 problemSolution->addSingleAction (itemTo, INSTALL);
929 if (evrcmp(pool, s->evr, sd->evr, EVRCMP_COMPARE ) > 0)
931 string description = str::form (_("downgrade of %s to %s"), solvable2str(pool, s), solvable2str(pool, sd));
932 MIL << description << endl;
933 problemSolution->addDescription (description);
936 if (!_solv->allowarchchange && s->name == sd->name && s->arch != sd->arch && policy_illegal_archchange(_solv, s, sd))
938 string description = str::form (_("architecture change of %s to %s"), solvable2str(pool, s), solvable2str(pool, sd));
939 MIL << description << endl;
940 problemSolution->addDescription (description);
943 if (!_solv->allowvendorchange && s->name == sd->name && s->vendor != sd->vendor && policy_illegal_vendorchange(_solv, s, sd))
945 string description = str::form (_("install %s (with vendor change)\n %s\n-->\n %s") ,
946 solvable2str(pool, sd) , id2str(pool, s->vendor),
947 string(sd->vendor ? id2str(pool, sd->vendor) : " (no vendor) ").c_str() );
948 MIL << description << endl;
949 problemSolution->addDescription (description);
953 string description = str::form (_("replacement of %s with %s"), solvable2str(pool, s), solvable2str(pool, sd));
954 MIL << description << endl;
955 problemSolution->addDescription (description);
958 ERR << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." << id2str(pool, s->arch)
959 << " or " << id2str(pool, sd->name) << "-" << id2str(pool, sd->evr) << "." << id2str(pool, sd->arch) << " not found" << endl;
965 string description = str::form (_("deinstallation of %s"), solvable2str(pool, s));
966 MIL << description << endl;
967 problemSolution->addDescription (description);
968 problemSolution->addSingleAction (itemFrom, REMOVE);
973 resolverProblem->addSolution (problemSolution,
974 problemSolution->actionCount() > 1 ? true : false); // Solutions with more than 1 action will be shown first.
975 MIL << "------------------------------------" << endl;
978 resolverProblems.push_back (resolverProblem);
981 return resolverProblems;
985 SATResolver::applySolutions (const ProblemSolutionList & solutions)
987 for (ProblemSolutionList::const_iterator iter = solutions.begin();
988 iter != solutions.end(); ++iter) {
989 ProblemSolution_Ptr solution = *iter;
990 Resolver dummyResolver(_pool);
991 if (!solution->apply (dummyResolver))
998 ///////////////////////////////////////////////////////////////////
999 };// namespace detail
1000 /////////////////////////////////////////////////////////////////////
1001 /////////////////////////////////////////////////////////////////////
1002 };// namespace solver
1003 ///////////////////////////////////////////////////////////////////////
1004 ///////////////////////////////////////////////////////////////////////
1006 /////////////////////////////////////////////////////////////////////////