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/Pool.h"
35 #include "zypp/sat/WhatProvides.h"
36 #include "zypp/solver/detail/SATResolver.h"
37 #include "zypp/solver/detail/ProblemSolutionCombi.h"
38 #include "zypp/solver/detail/ProblemSolutionIgnore.h"
41 #include "satsolver/repo_solv.h"
42 #include "satsolver/poolarch.h"
43 #include "satsolver/evr.h"
44 #include "satsolver/poolvendor.h"
45 #include "satsolver/policy.h"
46 #include "satsolver/bitmap.h"
49 /////////////////////////////////////////////////////////////////////////
51 { ///////////////////////////////////////////////////////////////////////
52 ///////////////////////////////////////////////////////////////////////
54 { /////////////////////////////////////////////////////////////////////
55 /////////////////////////////////////////////////////////////////////
57 { ///////////////////////////////////////////////////////////////////
61 IMPL_PTR_TYPE(SATResolver);
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
107 os << " fixsystem = " << _fixsystem << endl;
108 os << " allowdowngrade = " << _allowdowngrade << endl;
109 os << " allowarchchange = " << _allowarchchange << endl;
110 os << " allowvendorchange = " << _allowvendorchange << endl;
111 os << " allowuninstall = " << _allowuninstall << endl;
112 os << " updatesystem = " << _updatesystem << endl;
113 os << " allowvirtualconflicts = " << _allowvirtualconflicts << endl;
114 os << " noupdateprovide = " << _noupdateprovide << endl;
115 os << " dosplitprovides = " << _dosplitprovides << endl;
116 os << " onlyRequires = " << _onlyRequires << endl;
117 return os << "<resolver/>" << endl;
120 //---------------------------------------------------------------------------
122 SATResolver::SATResolver (const ResPool & pool, Pool *SATPool)
127 , _allowdowngrade(false)
128 , _allowarchchange(false)
129 , _allowvendorchange(false)
130 , _allowuninstall(false)
131 , _updatesystem(false)
132 , _allowvirtualconflicts(false)
133 , _noupdateprovide(false)
134 , _dosplitprovides(false)
135 , _onlyRequires(ZConfig::instance().solver_onlyRequires())
141 SATResolver::~SATResolver()
145 //---------------------------------------------------------------------------
149 SATResolver::pool (void) const
156 SATResolver::resetItemTransaction (PoolItem item)
159 for (PoolItemList::const_iterator iter = _items_to_remove.begin();
160 iter != _items_to_remove.end(); iter++) {
162 _items_to_remove.remove(*iter);
168 for (PoolItemList::const_iterator iter = _items_to_install.begin();
169 iter != _items_to_install.end(); iter++) {
171 _items_to_install.remove(*iter);
178 for (PoolItemList::const_iterator iter = _items_to_keep.begin();
179 iter != _items_to_keep.end(); iter++) {
181 _items_to_keep.remove(*iter);
188 for (PoolItemList::const_iterator iter = _items_to_lock.begin();
189 iter != _items_to_lock.end(); iter++) {
191 _items_to_lock.remove(*iter);
198 for (PoolItemList::const_iterator iter = _items_to_update.begin();
199 iter != _items_to_update.end(); iter++) {
201 _items_to_update.remove(*iter);
211 SATResolver::addPoolItemToInstall (PoolItem item)
213 resetItemTransaction (item);
214 _items_to_install.push_back (item);
215 _items_to_install.unique ();
220 SATResolver::addPoolItemsToInstallFromList (PoolItemList & rl)
222 for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
223 addPoolItemToInstall (*iter);
229 SATResolver::addPoolItemToRemove (PoolItem item)
231 resetItemTransaction (item);
232 _items_to_remove.push_back (item);
233 _items_to_remove.unique ();
238 SATResolver::addPoolItemsToRemoveFromList (PoolItemList & rl)
240 for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
241 addPoolItemToRemove (*iter);
246 SATResolver::addPoolItemToLock (PoolItem item)
248 resetItemTransaction (item);
249 _items_to_lock.push_back (item);
250 _items_to_lock.unique ();
254 SATResolver::addPoolItemToKeep (PoolItem item)
256 resetItemTransaction (item);
257 _items_to_keep.push_back (item);
258 _items_to_keep.unique ();
261 //---------------------------------------------------------------------------
263 // copy marked item from solution back to pool
264 // if data != NULL, set as APPL_LOW (from establishPool())
267 SATSolutionToPool (PoolItem item, const ResStatus & status, const ResStatus::TransactByValue causer)
270 item.status().resetTransact (causer);
271 item.status().resetWeak ();
275 // installation/deletion
276 if (status.isToBeInstalled()) {
277 r = item.status().setToBeInstalled (causer);
278 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") install !" << r);
280 else if (status.isToBeUninstalledDueToUpgrade()) {
281 r = item.status().setToBeUninstalledDueToUpgrade (causer);
282 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") upgrade !" << r);
284 else if (status.isToBeUninstalled()) {
285 r = item.status().setToBeUninstalled (causer);
286 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") remove !" << r);
290 if (status.isRecommended()) {
291 item.status().setRecommended(true);
292 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") recommended !" << r);
294 else if (status.isSuggested()) {
295 item.status().setSuggested(true);
296 _XDEBUG("SATSolutionToPool(" << item << ", " << status << ") suggested !" << r);
303 //----------------------------------------------------------------------------
304 // helper functions for distupgrade
305 //----------------------------------------------------------------------------
307 bool SATResolver::doesObsoleteItem (PoolItem candidate, PoolItem installed) {
308 Solvable *sCandidate = _SATPool->solvables + candidate.satSolvable().id();
309 ::_Repo *installedRepo = sat::Pool::instance().systemRepo().get();
311 Id p, *pp, obsolete, *obsoleteIt;
313 if ((!installedRepo || sCandidate->repo != installedRepo) && sCandidate->obsoletes) {
314 obsoleteIt = sCandidate->repo->idarraydata + sCandidate->obsoletes;
315 while ((obsolete = *obsoleteIt++) != 0)
317 for (pp = pool_whatprovides(_SATPool, obsolete) ; (p = *pp++) != 0; ) {
318 if (p > 0 && installed.satSolvable().id() == (sat::detail::SolvableIdType)p) {
319 MIL << candidate << " obsoletes " << installed << endl;
328 //----------------------------------------------------------------------------
329 //----------------------------------------------------------------------------
331 //----------------------------------------------------------------------------
332 //----------------------------------------------------------------------------
334 //----------------------------------------------------------------------------
335 // Helper functions for the ZYPP-Pool
336 //----------------------------------------------------------------------------
339 //------------------------------------------------------------------------------------------------------------
340 // This function loops over the pool and grabs all items
341 // It clears all previous bySolver() states also
343 // Every toBeInstalled is passed to zypp::solver:detail::Resolver.addPoolItemToInstall()
344 // Every toBeUninstalled is passed to zypp::solver:detail::Resolver.addPoolItemToRemove()
346 // Solver results must be written back to the pool.
347 //------------------------------------------------------------------------------------------------------------
350 struct SATCollectTransact : public resfilter::PoolItemFilterFunctor
352 SATResolver & resolver;
354 SATCollectTransact (SATResolver & r)
358 bool operator()( PoolItem item ) // only transacts() items go here
360 ResStatus status = item.status();
361 bool by_solver = (status.isBySolver() || status.isByApplLow());
364 _XDEBUG("Resetting " << item );
365 item.status().resetTransact( ResStatus::APPL_LOW );// clear any solver/establish transactions
366 return true; // back out here, dont re-queue former solver result
369 if (status.isToBeInstalled()) {
370 resolver.addPoolItemToInstall(item); // -> install!
372 else if (status.isToBeUninstalled()) {
373 resolver.addPoolItemToRemove(item); // -> remove !
375 else if (status.isLocked()
377 resolver.addPoolItemToLock (item);
379 else if (status.isKept()
381 resolver.addPoolItemToKeep (item);
389 //----------------------------------------------------------------------------
390 //----------------------------------------------------------------------------
392 //----------------------------------------------------------------------------
393 //----------------------------------------------------------------------------
396 class CheckIfUpdate : public resfilter::PoolItemFilterFunctor
402 : is_updated( false )
405 // check this item will be installed
407 bool operator()( PoolItem item )
409 if (item.status().isToBeInstalled())
419 class SetValidate : public resfilter::PoolItemFilterFunctor
422 Map installedmap, conflictsmap;
424 SetValidate(Solver *solv)
426 solver_create_state_maps(solv, &installedmap, &conflictsmap);
431 bool operator()( PoolItem item )
434 if (isKind<Product>(item.resolvable())) {
435 // FIXME This is a hack for registration 11.0 beta1
436 item.status().setSatisfied();
437 _XDEBUG("SATSolutionToPool(" << item << " ) satisfied. THIS IS A HACK !");
441 int ret = solvable_trivial_installable_map(item.satSolvable().get(), &installedmap, &conflictsmap);
442 item.status().setUndetermined();
445 item.status().setNonRelevant();
446 _XDEBUG("SATSolutionToPool(" << item << " ) nonRelevant !");
447 } else if (ret == 1) {
448 item.status().setSatisfied();
449 _XDEBUG("SATSolutionToPool(" << item << " ) satisfied !");
450 } else if (ret == 0) {
451 item.status().setBroken();
452 _XDEBUG("SATSolutionToPool(" << item << " ) broken !");
459 SATResolver::solving()
461 _solv = solver_create( _SATPool, sat::Pool::instance().systemRepo().get() );
462 _solv->vendorCheckCb = &vendorCheck;
463 _solv->fixsystem = _fixsystem;
464 _solv->updatesystem = _updatesystem;
465 _solv->allowdowngrade = _allowdowngrade;
466 _solv->allowuninstall = _allowuninstall;
467 _solv->allowarchchange = _allowarchchange;
468 _solv->dosplitprovides = _dosplitprovides;
469 _solv->noupdateprovide = _noupdateprovide;
470 _solv->dontinstallrecommended = _onlyRequires;
472 sat::Pool::instance().prepare();
474 // Add ignoring request
478 MIL << "Starting solving...." << endl;
480 solver_solve( _solv, &(_jobQueue) );
481 MIL << "....Solver end" << endl;
483 // copying solution back to zypp pool
484 //-----------------------------------------
486 if (_solv->problems.count > 0 )
488 ERR << "Solverrun finished with an ERROR" << endl;
492 /* solvables to be installed */
493 for (int i = 0; i < _solv->decisionq.count; i++)
496 p = _solv->decisionq.elements[i];
497 if (p < 0 || !sat::Solvable(p))
499 if (sat::Solvable(p).repository().get() == _solv->installed)
502 PoolItem poolItem = _pool.find (sat::Solvable(p));
504 SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
506 ERR << "id " << p << " not found in ZYPP pool." << endl;
510 /* solvables to be erased */
511 for (int i = _solv->installed->start; i < _solv->installed->start + _solv->installed->nsolvables; i++)
513 if (_solv->decisionmap[i] > 0)
516 PoolItem poolItem = _pool.find (sat::Solvable(i));
518 // Check if this is an update
520 invokeOnEach( _pool.byIdentBegin( poolItem ),
521 _pool.byIdentEnd( poolItem ),
522 resfilter::ByUninstalled(), // ByUninstalled
523 functor::functorRef<bool,PoolItem> (info) );
525 if (info.is_updated) {
526 SATSolutionToPool (poolItem, ResStatus::toBeUninstalledDueToUpgrade , ResStatus::SOLVER);
528 SATSolutionToPool (poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER);
531 ERR << "id " << i << " not found in ZYPP pool." << endl;
535 /* solvables which are recommended */
536 for (int i = 0; i < _solv->recommendations.count; i++)
539 p = _solv->recommendations.elements[i];
540 if (p < 0 || !sat::Solvable(p))
543 PoolItem poolItem = _pool.find (sat::Solvable(p));
545 ResStatus status = poolItem.status();
546 status.setRecommended (true);
547 SATSolutionToPool (poolItem, status, ResStatus::SOLVER);
549 ERR << "id " << p << " not found in ZYPP pool." << endl;
553 /* solvables which are suggested */
554 for (int i = 0; i < _solv->suggestions.count; i++)
557 p = _solv->suggestions.elements[i];
558 if (p < 0 || !sat::Solvable(p))
561 PoolItem poolItem = _pool.find (sat::Solvable(p));
563 ResStatus status = poolItem.status();
564 status.setSuggested (true);
565 SATSolutionToPool (poolItem, status, ResStatus::SOLVER);
567 ERR << "id " << p << " not found in ZYPP pool." << endl;
571 /* Write validation state back to pool */
572 SetValidate infoValidate(_solv);
573 invokeOnEach( _pool.begin(),
575 functor::not_c(resfilter::byKind<Package>()), // every solvable BUT packages
576 functor::functorRef<bool,PoolItem> (infoValidate) );
583 SATResolver::solverInit(const PoolItemList & weakItems)
585 SATCollectTransact info (*this);
587 MIL << "SATResolver::solverInit()" << endl;
593 queue_free( &(_jobQueue) );
596 queue_init( &_jobQueue );
597 _items_to_install.clear();
598 _items_to_remove.clear();
599 _items_to_lock.clear();
600 _items_to_keep.clear();
602 invokeOnEach ( _pool.begin(), _pool.end(),
603 functor::functorRef<bool,PoolItem>(info) );
605 for (PoolItemList::const_iterator iter = weakItems.begin(); iter != weakItems.end(); iter++) {
606 Id id = (*iter)->satSolvable().id();
608 ERR << "Weaken: " << *iter << " not found" << endl;
610 MIL << "Weaken dependencies of " << *iter << " with the SAT-Pool ID: " << id << endl;
611 queue_push( &(_jobQueue), SOLVER_WEAKEN_SOLVABLE_DEPS );
612 queue_push( &(_jobQueue), id );
617 SATResolver::solverEnd()
622 queue_free( &(_jobQueue) );
627 SATResolver::resolvePool(const CapabilitySet & requires_caps,
628 const CapabilitySet & conflict_caps,
629 const PoolItemList & weakItems)
631 MIL << "SATResolver::resolvePool()" << endl;
634 solverInit(weakItems);
636 for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
637 Id id = (*iter)->satSolvable().id();
639 ERR << "Install: " << *iter << " not found" << endl;
641 MIL << "Install " << *iter << " with the SAT-Pool ID: " << id << endl;
642 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE );
643 queue_push( &(_jobQueue), id );
646 for (PoolItemList::const_iterator iter = _items_to_update.begin(); iter != _items_to_update.end(); iter++) {
647 Id id = (*iter)->satSolvable().id();
649 ERR << "Update explicit: " << *iter << " not found" << endl;
651 MIL << "Update explicit " << *iter << " with the SAT-Pool ID: " << id << endl;
652 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE_UPDATE );
653 queue_push( &(_jobQueue), id );
656 for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
657 sat::detail::IdType ident( (*iter)->satSolvable().ident().id() );
658 MIL << "Delete " << *iter << " with the string ID: " << ident << endl;
659 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_NAME );
660 queue_push( &(_jobQueue), ident);
663 for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
664 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE_PROVIDES );
665 queue_push( &(_jobQueue), iter->id() );
666 MIL << "Requires " << *iter << endl;
669 for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
670 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE_PROVIDES);
671 queue_push( &(_jobQueue), iter->id() );
672 MIL << "Conflicts " << *iter << endl;
675 for (PoolItemList::const_iterator iter = _items_to_lock.begin(); iter != _items_to_lock.end(); iter++) {
676 sat::detail::SolvableIdType ident( (*iter)->satSolvable().id() );
677 if (iter->status().isInstalled()) {
678 MIL << "Lock installed item " << *iter << " with the string ID: " << ident << endl;
679 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE );
680 queue_push( &(_jobQueue), ident );
682 MIL << "Lock NOT installed item " << *iter << " with the string ID: " << ident << endl;
683 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE );
684 queue_push( &(_jobQueue), ident );
688 for (PoolItemList::const_iterator iter = _items_to_keep.begin(); iter != _items_to_keep.end(); iter++) {
689 sat::detail::SolvableIdType ident( (*iter)->satSolvable().id() );
690 if (iter->status().isInstalled()) {
691 MIL << "Keep installed item " << *iter << " with the string ID: " << ident << endl;
692 queue_push( &(_jobQueue), SOLVER_INSTALL_SOLVABLE | SOLVER_WEAK);
693 queue_push( &(_jobQueue), ident );
695 MIL << "Keep NOT installed item " << *iter << " with the string ID: " << ident << endl;
696 queue_push( &(_jobQueue), SOLVER_ERASE_SOLVABLE | SOLVER_WEAK);
697 queue_push( &(_jobQueue), ident );
702 bool ret = solving();
705 solverEnd(); // remove solver only if no errors happend. Need it for solving problems
707 MIL << "SATResolver::resolvePool() done. Ret:" << ret << endl;
713 SATResolver::resolveQueue(const SolverQueueItemList &requestQueue,
714 const PoolItemList & weakItems)
716 MIL << "SATResolver::resolvQueue()" << endl;
719 solverInit(weakItems);
721 // generate solver queue
722 for (SolverQueueItemList::const_iterator iter = requestQueue.begin(); iter != requestQueue.end(); iter++) {
723 (*iter)->addRule(_jobQueue);
727 bool ret = solving();
731 solverEnd(); // remove solver only if no errors happend. Need it for solving problems
733 MIL << "SATResolver::resolveQueue() done. Ret:" << ret << endl;
738 bool SATResolver::doUpdate()
740 MIL << "SATResolver::doUpdate()" << endl;
743 solverInit(PoolItemList());
745 _solv = solver_create( _SATPool, sat::Pool::instance().systemRepo().get() );
746 _solv->vendorCheckCb = &vendorCheck;
748 _solv->updatesystem = true;
749 _solv->dontinstallrecommended = true; // #FIXME dontinstallrecommended maybe set to false if it works correctly
751 sat::Pool::instance().prepare();
754 MIL << "Starting solving for update...." << endl;
756 solver_solve( _solv, &(_jobQueue) );
757 MIL << "....Solver end" << endl;
759 // copying solution back to zypp pool
760 //-----------------------------------------
762 /* solvables to be installed */
763 for (int i = 0; i < _solv->decisionq.count; i++)
766 p = _solv->decisionq.elements[i];
767 if (p < 0 || !sat::Solvable(p))
769 if (sat::Solvable(p).repository().get() == _solv->installed)
772 PoolItem poolItem = _pool.find (sat::Solvable(p));
774 SATSolutionToPool (poolItem, ResStatus::toBeInstalled, ResStatus::SOLVER);
776 ERR << "id " << p << " not found in ZYPP pool." << endl;
780 /* solvables to be erased */
781 for (int i = _solv->installed->start; i < _solv->installed->start + _solv->installed->nsolvables; i++)
783 if (_solv->decisionmap[i] > 0)
786 PoolItem poolItem = _pool.find (sat::Solvable(i));
788 // Check if this is an update
790 invokeOnEach( _pool.byIdentBegin( poolItem ),
791 _pool.byIdentEnd( poolItem ),
792 resfilter::ByUninstalled(), // ByUninstalled
793 functor::functorRef<bool,PoolItem> (info) );
795 if (info.is_updated) {
796 SATSolutionToPool (poolItem, ResStatus::toBeUninstalledDueToUpgrade , ResStatus::SOLVER);
798 SATSolutionToPool (poolItem, ResStatus::toBeUninstalled, ResStatus::SOLVER);
801 ERR << "id " << i << " not found in ZYPP pool." << endl;
808 MIL << "SATResolver::doUpdate() done" << endl;
814 //----------------------------------------------------------------------------
815 //----------------------------------------------------------------------------
817 //----------------------------------------------------------------------------
818 //----------------------------------------------------------------------------
820 //----------------------------------------------------------------------------
822 //----------------------------------------------------------------------------
824 struct FindPackage : public resfilter::ResObjectFilterFunctor
826 ProblemSolutionCombi *problemSolution;
827 TransactionKind action;
828 FindPackage (ProblemSolutionCombi *p, const TransactionKind act)
829 : problemSolution (p)
834 bool operator()( PoolItem p)
836 problemSolution->addSingleAction (p, action);
842 string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreId)
845 Pool *pool = _solv->pool;
847 Id dep, source, target;
851 probr = solver_findproblemrule(_solv, problem);
852 switch (solver_problemruleinfo(_solv, &(_jobQueue), probr, &dep, &source, &target))
854 case SOLVER_PROBLEM_UPDATE_RULE:
855 s = pool_id2solvable(pool, source);
856 ret = str::form (_("problem with installed package %s"), solvable2str(pool, s));
858 case SOLVER_PROBLEM_JOB_RULE:
859 ret = str::form (_("conflicting requests"));
861 case SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP:
862 ret = str::form (_("nothing provides requested %s"), dep2str(pool, dep));
864 case SOLVER_PROBLEM_NOT_INSTALLABLE:
865 s = pool_id2solvable(pool, source);
866 ret = str::form (_("%s is not installable"), solvable2str(pool, s));
868 case SOLVER_PROBLEM_NOTHING_PROVIDES_DEP:
869 s = pool_id2solvable(pool, source);
870 ret = str::form (_("nothing provides %s needed by %s"), dep2str(pool, dep), solvable2str(pool, s));
872 case SOLVER_PROBLEM_SAME_NAME:
873 s = pool_id2solvable(pool, source);
874 s2 = pool_id2solvable(pool, target);
875 ret = str::form (_("cannot install both %s and %s"), solvable2str(pool, s), solvable2str(pool, s2));
877 case SOLVER_PROBLEM_PACKAGE_CONFLICT:
878 s = pool_id2solvable(pool, source);
879 s2 = pool_id2solvable(pool, target);
880 ret = str::form (_("%s conflicts with %s provided by %s"), solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2));
882 case SOLVER_PROBLEM_PACKAGE_OBSOLETES:
883 s = pool_id2solvable(pool, source);
884 s2 = pool_id2solvable(pool, target);
885 ret = str::form (_("%s obsoletes %s provided by %s"), solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2));
887 case SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE:
888 ignoreId = source; // for setting weak dependencies
889 s = pool_id2solvable(pool, source);
891 sat::WhatProvides possibleProviders(cap);
893 // check, if a provider will be deleted
894 typedef list<PoolItem> ProviderList;
895 ProviderList providerlistInstalled, providerlistUninstalled;
896 for_( iter1, possibleProviders.begin(), possibleProviders.end() ) {
897 PoolItem provider1 = ResPool::instance().find( *iter1 );
898 // find pair of an installed/uninstalled item with the same NVR
900 for_( iter2, possibleProviders.begin(), possibleProviders.end() ) {
901 PoolItem provider2 = ResPool::instance().find( *iter2 );
902 if (compareByNVR (provider1.resolvable(),provider2.resolvable()) == 0
903 && ( (provider1.status().isInstalled() && provider2.status().isUninstalled())
904 || (provider2.status().isInstalled() && provider1.status().isUninstalled()) )) {
910 if (provider1.status().isInstalled())
911 providerlistInstalled.push_back(provider1);
913 providerlistUninstalled.push_back(provider1);
917 ret = str::form (_("%s requires %s, but this requirement cannot be provided"), solvable2str(pool, s), dep2str(pool, dep));
918 if (providerlistInstalled.size() > 0) {
919 detail += _("deleted providers: ");
920 for (ProviderList::const_iterator iter = providerlistInstalled.begin(); iter != providerlistInstalled.end(); iter++) {
921 if (iter == providerlistInstalled.begin())
922 detail += itemToString (*iter, false);
924 detail += "\n " + itemToString (*iter, false);
927 if (providerlistUninstalled.size() > 0) {
928 if (detail.size() > 0)
929 detail += _("\nuninstallable providers: ");
931 detail = _("uninstallable providers: ");
932 for (ProviderList::const_iterator iter = providerlistUninstalled.begin(); iter != providerlistUninstalled.end(); iter++) {
933 if (iter == providerlistUninstalled.begin())
934 detail += itemToString (*iter, false);
936 detail += "\n " + itemToString (*iter, false);
946 SATResolver::problems ()
948 ResolverProblemList resolverProblems;
949 if (_solv && _solv->problems.count) {
950 Pool *pool = _solv->pool;
953 Id problem, solution, element;
956 MIL << "Encountered problems! Here are the solutions:\n" << endl;
959 while ((problem = solver_next_problem(_solv, problem)) != 0) {
960 MIL << "Problem " << pcnt++ << ":" << endl;
961 MIL << "====================================" << endl;
964 string whatString = SATprobleminfoString (problem,detail,ignorId);
965 MIL << whatString << endl;
966 MIL << "------------------------------------" << endl;
967 ResolverProblem_Ptr resolverProblem = new ResolverProblem (whatString, detail);
970 while ((solution = solver_next_solution(_solv, problem, solution)) != 0) {
972 ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi(resolverProblem);
973 while ((element = solver_next_solutionelement(_solv, problem, solution, element, &p, &rp)) != 0) {
975 /* job, rp is index into job queue */
976 what = _jobQueue.elements[rp];
977 switch (_jobQueue.elements[rp-1])
979 case SOLVER_INSTALL_SOLVABLE: {
980 s = pool->solvables + what;
981 PoolItem poolItem = _pool.find (sat::Solvable(what));
983 if (_solv->installed && s->repo == _solv->installed) {
984 problemSolution->addSingleAction (poolItem, REMOVE);
985 string description = str::form (_("do not keep %s installed"), solvable2str(pool, s) );
986 MIL << description << endl;
987 problemSolution->addDescription (description);
989 problemSolution->addSingleAction (poolItem, REMOVE);
990 string description = str::form (_("do not install %s"), solvable2str(pool, s));
991 MIL << description << endl;
992 problemSolution->addDescription (description);
995 ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << id2str(pool, s->name) << "-"
996 << id2str(pool, s->evr) << "." << id2str(pool, s->arch) << endl;
1000 case SOLVER_ERASE_SOLVABLE: {
1001 s = pool->solvables + what;
1002 PoolItem poolItem = _pool.find (sat::Solvable(what));
1004 if (_solv->installed && s->repo == _solv->installed) {
1005 problemSolution->addSingleAction (poolItem, KEEP);
1006 string description = str::form (_("keep %s"), solvable2str(pool, s));
1007 MIL << description << endl;
1008 problemSolution->addDescription (description);
1010 problemSolution->addSingleAction (poolItem, INSTALL);
1011 string description = str::form (_("do not forbid installation of %s"), solvable2str(pool, s));
1012 MIL << description << endl;
1013 problemSolution->addDescription (description);
1016 ERR << "SOLVER_ERASE_SOLVABLE: No item found for " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." <<
1017 id2str(pool, s->arch) << endl;
1021 case SOLVER_INSTALL_SOLVABLE_NAME:
1023 FindPackage info (problemSolution, KEEP);
1024 IdString ident( what );
1025 invokeOnEach( _pool.byIdentBegin( ident ),
1026 _pool.byIdentEnd( ident ),
1027 resfilter::ByUninstalled (),
1028 functor::functorRef<bool,PoolItem> (info) );
1029 string description = str::form (_("do not install %s"), ident.c_str() );
1030 MIL << description << endl;
1031 problemSolution->addDescription (description);
1034 case SOLVER_ERASE_SOLVABLE_NAME:
1036 FindPackage info (problemSolution, KEEP);
1037 IdString ident( what );
1038 invokeOnEach( _pool.byIdentBegin( ident ),
1039 _pool.byIdentEnd( ident ),
1040 functor::chain (resfilter::ByInstalled (), // ByInstalled
1041 resfilter::ByTransact ()), // will be deinstalled
1042 functor::functorRef<bool,PoolItem> (info) );
1043 string description = str::form (_("keep %s"), ident.c_str());
1044 MIL << description << endl;
1045 problemSolution->addDescription (description);
1048 case SOLVER_INSTALL_SOLVABLE_PROVIDES:
1051 FOR_PROVIDES(p, pp, what);
1053 PoolItem poolItem = _pool.find (sat::Solvable(p));
1054 if (poolItem.status().isToBeInstalled()
1055 || poolItem.status().staysUninstalled())
1056 problemSolution->addSingleAction (poolItem, KEEP);
1058 string description = str::form (_("do not ask to install a solvable providing %s"), dep2str(pool, what));
1059 MIL << description << endl;
1060 problemSolution->addDescription (description);
1063 case SOLVER_ERASE_SOLVABLE_PROVIDES:
1066 FOR_PROVIDES(p, pp, what);
1068 PoolItem poolItem = _pool.find (sat::Solvable(p));
1069 if (poolItem.status().isToBeUninstalled()
1070 || poolItem.status().staysInstalled())
1071 problemSolution->addSingleAction (poolItem, KEEP);
1073 string description = str::form (_("do not ask to delete all solvables providing %s"), dep2str(pool, what));
1074 MIL << description << endl;
1075 problemSolution->addDescription (description);
1078 case SOLVER_INSTALL_SOLVABLE_UPDATE:
1080 PoolItem poolItem = _pool.find (sat::Solvable(what));
1081 s = pool->solvables + what;
1083 if (_solv->installed && s->repo == _solv->installed) {
1084 problemSolution->addSingleAction (poolItem, KEEP);
1085 string description = str::form (_("do not install most recent version of %s"), solvable2str(pool, s));
1086 MIL << description << endl;
1087 problemSolution->addDescription (description);
1089 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE " << poolItem << " is not selected for installation" << endl;
1092 ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE: No item found for " << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." <<
1093 id2str(pool, s->arch) << endl;
1098 MIL << "- do something different" << endl;
1099 ERR << "No valid solution available" << endl;
1103 /* policy, replace p with rp */
1104 s = pool->solvables + p;
1105 sd = rp ? pool->solvables + rp : 0;
1107 PoolItem itemFrom = _pool.find (sat::Solvable(p));
1112 PoolItem itemTo = _pool.find (sat::Solvable(rp));
1113 if (itemFrom && itemTo) {
1114 problemSolution->addSingleAction (itemTo, INSTALL);
1116 if (evrcmp(pool, s->evr, sd->evr, EVRCMP_COMPARE ) > 0)
1118 string description = str::form (_("downgrade of %s to %s"), solvable2str(pool, s), solvable2str(pool, sd));
1119 MIL << description << endl;
1120 problemSolution->addDescription (description);
1123 if (!_solv->allowarchchange && s->name == sd->name && s->arch != sd->arch && policy_illegal_archchange(_solv, s, sd))
1125 string description = str::form (_("architecture change of %s to %s"), solvable2str(pool, s), solvable2str(pool, sd));
1126 MIL << description << endl;
1127 problemSolution->addDescription (description);
1130 if (!_solv->allowvendorchange && s->name == sd->name && s->vendor != sd->vendor && policy_illegal_vendorchange(_solv, s, sd))
1132 string description = str::form (_("install %s (with vendor change)\n %s\n-->\n %s") ,
1133 solvable2str(pool, sd) , id2str(pool, s->vendor),
1134 string(sd->vendor ? id2str(pool, sd->vendor) : " (no vendor) ").c_str() );
1135 MIL << description << endl;
1136 problemSolution->addDescription (description);
1140 string description = str::form (_("replacement of %s with %s"), solvable2str(pool, s), solvable2str(pool, sd));
1141 MIL << description << endl;
1142 problemSolution->addDescription (description);
1145 ERR << id2str(pool, s->name) << "-" << id2str(pool, s->evr) << "." << id2str(pool, s->arch)
1146 << " or " << id2str(pool, sd->name) << "-" << id2str(pool, sd->evr) << "." << id2str(pool, sd->arch) << " not found" << endl;
1152 string description = str::form (_("deinstallation of %s"), solvable2str(pool, s));
1153 MIL << description << endl;
1154 problemSolution->addDescription (description);
1155 problemSolution->addSingleAction (itemFrom, REMOVE);
1160 resolverProblem->addSolution (problemSolution,
1161 problemSolution->actionCount() > 1 ? true : false); // Solutions with more than 1 action will be shown first.
1162 MIL << "------------------------------------" << endl;
1166 // There is a possibility to ignore this error by setting weak dependencies
1167 PoolItem item = _pool.find (sat::Solvable(ignorId));
1168 ProblemSolutionIgnore *problemSolution = new ProblemSolutionIgnore(resolverProblem, item);
1169 resolverProblem->addSolution (problemSolution,
1170 false); // Solutions will be shown at the end
1174 resolverProblems.push_back (resolverProblem);
1177 return resolverProblems;
1181 SATResolver::applySolutions (const ProblemSolutionList & solutions)
1183 for (ProblemSolutionList::const_iterator iter = solutions.begin();
1184 iter != solutions.end(); ++iter) {
1185 ProblemSolution_Ptr solution = *iter;
1186 Resolver dummyResolver(_pool);
1187 if (!solution->apply (dummyResolver))
1194 ///////////////////////////////////////////////////////////////////
1195 };// namespace detail
1196 /////////////////////////////////////////////////////////////////////
1197 /////////////////////////////////////////////////////////////////////
1198 };// namespace solver
1199 ///////////////////////////////////////////////////////////////////////
1200 ///////////////////////////////////////////////////////////////////////
1202 /////////////////////////////////////////////////////////////////////////