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/sat/SATResolver.h"
34 #include "zypp/sat/Pool.h"
35 #include "zypp/sat/WhatProvides.h"
36 #include "zypp/solver/detail/ProblemSolutionCombi.h"
39 #include "satsolver/repo_solv.h"
40 #include "satsolver/poolarch.h"
41 #include "satsolver/evr.h"
42 #include "satsolver/poolvendor.h"
43 #include "satsolver/policy.h"
46 /////////////////////////////////////////////////////////////////////////
48 { ///////////////////////////////////////////////////////////////////////
49 ///////////////////////////////////////////////////////////////////////
51 { /////////////////////////////////////////////////////////////////////
52 /////////////////////////////////////////////////////////////////////
54 { ///////////////////////////////////////////////////////////////////
58 IMPL_PTR_TYPE(SATResolver);
60 static PoolItemSet triggeredSolution; // only the latest state of an item is interesting
61 // for the pool. Documents already inserted items.
63 //---------------------------------------------------------------------------
64 // Callbacks for SAT policies
65 //---------------------------------------------------------------------------
67 int vendorCheck (Pool *pool, Solvable *solvable1, Solvable *solvable2) {
68 // DBG << "vendorCheck: " << id2str(pool, solvable1->vendor) << " <--> " << id2str(pool, solvable1->vendor) << endl;
69 return VendorAttr::instance().equivalent(id2str(pool, solvable1->vendor), id2str(pool, solvable2->vendor)) ? 0:1;
74 itemToString (PoolItem item, bool shortVersion)
79 if (item->kind() != ResTraits<zypp::Package>::kind)
80 os << item->kind() << ':';
83 os << '-' << item->edition();
84 if (item->arch() != "") {
85 os << '.' << item->arch();
87 Repository s = item->repository();
89 string alias = s.info().alias();
91 && alias != "@system")
93 os << '[' << s.info().alias() << ']';
101 //---------------------------------------------------------------------------
104 SATResolver::dumpOn( std::ostream & os ) const
106 return os << "<resolver/>";
109 //---------------------------------------------------------------------------
111 SATResolver::SATResolver (const ResPool & pool, Pool *SATPool)
116 , _allowdowngrade(false)
117 , _allowarchchange(false)
118 , _allowvendorchange(false)
119 , _allowuninstall(false)
120 , _updatesystem(false)
121 , _allowvirtualconflicts(false)
122 , _noupdateprovide(false)
123 , _dosplitprovides(false)
129 SATResolver::~SATResolver()
133 //---------------------------------------------------------------------------
137 SATResolver::pool (void) const
144 SATResolver::addPoolItemToInstall (PoolItem item)
147 for (PoolItemList::const_iterator iter = _items_to_remove.begin();
148 iter != _items_to_remove.end(); iter++) {
150 _items_to_remove.remove(*iter);
156 _items_to_install.push_back (item);
157 _items_to_install.unique ();
163 SATResolver::addPoolItemsToInstallFromList (PoolItemList & rl)
165 for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
166 addPoolItemToInstall (*iter);
172 SATResolver::addPoolItemToRemove (PoolItem item)
175 for (PoolItemList::const_iterator iter = _items_to_install.begin();
176 iter != _items_to_install.end(); iter++) {
178 _items_to_install.remove(*iter);
184 _items_to_remove.push_back (item);
185 _items_to_remove.unique ();
191 SATResolver::addPoolItemsToRemoveFromList (PoolItemList & rl)
193 for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
194 addPoolItemToRemove (*iter);
199 SATResolver::addPoolItemToLock (PoolItem item)
201 _items_to_lock.push_back (item);
202 _items_to_lock.unique ();
206 //---------------------------------------------------------------------------
208 // copy marked item from solution back to pool
209 // if data != NULL, set as APPL_LOW (from establishPool())
212 SATSolutionToPool (PoolItem item, const ResStatus & status, const ResStatus::TransactByValue causer)
215 if (triggeredSolution.find(item) != triggeredSolution.end()) {
216 _XDEBUG("SATSolutionToPool(" << item << ") is already in the pool --> skip");
221 triggeredSolution.insert(item);
223 // resetting transaction only
224 item.status().resetTransact (causer);
228 if (status.isToBeInstalled()) {
229 r = item.status().setToBeInstalled (causer);
230 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") install !" << r);
232 else if (status.isToBeUninstalledDueToUpgrade()) {
233 r = item.status().setToBeUninstalledDueToUpgrade (causer);
234 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") upgrade !" << r);
236 else if (status.isToBeUninstalled()) {
237 r = item.status().setToBeUninstalled (causer);
238 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") remove !" << r);
240 else if (status.isIncomplete()
241 || status.isNeeded()) {
242 r = item.status().setIncomplete();
243 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") incomplete !" << r);
245 else if (status.isUnneeded()) {
246 r = item.status().setUnneeded();
247 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") unneeded !" << r);
249 else if (status.isSatisfied()) {
250 r = item.status().setSatisfied();
251 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") satisfied !" << r);
253 else if (status.isRecommended()) {
254 item.status().setRecommended(true);
255 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") recommended !" << r);
257 else if (status.isSuggested()) {
258 item.status().setSuggested(true);
259 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") suggested !" << r);
261 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") unchanged !");
267 //----------------------------------------------------------------------------
268 // helper functions for distupgrade
269 //----------------------------------------------------------------------------
271 bool SATResolver::doesObsoleteItem (PoolItem candidate, PoolItem installed) {
272 Solvable *sCandidate = _SATPool->solvables + candidate.satSolvable().id();
273 ::_Repo *installedRepo = sat::Pool::instance().systemRepo().get();
275 Id p, *pp, obsolete, *obsoleteIt;
277 if ((!installedRepo || sCandidate->repo != installedRepo) && sCandidate->obsoletes) {
278 obsoleteIt = sCandidate->repo->idarraydata + sCandidate->obsoletes;
279 while ((obsolete = *obsoleteIt++) != 0)
281 for (pp = pool_whatprovides(_SATPool, obsolete) ; (p = *pp++) != 0; ) {
282 if (p > 0 && installed.satSolvable().id() == (sat::detail::SolvableIdType)p) {
283 MIL << candidate << " obsoletes " << installed << endl;
292 //----------------------------------------------------------------------------
293 //----------------------------------------------------------------------------
295 //----------------------------------------------------------------------------
296 //----------------------------------------------------------------------------
298 //----------------------------------------------------------------------------
299 // Helper functions for the ZYPP-Pool
300 //----------------------------------------------------------------------------
303 //------------------------------------------------------------------------------------------------------------
304 // This function loops over the pool and grabs all items
305 // It clears all previous bySolver() states also
307 // Every toBeInstalled is passed to zypp::solver:detail::Resolver.addPoolItemToInstall()
308 // Every toBeUninstalled is passed to zypp::solver:detail::Resolver.addPoolItemToRemove()
310 // Solver results must be written back to the pool.
311 //------------------------------------------------------------------------------------------------------------
314 struct SATCollectTransact : public resfilter::PoolItemFilterFunctor
316 SATResolver & resolver;
318 SATCollectTransact (SATResolver & r)
322 bool operator()( PoolItem item ) // only transacts() items go here
324 ResStatus status = item.status();
325 bool by_solver = (status.isBySolver() || status.isByApplLow());
328 _XDEBUG("Resetting " << item );
329 item.status().resetTransact( ResStatus::APPL_LOW );// clear any solver/establish transactions
330 return true; // back out here, dont re-queue former solver result
333 if (status.isToBeInstalled()) {
334 resolver.addPoolItemToInstall(item); // -> install!
336 else if (status.isToBeUninstalled()) {
337 resolver.addPoolItemToRemove(item); // -> remove !
339 else if (status.isLocked()
342 resolver.addPoolItemToLock (item);
350 //----------------------------------------------------------------------------
351 //----------------------------------------------------------------------------
353 //----------------------------------------------------------------------------
354 //----------------------------------------------------------------------------
357 class CheckIfUpdate : public resfilter::PoolItemFilterFunctor
363 : is_updated( false )
366 // check this item will be installed
368 bool operator()( PoolItem item )
370 if (item.status().isToBeInstalled())
381 SATResolver::resolvePool(const CapabilitySet & requires_caps,
382 const CapabilitySet & conflict_caps)
384 SATCollectTransact info (*this);
386 MIL << "SATResolver::resolvePool()" << endl;
392 queue_free( &(_jobQueue) );
395 queue_init( &_jobQueue );
396 _items_to_install.clear();
397 _items_to_remove.clear();
398 _items_to_lock.clear();
400 invokeOnEach ( _pool.begin(), _pool.end(),
401 functor::functorRef<bool,PoolItem>(info) );
403 for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
406 Id id = (*iter)->satSolvable().id();
408 ERR << "Install: " << *iter << " not found" << endl;
410 MIL << "Install " << *iter << " with the SAT-Pool ID: " << id << endl;
411 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE );
412 queue_push( &(_jobQueue), id );
415 for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
416 sat::detail::IdType ident( (*iter)->satSolvable().ident().id() );
417 MIL << "Delete " << *iter << " with the string ID: " << ident << endl;
418 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_NAME );
419 queue_push( &(_jobQueue), ident);
422 for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
423 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE_PROVIDES );
424 queue_push( &(_jobQueue), iter->id() );
425 MIL << "Requires " << *iter << endl;
428 for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
429 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_PROVIDES);
430 queue_push( &(_jobQueue), iter->id() );
431 MIL << "Conflicts " << *iter << endl;
434 for (PoolItemList::const_iterator iter = _items_to_lock.begin(); iter != _items_to_lock.end(); iter++) {
435 sat::detail::SolvableIdType ident( (*iter)->satSolvable().id() );
436 if (iter->status().isInstalled()) {
437 MIL << "Lock installed item " << *iter << " with the string ID: " << ident << endl;
438 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE );
439 queue_push( &(_jobQueue), ident );
441 MIL << "Lock NOT installed item " << *iter << " with the string ID: " << ident << endl;
442 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE );
443 queue_push( &(_jobQueue), ident );
447 _solv = solver_create( _SATPool, sat::Pool::instance().systemRepo().get() );
448 _solv->vendorCheckCb = &vendorCheck;
449 _solv->fixsystem = _fixsystem;
450 _solv->updatesystem = _updatesystem;
451 _solv->allowdowngrade = _allowdowngrade;
452 _solv->allowuninstall = _allowuninstall;
453 _solv->allowarchchange = _allowarchchange;
454 _solv->dosplitprovides = _dosplitprovides;
455 _solv->noupdateprovide = _noupdateprovide;
457 sat::Pool::instance().prepare();
460 MIL << "Starting solving...." << endl;
461 solver_solve( _solv, &(_jobQueue) );
462 MIL << "....Solver end" << endl;
464 // copying solution back to zypp pool
465 //-----------------------------------------
467 if (_solv->problems.count > 0 )
469 ERR << "Solverrun finished with an ERROR" << endl;
473 /* solvables to be installed */
474 for (int i = 0; i < _solv->decisionq.count; i++)
477 p = _solv->decisionq.elements[i];
478 if (p < 0 || !sat::Solvable(p))
480 if (sat::Solvable(p).repository().get() == _solv->installed)
483 PoolItem poolItem = _pool.find (sat::Solvable(p));
485 SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
487 ERR << "id " << p << " not found in ZYPP pool." << endl;
491 /* solvables to be erased */
492 for (int i = _solv->installed->start; i < _solv->installed->start + _solv->installed->nsolvables; i++)
494 if (_solv->decisionmap[i] > 0)
497 PoolItem poolItem = _pool.find (sat::Solvable(i));
499 // Check if this is an update
501 invokeOnEach( _pool.byIdentBegin( poolItem ),
502 _pool.byIdentEnd( poolItem ),
503 resfilter::ByUninstalled(), // ByUninstalled
504 functor::functorRef<bool,PoolItem> (info) );
506 if (info.is_updated) {
507 SATSolutionToPool (poolItem, ResStatus::toBeUninstalledDueToUpgrade , ResStatus::SOLVER);
509 SATSolutionToPool (poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER);
512 ERR << "id " << i << " not found in ZYPP pool." << endl;
516 /* solvables which are recommended */
517 for (int i = 0; i < _solv->recommendations.count; i++)
520 p = _solv->recommendations.elements[i];
521 if (p < 0 || !sat::Solvable(p))
524 PoolItem poolItem = _pool.find (sat::Solvable(p));
526 SATSolutionToPool (poolItem, ResStatus::recommended, ResStatus::SOLVER);
528 ERR << "id " << p << " not found in ZYPP pool." << endl;
532 /* solvables which are suggested */
533 for (int i = 0; i < _solv->suggestions.count; i++)
536 p = _solv->suggestions.elements[i];
537 if (p < 0 || !sat::Solvable(p))
540 PoolItem poolItem = _pool.find (sat::Solvable(p));
542 SATSolutionToPool (poolItem, ResStatus::suggested, ResStatus::SOLVER);
544 ERR << "id " << p << " not found in ZYPP pool." << endl;
551 queue_free( &(_jobQueue) );
553 MIL << "SATResolver::resolvePool() done" << endl;
558 //----------------------------------------------------------------------------
559 //----------------------------------------------------------------------------
561 //----------------------------------------------------------------------------
562 //----------------------------------------------------------------------------
564 //----------------------------------------------------------------------------
566 //----------------------------------------------------------------------------
568 struct FindPackage : public resfilter::ResObjectFilterFunctor
570 ProblemSolutionCombi *problemSolution;
571 TransactionKind action;
572 FindPackage (ProblemSolutionCombi *p, const TransactionKind act)
573 : problemSolution (p)
578 bool operator()( PoolItem p)
580 problemSolution->addSingleAction (p, action);
586 string SATResolver::SATprobleminfoString(Id problem, string &detail)
589 Pool *pool = _solv->pool;
591 Id dep, source, target;
594 probr = solver_findproblemrule(_solv, problem);
595 switch (solver_problemruleinfo(_solv, &(_jobQueue), probr, &dep, &source, &target))
597 case SOLVER_PROBLEM_UPDATE_RULE:
598 s = pool_id2solvable(pool, source);
599 ret = str::form (_("problem with installed package %s"), solvable2str(pool, s));
601 case SOLVER_PROBLEM_JOB_RULE:
602 ret = str::form (_("conflicting requests"));
604 case SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP:
605 ret = str::form (_("nothing provides requested %s"), dep2str(pool, dep));
607 case SOLVER_PROBLEM_NOT_INSTALLABLE:
608 s = pool_id2solvable(pool, source);
609 ret = str::form (_("%s is not installable"), solvable2str(pool, s));
611 case SOLVER_PROBLEM_NOTHING_PROVIDES_DEP:
612 s = pool_id2solvable(pool, source);
613 ret = str::form (_("nothing provides %s needed by %s"), dep2str(pool, dep), solvable2str(pool, s));
615 case SOLVER_PROBLEM_SAME_NAME:
616 s = pool_id2solvable(pool, source);
617 s2 = pool_id2solvable(pool, target);
618 ret = str::form (_("cannot install both %s and %s"), solvable2str(pool, s), solvable2str(pool, s2));
620 case SOLVER_PROBLEM_PACKAGE_CONFLICT:
621 s = pool_id2solvable(pool, source);
622 s2 = pool_id2solvable(pool, target);
623 ret = str::form (_("%s conflicts with %s provided by %s"), solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2));
625 case SOLVER_PROBLEM_PACKAGE_OBSOLETES:
626 s = pool_id2solvable(pool, source);
627 s2 = pool_id2solvable(pool, target);
628 ret = str::form (_("%s obsoletes %s provided by %s"), solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2));
630 case SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE:
631 s = pool_id2solvable(pool, source);
633 sat::WhatProvides possibleProviders(cap);
635 // check, if a provider will be deleted
636 typedef list<PoolItem> ProviderList;
637 ProviderList providerlistInstalled, providerlistUninstalled;
638 for_( iter1, possibleProviders.begin(), possibleProviders.end() ) {
639 PoolItem provider1 = ResPool::instance().find( *iter1 );
640 // find pair of an installed/uninstalled item with the same NVR
642 for_( iter2, possibleProviders.begin(), possibleProviders.end() ) {
643 PoolItem provider2 = ResPool::instance().find( *iter2 );
644 if (compareByNVR (provider1.resolvable(),provider2.resolvable()) == 0
645 && (provider1.status().isInstalled() && provider2.status().isUninstalled()
646 || provider2.status().isInstalled() && provider1.status().isUninstalled())) {
652 if (provider1.status().isInstalled())
653 providerlistInstalled.push_back(provider1);
655 providerlistUninstalled.push_back(provider1);
659 ret = str::form (_("%s requires %s, but this requirement cannot be provided"), solvable2str(pool, s), dep2str(pool, dep));
660 if (providerlistInstalled.size() > 0) {
661 detail += _("deleted providers: ");
662 for (ProviderList::const_iterator iter = providerlistInstalled.begin(); iter != providerlistInstalled.end(); iter++) {
663 if (iter == providerlistInstalled.begin())
664 detail += itemToString (*iter, false);
666 detail += "\n " + itemToString (*iter, false);
669 if (providerlistUninstalled.size() > 0) {
670 if (detail.size() > 0)
671 detail += _("\nuninstallable providers: ");
673 detail = _("uninstallable providers: ");
674 for (ProviderList::const_iterator iter = providerlistUninstalled.begin(); iter != providerlistUninstalled.end(); iter++) {
675 if (iter == providerlistUninstalled.begin())
676 detail += itemToString (*iter, false);
678 detail += "\n " + itemToString (*iter, false);
688 SATResolver::problems ()
690 ResolverProblemList resolverProblems;
691 if (_solv && _solv->problems.count) {
692 Pool *pool = _solv->pool;
695 Id problem, solution, element;
698 MIL << "Encountered problems! Here are the solutions:\n" << endl;
701 while ((problem = solver_next_problem(_solv, problem)) != 0) {
702 MIL << "Problem " << pcnt++ << ":" << endl;
703 MIL << "====================================" << endl;
705 string whatString = SATprobleminfoString (problem,detail);
706 MIL << whatString << endl;
707 MIL << "------------------------------------" << endl;
708 ResolverProblem_Ptr resolverProblem = new ResolverProblem (whatString, detail);
710 while ((solution = solver_next_solution(_solv, problem, solution)) != 0) {
712 ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi(resolverProblem);
713 while ((element = solver_next_solutionelement(_solv, problem, solution, element, &p, &rp)) != 0) {
715 /* job, rp is index into job queue */
716 what = _jobQueue.elements[rp];
717 switch (_jobQueue.elements[rp-1])
719 case SOLVER_INSTALL_SOLVABLE: {
720 s = pool->solvables + what;
721 PoolItem poolItem = _pool.find (sat::Solvable(what));
723 if (_solv->installed && s->repo == _solv->installed) {
724 problemSolution->addSingleAction (poolItem, REMOVE);
725 string description = str::form (_("do not keep %s installed"), solvable2str(pool, s) );
726 MIL << description << endl;
727 problemSolution->addDescription (description);
729 problemSolution->addSingleAction (poolItem, REMOVE);
730 string description = str::form (_("do not install %s"), solvable2str(pool, s));
731 MIL << description << endl;
732 problemSolution->addDescription (description);
735 ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << id2str(pool, s->name) << "-"
736 << id2str(pool, s->evr) << "." << id2str(pool, s->arch) << endl;
740 case SOLVER_ERASE_SOLVABLE: {
741 s = pool->solvables + what;
742 PoolItem poolItem = _pool.find (sat::Solvable(what));
744 if (_solv->installed && s->repo == _solv->installed) {
745 problemSolution->addSingleAction (poolItem, KEEP);
746 string description = str::form (_("keep %s"), solvable2str(pool, s));
747 MIL << description << endl;
748 problemSolution->addDescription (description);
750 problemSolution->addSingleAction (poolItem, INSTALL);
751 string description = str::form (_("do not forbid installation of %s"), solvable2str(pool, s));
752 MIL << description << endl;
753 problemSolution->addDescription (description);
756 ERR << "SOLVER_ERASE_SOLVABLE: No item found for " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." <<
757 id2str(pool, s->arch) << endl;
761 case SOLVER_INSTALL_SOLVABLE_NAME:
763 FindPackage info (problemSolution, KEEP);
764 IdString ident( what );
765 invokeOnEach( _pool.byIdentBegin( ident ),
766 _pool.byIdentEnd( ident ),
767 resfilter::ByUninstalled (),
768 functor::functorRef<bool,PoolItem> (info) );
769 string description = str::form (_("do not install %s"), ident.c_str() );
770 MIL << description << endl;
771 problemSolution->addDescription (description);
774 case SOLVER_ERASE_SOLVABLE_NAME:
776 FindPackage info (problemSolution, KEEP);
777 IdString ident( what );
778 invokeOnEach( _pool.byIdentBegin( ident ),
779 _pool.byIdentEnd( ident ),
780 functor::chain (resfilter::ByInstalled (), // ByInstalled
781 resfilter::ByTransact ()), // will be deinstalled
782 functor::functorRef<bool,PoolItem> (info) );
783 string description = str::form (_("keep %s"), ident.c_str());
784 MIL << description << endl;
785 problemSolution->addDescription (description);
788 case SOLVER_INSTALL_SOLVABLE_PROVIDES:
791 FOR_PROVIDES(p, pp, what);
793 PoolItem poolItem = _pool.find (sat::Solvable(p));
794 if (poolItem.status().isToBeInstalled()
795 || poolItem.status().staysUninstalled())
796 problemSolution->addSingleAction (poolItem, KEEP);
798 string description = str::form (_("do not ask to install a solvable providing %s"), dep2str(pool, what));
799 MIL << description << endl;
800 problemSolution->addDescription (description);
803 case SOLVER_ERASE_SOLVABLE_PROVIDES:
806 FOR_PROVIDES(p, pp, what);
808 PoolItem poolItem = _pool.find (sat::Solvable(p));
809 if (poolItem.status().isToBeUninstalled()
810 || poolItem.status().staysInstalled())
811 problemSolution->addSingleAction (poolItem, KEEP);
813 string description = str::form (_("do not ask to delete all solvables providing %s"), dep2str(pool, what));
814 MIL << description << endl;
815 problemSolution->addDescription (description);
818 case SOLVER_INSTALL_SOLVABLE_UPDATE:
820 PoolItem poolItem = _pool.find (sat::Solvable(what));
821 s = pool->solvables + what;
823 if (_solv->installed && s->repo == _solv->installed) {
824 problemSolution->addSingleAction (poolItem, KEEP);
825 string description = str::form (_("do not install most recent version of %s"), solvable2str(pool, s));
826 MIL << description << endl;
827 problemSolution->addDescription (description);
829 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE " << poolItem << " is not selected for installation" << endl;
832 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE: No item found for " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." <<
833 id2str(pool, s->arch) << endl;
838 MIL << "- do something different" << endl;
839 ERR << "No valid solution available" << endl;
843 /* policy, replace p with rp */
844 s = pool->solvables + p;
845 sd = rp ? pool->solvables + rp : 0;
847 PoolItem itemFrom = _pool.find (sat::Solvable(p));
852 PoolItem itemTo = _pool.find (sat::Solvable(rp));
853 if (itemFrom && itemTo) {
854 problemSolution->addSingleAction (itemTo, INSTALL);
856 if (evrcmp(pool, s->evr, sd->evr, EVRCMP_COMPARE ) > 0)
858 string description = str::form (_("downgrade of %s to %s"), solvable2str(pool, s), solvable2str(pool, sd));
859 MIL << description << endl;
860 problemSolution->addDescription (description);
863 if (!_solv->allowarchchange && s->name == sd->name && s->arch != sd->arch && policy_illegal_archchange(_solv, s, sd))
865 string description = str::form (_("architecture change of %s to %s"), solvable2str(pool, s), solvable2str(pool, sd));
866 MIL << description << endl;
867 problemSolution->addDescription (description);
870 if (!_solv->allowvendorchange && s->name == sd->name && s->vendor != sd->vendor && policy_illegal_vendorchange(_solv, s, sd))
872 string description = str::form (_("install %s (with vendor change)\n %s\n-->\n %s") ,
873 solvable2str(pool, sd) , id2str(pool, s->vendor),
874 string(sd->vendor ? id2str(pool, sd->vendor) : " (no vendor) ").c_str() );
875 MIL << description << endl;
876 problemSolution->addDescription (description);
880 string description = str::form (_("replacement of %s with %s"), solvable2str(pool, s), solvable2str(pool, sd));
881 MIL << description << endl;
882 problemSolution->addDescription (description);
885 ERR << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." << id2str(pool, s->arch)
886 << " or " << id2str(pool, sd->name) << "-" << id2str(pool, sd->evr) << "." << id2str(pool, sd->arch) << " not found" << endl;
892 string description = str::form (_("deinstallation of %s"), solvable2str(pool, s));
893 MIL << description << endl;
894 problemSolution->addDescription (description);
895 problemSolution->addSingleAction (itemFrom, REMOVE);
900 resolverProblem->addSolution (problemSolution,
901 problemSolution->actionCount() > 1 ? true : false); // Solutions with more than 1 action will be shown first.
902 MIL << "------------------------------------" << endl;
905 resolverProblems.push_back (resolverProblem);
908 return resolverProblems;
912 SATResolver::applySolutions (const ProblemSolutionList & solutions)
914 for (ProblemSolutionList::const_iterator iter = solutions.begin();
915 iter != solutions.end(); ++iter) {
916 ProblemSolution_Ptr solution = *iter;
917 Resolver dummyResolver(_pool);
918 if (!solution->apply (dummyResolver))
925 ///////////////////////////////////////////////////////////////////
926 };// namespace detail
927 /////////////////////////////////////////////////////////////////////
928 /////////////////////////////////////////////////////////////////////
929 };// namespace solver
930 ///////////////////////////////////////////////////////////////////////
931 ///////////////////////////////////////////////////////////////////////
933 /////////////////////////////////////////////////////////////////////////