libzypp  13.10.6
SATResolver.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* SATResolver.cc
3  *
4  * Copyright (C) 2000-2002 Ximian, Inc.
5  * Copyright (C) 2005 SUSE Linux Products GmbH
6  *
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.
10  *
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.
15  *
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
19  * 02111-1307, USA.
20  */
21 extern "C"
22 {
23 #include <solv/repo_solv.h>
24 #include <solv/poolarch.h>
25 #include <solv/evr.h>
26 #include <solv/poolvendor.h>
27 #include <solv/policy.h>
28 #include <solv/bitmap.h>
29 #include <solv/queue.h>
30 }
31 
33 #include "zypp/base/String.h"
34 #include "zypp/Product.h"
35 #include "zypp/Capability.h"
36 #include "zypp/ResStatus.h"
37 #include "zypp/VendorAttr.h"
38 #include "zypp/base/LogTools.h"
39 #include "zypp/base/String.h"
40 #include "zypp/base/Gettext.h"
41 #include "zypp/base/Algorithm.h"
42 #include "zypp/ResPool.h"
43 #include "zypp/ResFilters.h"
44 #include "zypp/ZConfig.h"
45 #include "zypp/sat/Pool.h"
46 #include "zypp/sat/WhatProvides.h"
47 #include "zypp/sat/WhatObsoletes.h"
54 #include "zypp/sat/Transaction.h"
55 #include "zypp/sat/Queue.h"
56 
58 namespace zypp
59 {
60  namespace solver
62  {
63  namespace detail
65  {
66 
67 using namespace std;
68 
69 IMPL_PTR_TYPE(SATResolver);
70 
71 #define MAYBE_CLEANDEPS (cleandepsOnRemove()?SOLVER_CLEANDEPS:0)
72 
73 //---------------------------------------------------------------------------
74 // Callbacks for SAT policies
75 //---------------------------------------------------------------------------
76 
77 int vendorCheck( Pool *pool, Solvable *solvable1, Solvable *solvable2 )
78 {
79  return VendorAttr::instance().equivalent( IdString(solvable1->vendor),
80  IdString(solvable2->vendor) ) ? 0 : 1;
81 }
82 
83 
84 inline std::string itemToString( const PoolItem & item )
85 {
86  if ( !item )
87  return std::string();
88 
89  sat::Solvable slv( item.satSolvable() );
90  std::string ret( slv.asString() ); // n-v-r.a
91  if ( ! slv.isSystem() )
92  {
93  ret += "[";
94  ret += slv.repository().alias();
95  ret += "]";
96  }
97  return ret;
98 }
99 
100 inline PoolItem getPoolItem( Id id_r )
101 {
102  PoolItem ret( (sat::Solvable( id_r )) );
103  if ( !ret && id_r )
104  INT << "id " << id_r << " not found in ZYPP pool." << endl;
105  return ret;
106 }
107 
108 //---------------------------------------------------------------------------
109 
110 std::ostream &
111 SATResolver::dumpOn( std::ostream & os ) const
112 {
113  os << "<resolver>" << endl;
114  if (_solv) {
115  // os << " fixsystem = " << _solv->fixsystem << endl;
116  // os << " updatesystem = " << _solv->updatesystem << endl;
117  os << " allowdowngrade = " << solver_get_flag(_solv, SOLVER_FLAG_ALLOW_DOWNGRADE) << endl;
118  os << " allowarchchange = " << solver_get_flag(_solv, SOLVER_FLAG_ALLOW_ARCHCHANGE) << endl;
119  os << " allowvendorchange = " << solver_get_flag(_solv, SOLVER_FLAG_ALLOW_VENDORCHANGE) << endl;
120  os << " allowuninstall = " << solver_get_flag(_solv, SOLVER_FLAG_ALLOW_UNINSTALL) << endl;
121  os << " noupdateprovide = " << solver_get_flag(_solv, SOLVER_FLAG_NO_UPDATEPROVIDE) << endl;
122  os << " dosplitprovides = " << solver_get_flag(_solv, SOLVER_FLAG_SPLITPROVIDES) << endl;
123  os << " onlyRequires = " << solver_get_flag(_solv, SOLVER_FLAG_IGNORE_RECOMMENDED) << endl;
124  os << " ignorealreadyrecommended = " << !solver_get_flag(_solv, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED) << endl;
125  os << " distupgrade = " << _distupgrade << endl;
126  os << " distupgrade_removeunsupported = " << _distupgrade_removeunsupported << endl;
127  os << " solveSrcPackages = " << _solveSrcPackages << endl;
128  os << " cleandepsOnRemove = " << _cleandepsOnRemove << endl;
129  } else {
130  os << "<NULL>";
131  }
132  return os << "<resolver/>" << endl;
133 }
134 
135 //---------------------------------------------------------------------------
136 
137 SATResolver::SATResolver (const ResPool & pool, Pool *SATPool)
138  : _pool (pool)
139  , _SATPool (SATPool)
140  , _solv(NULL)
141  , _fixsystem(false)
142  , _allowdowngrade(false)
143  , _allowarchchange(false)
144  , _allowvendorchange(ZConfig::instance().solver_allowVendorChange())
145  , _allowuninstall(false)
146  , _updatesystem(false)
147  , _noupdateprovide(false)
148  , _dosplitprovides(false)
149  , _onlyRequires(ZConfig::instance().solver_onlyRequires())
150  , _ignorealreadyrecommended(false)
151  , _distupgrade(false)
152  , _distupgrade_removeunsupported(false)
153  , _solveSrcPackages(false)
154  , _cleandepsOnRemove(ZConfig::instance().solver_cleandepsOnRemove())
155 {
156 }
157 
158 
160 {
161  solverEnd();
162 }
163 
164 //---------------------------------------------------------------------------
165 
166 ResPool
167 SATResolver::pool (void) const
168 {
169  return _pool;
170 }
171 
172 void
174 {
175  bool found = false;
176  for (PoolItemList::const_iterator iter = _items_to_remove.begin();
177  iter != _items_to_remove.end(); ++iter) {
178  if (*iter == item) {
179  _items_to_remove.remove(*iter);
180  found = true;
181  break;
182  }
183  }
184  if (!found) {
185  for (PoolItemList::const_iterator iter = _items_to_install.begin();
186  iter != _items_to_install.end(); ++iter) {
187  if (*iter == item) {
188  _items_to_install.remove(*iter);
189  found = true;
190  break;
191  }
192  }
193  }
194  if (!found) {
195  for (PoolItemList::const_iterator iter = _items_to_keep.begin();
196  iter != _items_to_keep.end(); ++iter) {
197  if (*iter == item) {
198  _items_to_keep.remove(*iter);
199  found = true;
200  break;
201  }
202  }
203  }
204  if (!found) {
205  for (PoolItemList::const_iterator iter = _items_to_lock.begin();
206  iter != _items_to_lock.end(); ++iter) {
207  if (*iter == item) {
208  _items_to_lock.remove(*iter);
209  found = true;
210  break;
211  }
212  }
213  }
214 }
215 
216 
217 void
219 {
220  resetItemTransaction (item);
221  _items_to_install.push_back (item);
222  _items_to_install.unique ();
223 }
224 
225 
226 void
228 {
229  for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
230  addPoolItemToInstall (*iter);
231  }
232 }
233 
234 
235 void
237 {
238  resetItemTransaction (item);
239  _items_to_remove.push_back (item);
240  _items_to_remove.unique ();
241 }
242 
243 
244 void
246 {
247  for (PoolItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
248  addPoolItemToRemove (*iter);
249  }
250 }
251 
252 void
254 {
255  resetItemTransaction (item);
256  _items_to_lock.push_back (item);
257  _items_to_lock.unique ();
258 }
259 
260 void
262 {
263  resetItemTransaction (item);
264  _items_to_keep.push_back (item);
265  _items_to_keep.unique ();
266 }
267 
268 //---------------------------------------------------------------------------
269 
270 // copy marked item from solution back to pool
271 // if data != NULL, set as APPL_LOW (from establishPool())
272 
273 static void
275 {
276  // resetting
277  item.status().resetTransact (causer);
278  item.status().resetWeak ();
279 
280  bool r;
281 
282  // installation/deletion
283  if (status.isToBeInstalled()) {
284  r = item.status().setToBeInstalled (causer);
285  _XDEBUG("SATSolutionToPool install returns " << item << ", " << r);
286  }
287  else if (status.isToBeUninstalledDueToUpgrade()) {
288  r = item.status().setToBeUninstalledDueToUpgrade (causer);
289  _XDEBUG("SATSolutionToPool upgrade returns " << item << ", " << r);
290  }
291  else if (status.isToBeUninstalled()) {
292  r = item.status().setToBeUninstalled (causer);
293  _XDEBUG("SATSolutionToPool remove returns " << item << ", " << r);
294  }
295 
296  return;
297 }
298 
299 //----------------------------------------------------------------------------
300 //----------------------------------------------------------------------------
301 // resolvePool
302 //----------------------------------------------------------------------------
303 //----------------------------------------------------------------------------
304 
305 //----------------------------------------------------------------------------
306 // Helper functions for the ZYPP-Pool
307 //----------------------------------------------------------------------------
308 
309 
310 //------------------------------------------------------------------------------------------------------------
311 // This function loops over the pool and grabs all items
312 // It clears all previous bySolver() states also
313 //
314 // Every toBeInstalled is passed to zypp::solver:detail::Resolver.addPoolItemToInstall()
315 // Every toBeUninstalled is passed to zypp::solver:detail::Resolver.addPoolItemToRemove()
316 //
317 // Solver results must be written back to the pool.
318 //------------------------------------------------------------------------------------------------------------
319 
320 
322 {
324 
326  : resolver (r)
327  { }
328 
329  bool operator()( PoolItem item ) // only transacts() items go here
330  {
331  ResStatus status = item.status();
332  bool by_solver = (status.isBySolver() || status.isByApplLow());
333 
334  if (by_solver) {
335  item.status().resetTransact( ResStatus::APPL_LOW );// clear any solver/establish transactions
336  return true; // back out here, dont re-queue former solver result
337  }
338 
339  if ( item.satSolvable().isKind<SrcPackage>() && ! resolver.solveSrcPackages() )
340  {
341  // Later we may continue on a per source package base.
342  return true; // dont process this source package.
343  }
344 
345  if (status.isToBeInstalled()) {
346  resolver.addPoolItemToInstall(item); // -> install!
347  }
348  else if (status.isToBeUninstalled()) {
349  resolver.addPoolItemToRemove(item); // -> remove !
350  }
351  else if (status.isLocked()
352  && !by_solver) {
354  }
355  else if (status.isKept()
356  && !by_solver) {
358  }
359 
360  return true;
361  }
362 };
363 
364 
365 //----------------------------------------------------------------------------
366 //----------------------------------------------------------------------------
367 // solving.....
368 //----------------------------------------------------------------------------
369 //----------------------------------------------------------------------------
370 
371 
373 {
374  public:
378 
380  : is_updated( false )
381  , multiversion( installed_r.multiversionInstall() )
382  , _installed( installed_r )
383  {}
384 
385  // check this item will be updated
386 
387  bool operator()( PoolItem item )
388  {
389  if ( item.status().isToBeInstalled() )
390  {
391  if ( ! multiversion || sameNVRA( _installed, item ) )
392  {
393  is_updated = true;
394  return false;
395  }
396  }
397  return true;
398  }
399 };
400 
401 
403 {
404  public:
406 
407  CollectPseudoInstalled( Queue *queue )
408  :solvableQueue (queue)
409  {}
410 
411  // collecting PseudoInstalled items
412  bool operator()( PoolItem item )
413  {
414  if ( traits::isPseudoInstalled( item.satSolvable().kind() ) )
415  queue_push( solvableQueue, item.satSolvable().id() );
416  return true;
417  }
418 };
419 
420 bool
421 SATResolver::solving(const CapabilitySet & requires_caps,
422  const CapabilitySet & conflict_caps)
423 {
424  _solv = solver_create( _SATPool );
425  ::pool_set_custom_vendorcheck( _SATPool, &vendorCheck );
426  if (_fixsystem) {
427  queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL);
428  queue_push( &(_jobQueue), 0 );
429  }
430  if (_updatesystem) {
431  queue_push( &(_jobQueue), SOLVER_UPDATE|SOLVER_SOLVABLE_ALL);
432  queue_push( &(_jobQueue), 0 );
433  }
434  if (_distupgrade) {
435  queue_push( &(_jobQueue), SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL);
436  queue_push( &(_jobQueue), 0 );
437  }
439  queue_push( &(_jobQueue), SOLVER_DROP_ORPHANED|SOLVER_SOLVABLE_ALL);
440  queue_push( &(_jobQueue), 0 );
441  }
442  solver_set_flag(_solv, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended);
443  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade);
444  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
445  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange);
446  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange);
447  solver_set_flag(_solv, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
448  solver_set_flag(_solv, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
449  solver_set_flag(_solv, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
450 
452 
453  // Solve !
454  MIL << "Starting solving...." << endl;
455  MIL << *this;
456  solver_solve( _solv, &(_jobQueue) );
457  MIL << "....Solver end" << endl;
458 
459  // copying solution back to zypp pool
460  //-----------------------------------------
461  _result_items_to_install.clear();
462  _result_items_to_remove.clear();
463 
464  /* solvables to be installed */
465  Queue decisionq;
466  queue_init(&decisionq);
467  solver_get_decisionqueue(_solv, &decisionq);
468  for ( int i = 0; i < decisionq.count; ++i )
469  {
470  sat::Solvable slv( decisionq.elements[i] );
471  if ( !slv || slv.isSystem() )
472  continue;
473 
474  PoolItem poolItem( slv );
476  _result_items_to_install.push_back (poolItem);
477  }
478  queue_free(&decisionq);
479 
480  /* solvables to be erased */
481  Repository systemRepo( sat::Pool::instance().findSystemRepo() ); // don't create if it does not exist
482  if ( systemRepo && ! systemRepo.solvablesEmpty() )
483  {
484  bool mustCheckObsoletes = false;
485  for_( it, systemRepo.solvablesBegin(), systemRepo.solvablesEnd() )
486  {
487  if (solver_get_decisionlevel(_solv, it->id()) > 0)
488  continue;
489 
490  // Check if this is an update
491  CheckIfUpdate info( *it );
492  PoolItem poolItem( *it );
493  invokeOnEach( _pool.byIdentBegin( poolItem ),
494  _pool.byIdentEnd( poolItem ),
495  resfilter::ByUninstalled(), // ByUninstalled
496  functor::functorRef<bool,PoolItem> (info) );
497 
498  if (info.is_updated) {
500  } else {
502  if ( ! mustCheckObsoletes )
503  mustCheckObsoletes = true; // lazy check for UninstalledDueToObsolete
504  }
505  _result_items_to_remove.push_back (poolItem);
506  }
507  if ( mustCheckObsoletes )
508  {
510  for_( it, obsoleted.poolItemBegin(), obsoleted.poolItemEnd() )
511  {
512  ResStatus & status( it->status() );
513  // WhatObsoletes contains installed items only!
514  if ( status.transacts() && ! status.isToBeUninstalledDueToUpgrade() )
516  }
517  }
518  }
519 
520  Queue recommendations;
521  Queue suggestions;
522  Queue orphaned;
523  Queue unneeded;
524  queue_init(&recommendations);
525  queue_init(&suggestions);
526  queue_init(&orphaned);
527  queue_init(&unneeded);
528  solver_get_recommendations(_solv, &recommendations, &suggestions, 0);
529  solver_get_orphaned(_solv, &orphaned);
530  solver_get_unneeded(_solv, &unneeded, 1);
531  /* solvables which are recommended */
532  for ( int i = 0; i < recommendations.count; ++i )
533  {
534  PoolItem poolItem( getPoolItem( recommendations.elements[i] ) );
535  poolItem.status().setRecommended( true );
536  }
537 
538  /* solvables which are suggested */
539  for ( int i = 0; i < suggestions.count; ++i )
540  {
541  PoolItem poolItem( getPoolItem( suggestions.elements[i] ) );
542  poolItem.status().setSuggested( true );
543  }
544 
545  _problem_items.clear();
546  /* solvables which are orphaned */
547  for ( int i = 0; i < orphaned.count; ++i )
548  {
549  PoolItem poolItem( getPoolItem( orphaned.elements[i] ) );
550  poolItem.status().setOrphaned( true );
551  _problem_items.push_back( poolItem );
552  }
553 
554  /* solvables which are unneeded */
555  for ( int i = 0; i < unneeded.count; ++i )
556  {
557  PoolItem poolItem( getPoolItem( unneeded.elements[i] ) );
558  poolItem.status().setUnneeded( true );
559  }
560 
561  queue_free(&recommendations);
562  queue_free(&suggestions);
563  queue_free(&orphaned);
564  queue_free(&unneeded);
565 
566  /* Write validation state back to pool */
567  Queue flags, solvableQueue;
568 
569  queue_init(&flags);
570  queue_init(&solvableQueue);
571 
572  CollectPseudoInstalled collectPseudoInstalled(&solvableQueue);
574  _pool.end(),
575  functor::functorRef<bool,PoolItem> (collectPseudoInstalled) );
576  solver_trivial_installable(_solv, &solvableQueue, &flags );
577  for (int i = 0; i < solvableQueue.count; i++) {
578  PoolItem item = _pool.find (sat::Solvable(solvableQueue.elements[i]));
579  item.status().setUndetermined();
580 
581  if (flags.elements[i] == -1) {
582  item.status().setNonRelevant();
583  _XDEBUG("SATSolutionToPool(" << item << " ) nonRelevant !");
584  } else if (flags.elements[i] == 1) {
585  item.status().setSatisfied();
586  _XDEBUG("SATSolutionToPool(" << item << " ) satisfied !");
587  } else if (flags.elements[i] == 0) {
588  item.status().setBroken();
589  _XDEBUG("SATSolutionToPool(" << item << " ) broken !");
590  }
591  }
592  queue_free(&(solvableQueue));
593  queue_free(&flags);
594 
595 
596  // Solvables which were selected due requirements which have been made by the user will
597  // be selected by APPL_LOW. We can't use any higher level, because this setting must
598  // not serve as a request for the next solver run. APPL_LOW is reset before solving.
599  for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
600  sat::WhatProvides rpmProviders(*iter);
601  for_( iter2, rpmProviders.begin(), rpmProviders.end() ) {
602  PoolItem poolItem(*iter2);
603  if (poolItem.status().isToBeInstalled()) {
604  MIL << "User requirement " << *iter << " sets " << poolItem << endl;
606  }
607  }
608  }
609  for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
610  sat::WhatProvides rpmProviders(*iter);
611  for_( iter2, rpmProviders.begin(), rpmProviders.end() ) {
612  PoolItem poolItem(*iter2);
613  if (poolItem.status().isToBeUninstalled()) {
614  MIL << "User conflict " << *iter << " sets " << poolItem << endl;
616  }
617  }
618  }
619 
620  if (solver_problem_count(_solv) > 0 )
621  {
622  ERR << "Solverrun finished with an ERROR" << endl;
623  return false;
624  }
625 
626  return true;
627 }
628 
629 
630 void
632 {
633  SATCollectTransact info (*this);
634 
635  MIL << "SATResolver::solverInit()" << endl;
636 
637  // remove old stuff
638  solverEnd();
639 
640  queue_init( &_jobQueue );
641  _items_to_install.clear();
642  _items_to_remove.clear();
643  _items_to_lock.clear();
644  _items_to_keep.clear();
645 
647  functor::functorRef<bool,PoolItem>(info) );
648 
649  for (PoolItemList::const_iterator iter = weakItems.begin(); iter != weakItems.end(); iter++) {
650  Id id = (*iter)->satSolvable().id();
651  if (id == ID_NULL) {
652  ERR << "Weaken: " << *iter << " not found" << endl;
653  }
654  MIL << "Weaken dependencies of " << *iter << endl;
655  queue_push( &(_jobQueue), SOLVER_WEAKENDEPS | SOLVER_SOLVABLE );
656  queue_push( &(_jobQueue), id );
657  }
658 
659  // Add rules for parallel installable resolvables with different versions
660  for_( it, sat::Pool::instance().multiversionBegin(), sat::Pool::instance().multiversionEnd() )
661  {
662  queue_push( &(_jobQueue), SOLVER_NOOBSOLETES | SOLVER_SOLVABLE_NAME );
663  queue_push( &(_jobQueue), it->id() );
664  }
665 
666  if ( cleandepsOnRemove() )
667  {
668  // Add all items known to be installed by user request (not solver selected).
669  for_( it, sat::Pool::instance().onSystemByUserBegin(), sat::Pool::instance().onSystemByUserEnd() )
670  {
671  queue_push( &(_jobQueue), SOLVER_USERINSTALLED | SOLVER_SOLVABLE_NAME );
672  queue_push( &(_jobQueue), it->id() );
673  }
674  }
675 
676  if ( _distupgrade )
677  {
679  {
680  MIL << "Checking droplists ..." << endl;
681  // Dropped packages: look for 'weakremover()' provides
682  // in dup candidates of installed products.
683  ResPoolProxy proxy( ResPool::instance().proxy() );
684  for_( it, proxy.byKindBegin<Product>(), proxy.byKindEnd<Product>() )
685  {
686  if ( (*it)->onSystem() ) // (to install) or (not to delete)
687  {
688  Product::constPtr prodCand( (*it)->candidateAsKind<Product>() );
689  if ( ! prodCand )
690  continue; // product no longer available
691 
692  CapabilitySet droplist( prodCand->droplist() );
693  dumpRangeLine( MIL << "Droplist for " << (*it)->candidateObj() << ": " << droplist.size() << " ", droplist.begin(), droplist.end() ) << endl;
694  for_( cap, droplist.begin(), droplist.end() )
695  {
696  queue_push( &_jobQueue, SOLVER_DROP_ORPHANED | SOLVER_SOLVABLE_NAME );
697  queue_push( &_jobQueue, cap->id() );
698  }
699  }
700  }
701  }
702  else
703  {
704  MIL << "Droplist processing is disabled." << endl;
705  }
706  }
707 }
708 
709 void
711 {
712  // cleanup
713  if ( _solv )
714  {
715  solver_free(_solv);
716  _solv = NULL;
717  queue_free( &(_jobQueue) );
718  }
719 }
720 
721 
722 bool
724  const CapabilitySet & conflict_caps,
725  const PoolItemList & weakItems,
726  const std::set<Repository> & upgradeRepos)
727 {
728  MIL << "SATResolver::resolvePool()" << endl;
729 
730  // initialize
731  solverInit(weakItems);
732 
733  for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
734  Id id = (*iter)->satSolvable().id();
735  if (id == ID_NULL) {
736  ERR << "Install: " << *iter << " not found" << endl;
737  } else {
738  MIL << "Install " << *iter << endl;
739  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
740  queue_push( &(_jobQueue), id );
741  }
742  }
743 
744  for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
745  Id id = (*iter)->satSolvable().id();
746  if (id == ID_NULL) {
747  ERR << "Delete: " << *iter << " not found" << endl;
748  } else {
749  MIL << "Delete " << *iter << endl;
750  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE | MAYBE_CLEANDEPS );
751  queue_push( &(_jobQueue), id);
752  }
753  }
754 
755  for_( iter, upgradeRepos.begin(), upgradeRepos.end() )
756  {
757  queue_push( &(_jobQueue), SOLVER_DISTUPGRADE | SOLVER_SOLVABLE_REPO );
758  queue_push( &(_jobQueue), iter->get()->repoid );
759  MIL << "Upgrade repo " << *iter << endl;
760  }
761 
762  for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
763  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
764  queue_push( &(_jobQueue), iter->id() );
765  MIL << "Requires " << *iter << endl;
766  }
767 
768  for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
769  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS );
770  queue_push( &(_jobQueue), iter->id() );
771  MIL << "Conflicts " << *iter << endl;
772  }
773 
774  // set requirements for a running system
776 
777  // set locks for the solver
778  setLocks();
779 
780  // solving
781  bool ret = solving(requires_caps, conflict_caps);
782 
783  (ret?MIL:WAR) << "SATResolver::resolvePool() done. Ret:" << ret << endl;
784  return ret;
785 }
786 
787 
788 bool
790  const PoolItemList & weakItems)
791 {
792  MIL << "SATResolver::resolvQueue()" << endl;
793 
794  // initialize
795  solverInit(weakItems);
796 
797  // generate solver queue
798  for (SolverQueueItemList::const_iterator iter = requestQueue.begin(); iter != requestQueue.end(); iter++) {
799  (*iter)->addRule(_jobQueue);
800  }
801 
802  // Add addition item status to the resolve-queue cause these can be set by problem resolutions
803  for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
804  Id id = (*iter)->satSolvable().id();
805  if (id == ID_NULL) {
806  ERR << "Install: " << *iter << " not found" << endl;
807  } else {
808  MIL << "Install " << *iter << endl;
809  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
810  queue_push( &(_jobQueue), id );
811  }
812  }
813  for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
814  sat::detail::IdType ident( (*iter)->satSolvable().ident().id() );
815  MIL << "Delete " << *iter << ident << endl;
816  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | MAYBE_CLEANDEPS );
817  queue_push( &(_jobQueue), ident);
818  }
819 
820  // set requirements for a running system
822 
823  // set locks for the solver
824  setLocks();
825 
826  // solving
827  bool ret = solving();
828 
829  MIL << "SATResolver::resolveQueue() done. Ret:" << ret << endl;
830  return ret;
831 }
832 
835 {
836  MIL << "SATResolver::doUpdate()" << endl;
837 
838  // initialize
840 
841  // set requirements for a running system
843 
844  // set locks for the solver
845  setLocks();
846 
847  _solv = solver_create( _SATPool );
848  ::pool_set_custom_vendorcheck( _SATPool, &vendorCheck );
849  if (_fixsystem) {
850  queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL);
851  queue_push( &(_jobQueue), 0 );
852  }
853  if (1) {
854  queue_push( &(_jobQueue), SOLVER_UPDATE|SOLVER_SOLVABLE_ALL);
855  queue_push( &(_jobQueue), 0 );
856  }
857  if (_distupgrade) {
858  queue_push( &(_jobQueue), SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL);
859  queue_push( &(_jobQueue), 0 );
860  }
862  queue_push( &(_jobQueue), SOLVER_DROP_ORPHANED|SOLVER_SOLVABLE_ALL);
863  queue_push( &(_jobQueue), 0 );
864  }
865  solver_set_flag(_solv, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended);
866  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade);
867  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
868  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange);
869  solver_set_flag(_solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange);
870  solver_set_flag(_solv, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
871  solver_set_flag(_solv, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
872  solver_set_flag(_solv, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
873 
875 
876  // Solve !
877  MIL << "Starting solving for update...." << endl;
878  MIL << *this;
879  solver_solve( _solv, &(_jobQueue) );
880  MIL << "....Solver end" << endl;
881 
882  // copying solution back to zypp pool
883  //-----------------------------------------
884 
885  /* solvables to be installed */
886  Queue decisionq;
887  queue_init(&decisionq);
888  solver_get_decisionqueue(_solv, &decisionq);
889  for (int i = 0; i < decisionq.count; i++)
890  {
891  Id p;
892  p = decisionq.elements[i];
893  if (p < 0 || !sat::Solvable(p))
894  continue;
895  if (sat::Solvable(p).repository().get() == _solv->pool->installed)
896  continue;
897 
898  PoolItem poolItem = _pool.find (sat::Solvable(p));
899  if (poolItem) {
901  } else {
902  ERR << "id " << p << " not found in ZYPP pool." << endl;
903  }
904  }
905  queue_free(&decisionq);
906 
907  /* solvables to be erased */
908  for (int i = _solv->pool->installed->start; i < _solv->pool->installed->start + _solv->pool->installed->nsolvables; i++)
909  {
910  if (solver_get_decisionlevel(_solv, i) > 0)
911  continue;
912 
913  PoolItem poolItem( _pool.find( sat::Solvable(i) ) );
914  if (poolItem) {
915  // Check if this is an update
916  CheckIfUpdate info( (sat::Solvable(i)) );
917  invokeOnEach( _pool.byIdentBegin( poolItem ),
918  _pool.byIdentEnd( poolItem ),
919  resfilter::ByUninstalled(), // ByUninstalled
920  functor::functorRef<bool,PoolItem> (info) );
921 
922  if (info.is_updated) {
924  } else {
926  }
927  } else {
928  ERR << "id " << i << " not found in ZYPP pool." << endl;
929  }
930  }
931  MIL << "SATResolver::doUpdate() done" << endl;
932 }
933 
934 
935 
936 //----------------------------------------------------------------------------
937 //----------------------------------------------------------------------------
938 // error handling
939 //----------------------------------------------------------------------------
940 //----------------------------------------------------------------------------
941 
942 //----------------------------------------------------------------------------
943 // helper function
944 //----------------------------------------------------------------------------
945 
947 {
951  : problemSolution (p)
952  , action (act)
953  {
954  }
955 
957  {
959  return true;
960  }
961 };
962 
963 
964 //----------------------------------------------------------------------------
965 // Checking if this solvable/item has a buddy which reflect the real
966 // user visible description of an item
967 // e.g. The release package has a buddy to the concerning product item.
968 // This user want's the message "Product foo conflicts with product bar" and
969 // NOT "package release-foo conflicts with package release-bar"
970 // (ma: that's why we should map just packages to buddies, not vice versa)
971 //----------------------------------------------------------------------------
972 inline sat::Solvable mapBuddy( const PoolItem & item_r )
973 {
974  if ( item_r.satSolvable().isKind<Package>() )
975  {
976  sat::Solvable buddy = item_r.buddy();
977  if ( buddy )
978  return buddy;
979  }
980  return item_r.satSolvable();
981 }
983 { return mapBuddy( PoolItem( item_r ) ); }
984 
986 { return PoolItem( mapBuddy( item ) ); }
987 
989 { return mapBuddy( sat::Solvable(id) ); }
990 
991 string SATResolver::SATprobleminfoString(Id problem, string &detail, Id &ignoreId)
992 {
993  string ret;
994  Pool *pool = _solv->pool;
995  Id probr;
996  Id dep, source, target;
997  sat::Solvable s, s2;
998 
999  ignoreId = 0;
1000  probr = solver_findproblemrule(_solv, problem);
1001  switch (solver_ruleinfo(_solv, probr, &source, &target, &dep))
1002  {
1003  case SOLVER_RULE_DISTUPGRADE:
1004  s = mapSolvable (source);
1005  ret = str::form (_("%s does not belong to a distupgrade repository"), s.asString().c_str());
1006  break;
1007  case SOLVER_RULE_INFARCH:
1008  s = mapSolvable (source);
1009  ret = str::form (_("%s has inferior architecture"), s.asString().c_str());
1010  break;
1011  case SOLVER_RULE_UPDATE:
1012  s = mapSolvable (source);
1013  ret = str::form (_("problem with installed package %s"), s.asString().c_str());
1014  break;
1015  case SOLVER_RULE_JOB:
1016  ret = _("conflicting requests");
1017  break;
1018  case SOLVER_RULE_RPM:
1019  ret = _("some dependency problem");
1020  break;
1021  case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP:
1022  ret = str::form (_("nothing provides requested %s"), pool_dep2str(pool, dep));
1023  detail += _("Have you enabled all requested repositories?");
1024  break;
1025  case SOLVER_RULE_JOB_UNKNOWN_PACKAGE:
1026  ret = str::form (_("package %s does not exist"), pool_dep2str(pool, dep));
1027  detail += _("Have you enabled all requested repositories?");
1028  break;
1029  case SOLVER_RULE_JOB_UNSUPPORTED:
1030  ret = _("unsupported request");
1031  break;
1032  case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM:
1033  ret = str::form (_("%s is provided by the system and cannot be erased"), pool_dep2str(pool, dep));
1034  break;
1035  case SOLVER_RULE_RPM_NOT_INSTALLABLE:
1036  s = mapSolvable (source);
1037  ret = str::form (_("%s is not installable"), s.asString().c_str());
1038  break;
1039  case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP:
1040  ignoreId = source; // for setting weak dependencies
1041  s = mapSolvable (source);
1042  ret = str::form (_("nothing provides %s needed by %s"), pool_dep2str(pool, dep), s.asString().c_str());
1043  break;
1044  case SOLVER_RULE_RPM_SAME_NAME:
1045  s = mapSolvable (source);
1046  s2 = mapSolvable (target);
1047  ret = str::form (_("cannot install both %s and %s"), s.asString().c_str(), s2.asString().c_str());
1048  break;
1049  case SOLVER_RULE_RPM_PACKAGE_CONFLICT:
1050  s = mapSolvable (source);
1051  s2 = mapSolvable (target);
1052  ret = str::form (_("%s conflicts with %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str());
1053  break;
1054  case SOLVER_RULE_RPM_PACKAGE_OBSOLETES:
1055  s = mapSolvable (source);
1056  s2 = mapSolvable (target);
1057  ret = str::form (_("%s obsoletes %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str());
1058  break;
1059  case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES:
1060  s = mapSolvable (source);
1061  s2 = mapSolvable (target);
1062  ret = str::form (_("installed %s obsoletes %s provided by %s"), s.asString().c_str(), pool_dep2str(pool, dep), s2.asString().c_str());
1063  break;
1064  case SOLVER_RULE_RPM_SELF_CONFLICT:
1065  s = mapSolvable (source);
1066  ret = str::form (_("solvable %s conflicts with %s provided by itself"), s.asString().c_str(), pool_dep2str(pool, dep));
1067  break;
1068  case SOLVER_RULE_RPM_PACKAGE_REQUIRES:
1069  ignoreId = source; // for setting weak dependencies
1070  s = mapSolvable (source);
1071  Capability cap(dep);
1072  sat::WhatProvides possibleProviders(cap);
1073 
1074  // check, if a provider will be deleted
1075  typedef list<PoolItem> ProviderList;
1076  ProviderList providerlistInstalled, providerlistUninstalled;
1077  for_( iter1, possibleProviders.begin(), possibleProviders.end() ) {
1078  PoolItem provider1 = ResPool::instance().find( *iter1 );
1079  // find pair of an installed/uninstalled item with the same NVR
1080  bool found = false;
1081  for_( iter2, possibleProviders.begin(), possibleProviders.end() ) {
1082  PoolItem provider2 = ResPool::instance().find( *iter2 );
1083  if (compareByNVR (provider1.resolvable(),provider2.resolvable()) == 0
1084  && ( (provider1.status().isInstalled() && provider2.status().isUninstalled())
1085  || (provider2.status().isInstalled() && provider1.status().isUninstalled()) )) {
1086  found = true;
1087  break;
1088  }
1089  }
1090  if (!found) {
1091  if (provider1.status().isInstalled())
1092  providerlistInstalled.push_back(provider1);
1093  else
1094  providerlistUninstalled.push_back(provider1);
1095  }
1096  }
1097 
1098  ret = str::form (_("%s requires %s, but this requirement cannot be provided"), s.asString().c_str(), pool_dep2str(pool, dep));
1099  if (providerlistInstalled.size() > 0) {
1100  detail += _("deleted providers: ");
1101  for (ProviderList::const_iterator iter = providerlistInstalled.begin(); iter != providerlistInstalled.end(); iter++) {
1102  if (iter == providerlistInstalled.begin())
1103  detail += itemToString( *iter );
1104  else
1105  detail += "\n " + itemToString( mapItem(*iter) );
1106  }
1107  }
1108  if (providerlistUninstalled.size() > 0) {
1109  if (detail.size() > 0)
1110  detail += _("\nuninstallable providers: ");
1111  else
1112  detail = _("uninstallable providers: ");
1113  for (ProviderList::const_iterator iter = providerlistUninstalled.begin(); iter != providerlistUninstalled.end(); iter++) {
1114  if (iter == providerlistUninstalled.begin())
1115  detail += itemToString( *iter );
1116  else
1117  detail += "\n " + itemToString( mapItem(*iter) );
1118  }
1119  }
1120  break;
1121  }
1122 
1123  return ret;
1124 }
1125 
1128 {
1129  ResolverProblemList resolverProblems;
1130  if (_solv && solver_problem_count(_solv)) {
1131  Pool *pool = _solv->pool;
1132  int pcnt;
1133  Id p, rp, what;
1134  Id problem, solution, element;
1135  sat::Solvable s, sd;
1136 
1138  CapabilitySet system_conflicts = SystemCheck::instance().conflictSystemCap();
1139 
1140  MIL << "Encountered problems! Here are the solutions:\n" << endl;
1141  pcnt = 1;
1142  problem = 0;
1143  while ((problem = solver_next_problem(_solv, problem)) != 0) {
1144  MIL << "Problem " << pcnt++ << ":" << endl;
1145  MIL << "====================================" << endl;
1146  string detail;
1147  Id ignoreId;
1148  string whatString = SATprobleminfoString (problem,detail,ignoreId);
1149  MIL << whatString << endl;
1150  MIL << "------------------------------------" << endl;
1151  ResolverProblem_Ptr resolverProblem = new ResolverProblem (whatString, detail);
1152 
1153  solution = 0;
1154  while ((solution = solver_next_solution(_solv, problem, solution)) != 0) {
1155  element = 0;
1156  ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi(resolverProblem);
1157  while ((element = solver_next_solutionelement(_solv, problem, solution, element, &p, &rp)) != 0) {
1158  if (p == SOLVER_SOLUTION_JOB) {
1159  /* job, rp is index into job queue */
1160  what = _jobQueue.elements[rp];
1161  switch (_jobQueue.elements[rp-1]&(SOLVER_SELECTMASK|SOLVER_JOBMASK))
1162  {
1163  case SOLVER_INSTALL | SOLVER_SOLVABLE: {
1164  s = mapSolvable (what);
1165  PoolItem poolItem = _pool.find (s);
1166  if (poolItem) {
1167  if (pool->installed && s.get()->repo == pool->installed) {
1168  problemSolution->addSingleAction (poolItem, REMOVE);
1169  string description = str::form (_("do not keep %s installed"), s.asString().c_str() );
1170  MIL << description << endl;
1171  problemSolution->addDescription (description);
1172  } else {
1173  problemSolution->addSingleAction (poolItem, KEEP);
1174  string description = str::form (_("do not install %s"), s.asString().c_str());
1175  MIL << description << endl;
1176  problemSolution->addDescription (description);
1177  }
1178  } else {
1179  ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << s.asString() << endl;
1180  }
1181  }
1182  break;
1183  case SOLVER_ERASE | SOLVER_SOLVABLE: {
1184  s = mapSolvable (what);
1185  PoolItem poolItem = _pool.find (s);
1186  if (poolItem) {
1187  if (pool->installed && s.get()->repo == pool->installed) {
1188  problemSolution->addSingleAction (poolItem, KEEP);
1189  string description = str::form (_("keep %s"), s.asString().c_str());
1190  MIL << description << endl;
1191  problemSolution->addDescription (description);
1192  } else {
1193  problemSolution->addSingleAction (poolItem, UNLOCK);
1194  string description = str::form (_("do not forbid installation of %s"), itemToString( poolItem ).c_str());
1195  MIL << description << endl;
1196  problemSolution->addDescription (description);
1197  }
1198  } else {
1199  ERR << "SOLVER_ERASE_SOLVABLE: No item found for " << s.asString() << endl;
1200  }
1201  }
1202  break;
1203  case SOLVER_INSTALL | SOLVER_SOLVABLE_NAME:
1204  {
1205  IdString ident( what );
1206  SolverQueueItemInstall_Ptr install =
1207  new SolverQueueItemInstall(_pool, ident.asString(), false );
1208  problemSolution->addSingleAction (install, REMOVE_SOLVE_QUEUE_ITEM);
1209 
1210  string description = str::form (_("do not install %s"), ident.c_str() );
1211  MIL << description << endl;
1212  problemSolution->addDescription (description);
1213  }
1214  break;
1215  case SOLVER_ERASE | SOLVER_SOLVABLE_NAME:
1216  {
1217  // As we do not know, if this request has come from resolvePool or
1218  // resolveQueue we will have to take care for both cases.
1219  IdString ident( what );
1220  FindPackage info (problemSolution, KEEP);
1221  invokeOnEach( _pool.byIdentBegin( ident ),
1222  _pool.byIdentEnd( ident ),
1223  functor::chain (resfilter::ByInstalled (), // ByInstalled
1224  resfilter::ByTransact ()), // will be deinstalled
1225  functor::functorRef<bool,PoolItem> (info) );
1226 
1227  SolverQueueItemDelete_Ptr del =
1228  new SolverQueueItemDelete(_pool, ident.asString(), false );
1229  problemSolution->addSingleAction (del, REMOVE_SOLVE_QUEUE_ITEM);
1230 
1231  string description = str::form (_("keep %s"), ident.c_str());
1232  MIL << description << endl;
1233  problemSolution->addDescription (description);
1234  }
1235  break;
1236  case SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES:
1237  {
1238  problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_REQUIRE);
1239  string description = "";
1240 
1241  // Checking if this problem solution would break your system
1242  if (system_requires.find(Capability(what)) != system_requires.end()) {
1243  // Show a better warning
1244  resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() );
1245  resolverProblem->setDescription(_("This request will break your system!"));
1246  description = _("ignore the warning of a broken system");
1247  description += string(" (requires:")+pool_dep2str(pool, what)+")";
1248  MIL << description << endl;
1249  problemSolution->addFrontDescription (description);
1250  } else {
1251  description = str::form (_("do not ask to install a solvable providing %s"), pool_dep2str(pool, what));
1252  MIL << description << endl;
1253  problemSolution->addDescription (description);
1254  }
1255  }
1256  break;
1257  case SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES:
1258  {
1259  problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_CONFLICT);
1260  string description = "";
1261 
1262  // Checking if this problem solution would break your system
1263  if (system_conflicts.find(Capability(what)) != system_conflicts.end()) {
1264  // Show a better warning
1265  resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() );
1266  resolverProblem->setDescription(_("This request will break your system!"));
1267  description = _("ignore the warning of a broken system");
1268  description += string(" (conflicts:")+pool_dep2str(pool, what)+")";
1269  MIL << description << endl;
1270  problemSolution->addFrontDescription (description);
1271 
1272  } else {
1273  description = str::form (_("do not ask to delete all solvables providing %s"), pool_dep2str(pool, what));
1274  MIL << description << endl;
1275  problemSolution->addDescription (description);
1276  }
1277  }
1278  break;
1279  case SOLVER_UPDATE | SOLVER_SOLVABLE:
1280  {
1281  s = mapSolvable (what);
1282  PoolItem poolItem = _pool.find (s);
1283  if (poolItem) {
1284  if (pool->installed && s.get()->repo == pool->installed) {
1285  problemSolution->addSingleAction (poolItem, KEEP);
1286  string description = str::form (_("do not install most recent version of %s"), s.asString().c_str());
1287  MIL << description << endl;
1288  problemSolution->addDescription (description);
1289  } else {
1290  ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE " << poolItem << " is not selected for installation" << endl;
1291  }
1292  } else {
1293  ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE: No item found for " << s.asString() << endl;
1294  }
1295  }
1296  break;
1297  default:
1298  MIL << "- do something different" << endl;
1299  ERR << "No valid solution available" << endl;
1300  break;
1301  }
1302  } else if (p == SOLVER_SOLUTION_INFARCH) {
1303  s = mapSolvable (rp);
1304  PoolItem poolItem = _pool.find (s);
1305  if (pool->installed && s.get()->repo == pool->installed) {
1306  problemSolution->addSingleAction (poolItem, LOCK);
1307  string description = str::form (_("keep %s despite the inferior architecture"), s.asString().c_str());
1308  MIL << description << endl;
1309  problemSolution->addDescription (description);
1310  } else {
1311  problemSolution->addSingleAction (poolItem, INSTALL);
1312  string description = str::form (_("install %s despite the inferior architecture"), s.asString().c_str());
1313  MIL << description << endl;
1314  problemSolution->addDescription (description);
1315  }
1316  } else if (p == SOLVER_SOLUTION_DISTUPGRADE) {
1317  s = mapSolvable (rp);
1318  PoolItem poolItem = _pool.find (s);
1319  if (pool->installed && s.get()->repo == pool->installed) {
1320  problemSolution->addSingleAction (poolItem, LOCK);
1321  string description = str::form (_("keep obsolete %s"), s.asString().c_str());
1322  MIL << description << endl;
1323  problemSolution->addDescription (description);
1324  } else {
1325  problemSolution->addSingleAction (poolItem, INSTALL);
1326  string description = str::form (_("install %s from excluded repository"), s.asString().c_str());
1327  MIL << description << endl;
1328  problemSolution->addDescription (description);
1329  }
1330  } else {
1331  /* policy, replace p with rp */
1332  s = mapSolvable (p);
1333  PoolItem itemFrom = _pool.find (s);
1334  if (rp)
1335  {
1336  int gotone = 0;
1337 
1338  sd = mapSolvable (rp);
1339  PoolItem itemTo = _pool.find (sd);
1340  if (itemFrom && itemTo) {
1341  problemSolution->addSingleAction (itemTo, INSTALL);
1342  int illegal = policy_is_illegal(_solv, s.get(), sd.get(), 0);
1343 
1344  if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0)
1345  {
1346  string description = str::form (_("downgrade of %s to %s"), s.asString().c_str(), sd.asString().c_str());
1347  MIL << description << endl;
1348  problemSolution->addDescription (description);
1349  gotone = 1;
1350  }
1351  if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0)
1352  {
1353  string description = str::form (_("architecture change of %s to %s"), s.asString().c_str(), sd.asString().c_str());
1354  MIL << description << endl;
1355  problemSolution->addDescription (description);
1356  gotone = 1;
1357  }
1358  if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0)
1359  {
1360  IdString s_vendor( s.vendor() );
1361  IdString sd_vendor( sd.vendor() );
1362  string description = str::form (_("install %s (with vendor change)\n %s --> %s") ,
1363  sd.asString().c_str(),
1364  ( s_vendor ? s_vendor.c_str() : " (no vendor) " ),
1365  ( sd_vendor ? sd_vendor.c_str() : " (no vendor) " ) );
1366  MIL << description << endl;
1367  problemSolution->addDescription (description);
1368  gotone = 1;
1369  }
1370  if (!gotone) {
1371  string description = str::form (_("replacement of %s with %s"), s.asString().c_str(), sd.asString().c_str());
1372  MIL << description << endl;
1373  problemSolution->addDescription (description);
1374  }
1375  } else {
1376  ERR << s.asString() << " or " << sd.asString() << " not found" << endl;
1377  }
1378  }
1379  else
1380  {
1381  if (itemFrom) {
1382  string description = str::form (_("deinstallation of %s"), s.asString().c_str());
1383  MIL << description << endl;
1384  problemSolution->addDescription (description);
1385  problemSolution->addSingleAction (itemFrom, REMOVE);
1386  }
1387  }
1388  }
1389  }
1390  resolverProblem->addSolution (problemSolution,
1391  problemSolution->actionCount() > 1 ? true : false); // Solutions with more than 1 action will be shown first.
1392  MIL << "------------------------------------" << endl;
1393  }
1394 
1395  if (ignoreId > 0) {
1396  // There is a possibility to ignore this error by setting weak dependencies
1397  PoolItem item = _pool.find (sat::Solvable(ignoreId));
1398  ProblemSolutionIgnore *problemSolution = new ProblemSolutionIgnore(resolverProblem, item);
1399  resolverProblem->addSolution (problemSolution,
1400  false); // Solutions will be shown at the end
1401  MIL << "ignore some dependencies of " << item << endl;
1402  MIL << "------------------------------------" << endl;
1403  }
1404 
1405  // save problem
1406  resolverProblems.push_back (resolverProblem);
1407  }
1408  }
1409  return resolverProblems;
1410 }
1411 
1412 void
1414 {
1415  for (ProblemSolutionList::const_iterator iter = solutions.begin();
1416  iter != solutions.end(); ++iter) {
1417  ProblemSolution_Ptr solution = *iter;
1418  Resolver dummyResolver(_pool);
1419  if (!solution->apply (dummyResolver))
1420  break;
1421  }
1422 }
1423 
1425 {
1426  for (PoolItemList::const_iterator iter = _items_to_lock.begin(); iter != _items_to_lock.end(); ++iter) {
1427  sat::detail::SolvableIdType ident( (*iter)->satSolvable().id() );
1428  if (iter->status().isInstalled()) {
1429  MIL << "Lock installed item " << *iter << endl;
1430  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
1431  queue_push( &(_jobQueue), ident );
1432  } else {
1433  MIL << "Lock NOT installed item " << *iter << endl;
1434  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE | MAYBE_CLEANDEPS );
1435  queue_push( &(_jobQueue), ident );
1436  }
1437  }
1438 
1440  // Weak locks: Ignore if an item with this name is already installed.
1441  // If it's not installed try to keep it this way using a weak delete
1443  std::set<IdString> unifiedByName;
1444  for (PoolItemList::const_iterator iter = _items_to_keep.begin(); iter != _items_to_keep.end(); ++iter) {
1445  IdString ident( (*iter)->satSolvable().ident() );
1446  if ( unifiedByName.insert( ident ).second )
1447  {
1448  if ( ! ui::Selectable::get( *iter )->hasInstalledObj() )
1449  {
1450  MIL << "Keep NOT installed name " << ident << " (" << *iter << ")" << endl;
1451  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | SOLVER_WEAK | MAYBE_CLEANDEPS );
1452  queue_push( &(_jobQueue), ident.id() );
1453  }
1454  }
1455  }
1456 }
1457 
1459 {
1461  CapabilitySet system_conflicts = SystemCheck::instance().conflictSystemCap();
1462 
1463  for (CapabilitySet::const_iterator iter = system_requires.begin(); iter != system_requires.end(); ++iter) {
1464  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
1465  queue_push( &(_jobQueue), iter->id() );
1466  MIL << "SYSTEM Requires " << *iter << endl;
1467  }
1468 
1469  for (CapabilitySet::const_iterator iter = system_conflicts.begin(); iter != system_conflicts.end(); ++iter) {
1470  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS );
1471  queue_push( &(_jobQueue), iter->id() );
1472  MIL << "SYSTEM Conflicts " << *iter << endl;
1473  }
1474 
1475  // Lock the architecture of the running systems rpm
1476  // package on distupgrade.
1477  if ( _distupgrade && ZConfig::instance().systemRoot() == "/" )
1478  {
1480  IdString rpm( "rpm" );
1481  for_( it, pool.byIdentBegin(rpm), pool.byIdentEnd(rpm) )
1482  {
1483  if ( (*it)->isSystem() )
1484  {
1485  Capability archrule( (*it)->arch(), rpm.c_str(), Capability::PARSED );
1486  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_NAME | SOLVER_ESSENTIAL );
1487  queue_push( &(_jobQueue), archrule.id() );
1488 
1489  }
1490  }
1491  }
1492 }
1493 
1494 
1496 };// namespace detail
1499  };// namespace solver
1502 };// namespace zypp
1504 
Repository repository() const
The Repository this Solvable belongs to.
Definition: Solvable.cc:148
void addPoolItemToKeep(PoolItem item)
Definition: SATResolver.cc:261
bool setTransactByValue(TransactByValue causer)
Definition: ResStatus.h:293
bool isByApplLow() const
Definition: ResStatus.h:281
Interface to gettext.
std::list< ProblemSolution_Ptr > ProblemSolutionList
Definition: ProblemTypes.h:42
Product interface.
Definition: Product.h:32
#define MIL
Definition: Logger.h:47
int IdType
Generic Id type.
Definition: PoolMember.h:82
A Solvable object within the sat Pool.
Definition: Solvable.h:55
const_iterator begin() const
Definition: ResPool.h:85
Container of Solvable providing a Capability (read only).
Definition: WhatProvides.h:87
bool setUndetermined()
Definition: ResStatus.h:610
void addFrontDescription(const std::string &description)
Set description text (prepend)
std::string alias() const
Short unique string to identify a repo.
Definition: Repository.cc:57
bool isToBeUninstalledDueToUpgrade() const
Definition: ResStatus.h:306
static ZConfig & instance()
Singleton ctor.
Definition: ZConfig.cc:655
void addPoolItemsToInstallFromList(PoolItemList &rl)
Definition: SATResolver.cc:227
Class representing one possible solution to one problem found during resolving This problem solution ...
bool isToBeUninstalled() const
Definition: ResStatus.h:249
CheckIfUpdate(sat::Solvable installed_r)
Definition: SATResolver.cc:379
ProblemSolutionCombi * problemSolution
Definition: SATResolver.cc:948
const_iterator byKindBegin(const ResKind &kind_r) const
#define INT
Definition: Logger.h:51
static const ResStatus toBeInstalled
Definition: ResStatus.h:650
void addPoolItemToLock(PoolItem item)
Definition: SATResolver.cc:253
std::string asString() const
String representation &quot;ident-edition.arch&quot; or &quot;noSolvable&quot;.
Definition: Solvable.cc:506
bool isSystem() const
Return whether this Solvable belongs to the system repo.
Definition: Solvable.cc:154
bool isUninstalled() const
Definition: ResStatus.h:231
bool isLocked() const
Definition: ResStatus.h:252
bool isKept() const
Definition: ResStatus.h:261
unsigned SolvableIdType
Id type to connect Solvable and sat-solvable.
Definition: PoolMember.h:98
int invokeOnEach(_Iterator begin_r, _Iterator end_r, _Filter filter_r, _Function fnc_r)
Iterate through [begin_r,end_r) and invoke fnc_r on each item that passes filter_r.
Definition: Algorithm.h:30
SolvableIterator solvablesEnd() const
Iterator behind the last Solvable.
Definition: Repository.cc:169
::_Solvable * get() const
Expert backdoor.
Definition: Solvable.cc:124
void setOrphaned(bool toVal_r=true)
Definition: ResStatus.h:203
Access to the sat-pools string space.
Definition: IdString.h:39
void resetItemTransaction(PoolItem item)
Definition: SATResolver.cc:173
std::list< PoolItem > PoolItemList
Definition: Types.h:51
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:27
bool resetTransact(TransactByValue causer_r)
Not the same as setTransact( false ).
Definition: ResStatus.h:473
TraitsType::constPtrType constPtr
Definition: Product.h:38
const_iterator end() const
Definition: ResPool.h:88
std::list< SolverQueueItem_Ptr > SolverQueueItemList
byIdent_iterator byIdentEnd(const ByIdent &ident_r) const
Definition: ResPool.h:178
ResPool::instance().proxy();.
Definition: ResPoolProxy.h:34
static void SATSolutionToPool(PoolItem item, const ResStatus &status, const ResStatus::TransactByValue causer)
Definition: SATResolver.cc:274
std::tr1::unordered_set< Capability > CapabilitySet
Definition: Capability.h:33
bool solving(const CapabilitySet &requires_caps=CapabilitySet(), const CapabilitySet &conflict_caps=CapabilitySet())
Definition: SATResolver.cc:421
#define ERR
Definition: Logger.h:49
bool solverUpgradeRemoveDroppedPackages() const
Whether dist upgrade should remove a products dropped packages (true).
Definition: ZConfig.cc:885
bool setToBeUninstalledDueToUpgrade(TransactByValue causer)
Definition: ResStatus.h:557
Select PoolItem by installed.
Definition: ResFilters.h:287
void addPoolItemToRemove(PoolItem item)
Definition: SATResolver.cc:236
bool isInstalled() const
Definition: ResStatus.h:228
std::string SATprobleminfoString(Id problem, std::string &detail, Id &ignoreId)
Definition: SATResolver.cc:991
#define _XDEBUG(x)
Definition: Types.h:38
#define MAYBE_CLEANDEPS
Definition: SATResolver.cc:71
std::string asString() const
Conversion to std::string
Definition: IdString.h:83
static const ResStatus toBeUninstalledDueToUpgrade
Definition: ResStatus.h:652
std::unary_function< ResObject::constPtr, bool > ResObjectFilterFunctor
Definition: ResFilters.h:151
bool equivalent(const Vendor &lVendor, const Vendor &rVendor) const
Return whether two vendor strings shold be treated as the same vendor.
Definition: VendorAttr.cc:292
A mid layer class we should remove.
Definition: Resolver.h:101
ResObject::constPtr resolvable() const
Returns the ResObject::constPtr.
Definition: PoolItem.cc:280
int vendorCheck(Pool *pool, Solvable *solvable1, Solvable *solvable2)
Definition: SATResolver.cc:77
void addPoolItemToInstall(PoolItem item)
Definition: SATResolver.cc:218
std::list< ResolverProblem_Ptr > ResolverProblemList
Definition: ProblemTypes.h:46
static Pool instance()
Singleton ctor.
Definition: Pool.h:51
SolvableIterator solvablesBegin() const
Iterator to the first Solvable.
Definition: Repository.cc:159
const_iterator begin() const
Iterator pointing to the first Solvable.
const_iterator byKindEnd(const ResKind &kind_r) const
void addSingleAction(PoolItem item, const TransactionKind action)
Add a single action of an item.
sat::Solvable mapSolvable(const Id &id)
Definition: SATResolver.cc:988
const_iterator end() const
Iterator pointing behind the last Solvable.
Definition: WhatProvides.h:226
Package interface.
Definition: Package.h:32
std::unary_function< PoolItem, bool > PoolItemFilterFunctor
Definition: ResFilters.h:284
Interim helper class to collect global options and settings.
Definition: ZConfig.h:58
#define WAR
Definition: Logger.h:48
Class representing one possible solution to one problem found during resolving This problem solution ...
bool setBroken()
Definition: ResStatus.h:622
ResStatus & status() const
Returns the current status.
Definition: PoolItem.cc:241
Chain< _ACondition, _BCondition > chain(_ACondition conda_r, _BCondition condb_r)
Convenience function for creating a Chain from two conditions conda_r and condb_r.
Definition: Functional.h:348
bool setNonRelevant()
Definition: ResStatus.h:628
#define _(MSG)
Return translated text.
Definition: Gettext.h:21
bool isPseudoInstalled(ResKind kind_r)
Those are denoted to be installed, if the solver verifies them as being satisfied.
Definition: ResTraits.h:28
void addPoolItemsToRemoveFromList(PoolItemList &rl)
Definition: SATResolver.cc:245
void applySolutions(const ProblemSolutionList &solutions)
Container of installed Solvable which would be obsoleted by the Solvable passed to the ctor...
Definition: WhatObsoletes.h:36
static const SystemCheck & instance()
Singleton.
Definition: SystemCheck.cc:38
bool solvablesEmpty() const
Whether Repository contains solvables.
Definition: Repository.cc:147
const char * c_str() const
Conversion to const char *
Definition: IdString.cc:42
bool setToBeUninstalled(TransactByValue causer)
Definition: ResStatus.h:533
FindPackage(ProblemSolutionCombi *p, const TransactionKind act)
Definition: SATResolver.cc:950
std::ostream & dumpRangeLine(std::ostream &str, _Iterator begin, _Iterator end)
Print range defined by iterators (single line style).
Definition: LogTools.h:114
const CapabilitySet & conflictSystemCap() const
Returns a list of conflicting system capabilities.
Definition: SystemCheck.cc:67
Select PoolItem by transact.
Definition: ResFilters.h:306
void addDescription(const std::string description)
Set description text (append)
Select PoolItem by uninstalled.
Definition: ResFilters.h:297
bool resolveQueue(const SolverQueueItemList &requestQueue, const PoolItemList &weakItems)
Definition: SATResolver.cc:789
std::string form(const char *format,...)
Printf style construction of std::string.
Definition: String.cc:34
SATResolver(const ResPool &pool, Pool *SATPool)
Definition: SATResolver.cc:137
IdString vendor() const
Definition: Solvable.cc:397
ResKind kind() const
Definition: Solvable.cc:298
static Ptr get(const pool::ByIdent &ident_r)
Get the Selctable.
Definition: Selectable.cc:28
SrcPackage interface.
Definition: SrcPackage.h:29
sat::Solvable buddy() const
Return the buddy we share our status object with.
Definition: PoolItem.cc:247
Global ResObject pool.
Definition: ResPool.h:48
Pathname systemRoot() const
The target root directory.
Definition: ZConfig.cc:680
TransactionKind
A problem solution action that performs a transaction (installs, removes, keep ...) one resolvable (package, patch, pattern, product).
PoolItem getPoolItem(Id id_r)
Definition: SATResolver.cc:100
void setRecommended(bool toVal_r=true)
Definition: ResStatus.h:197
const CapabilitySet & requiredSystemCap() const
Returns a list of required system capabilities.
Definition: SystemCheck.cc:63
bool isToBeInstalled() const
Definition: ResStatus.h:241
A sat capability.
Definition: Capability.h:59
bool resolvePool(const CapabilitySet &requires_caps, const CapabilitySet &conflict_caps, const PoolItemList &weakItems, const std::set< Repository > &upgradeRepos)
Definition: SATResolver.cc:723
IMPL_PTR_TYPE(ProblemSolutionCombi)
void solverInit(const PoolItemList &weakItems)
Definition: SATResolver.cc:631
int actionCount()
returns the number of actions
sat::Solvable satSolvable() const
Return the corresponding sat::Solvable.
Definition: PoolItem.h:114
bool setToBeInstalled(TransactByValue causer)
Definition: ResStatus.h:519
sat::Solvable mapBuddy(const PoolItem &item_r)
Definition: SATResolver.cc:972
Status bitfield.
Definition: ResStatus.h:53
PoolItem mapItem(const PoolItem &item)
Definition: SATResolver.cc:985
Reference to a PoolItem connecting ResObject and ResStatus.
Definition: PoolItem.h:50
IdType id() const
Expert backdoor.
Definition: Solvable.h:296
void resetWeak()
Definition: ResStatus.h:194
PoolItem find(const sat::Solvable &slv_r) const
Return the corresponding PoolItem.
Definition: ResPool.cc:70
virtual std::ostream & dumpOn(std::ostream &str) const
Overload to realize std::ostream &amp; operator&lt;&lt;.
Definition: SATResolver.cc:111
static const VendorAttr & instance()
Singleton.
Definition: VendorAttr.cc:123
void setUnneeded(bool toVal_r=true)
Definition: ResStatus.h:206
bool isBySolver() const
Definition: ResStatus.h:278
bool isKind(const ResKind &kind_r) const
Test whether a Solvable is of a certain ResKind.
Definition: Solvable.cc:337
std::string itemToString(const PoolItem &item)
Definition: SATResolver.cc:84
bool setSatisfied()
Definition: ResStatus.h:616
byIdent_iterator byIdentBegin(const ByIdent &ident_r) const
Definition: ResPool.h:147
static const ResStatus toBeUninstalled
Definition: ResStatus.h:651
bool setToBeUninstalledDueToObsolete()
Definition: ResStatus.h:550
ResolverProblemList problems()
void prepareForSolving() const
prepare plus some expensive checks done before solving only.
Definition: Pool.cc:48
void setSuggested(bool toVal_r=true)
Definition: ResStatus.h:200
static ResPool instance()
Singleton ctor.
Definition: ResPool.cc:33