libzypp  17.35.14
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 
32 #define ZYPP_USE_RESOLVER_INTERNALS
33 
34 #include <zypp/base/LogTools.h>
35 #include <zypp/base/Gettext.h>
36 #include <zypp/base/Algorithm.h>
37 
38 #include <zypp/ZConfig.h>
39 #include <zypp/Product.h>
40 #include <zypp/AutoDispose.h>
41 #include <zypp/sat/WhatProvides.h>
42 #include <zypp/sat/WhatObsoletes.h>
44 
47 
55 
56 #include <utility>
57 using std::endl;
58 
59 #define XDEBUG(x) do { if (base::logger::isExcessive()) XXX << x << std::endl;} while (0)
60 
61 #undef ZYPP_BASE_LOGGER_LOGGROUP
62 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::solver"
63 
65 namespace zypp
66 {
67  namespace solver
69  {
70  namespace detail
72  {
73 
75  namespace
76  {
77  inline void solverSetFocus( sat::detail::CSolver & satSolver_r, const ResolverFocus & focus_r )
78  {
79  switch ( focus_r )
80  {
81  case ResolverFocus::Default: // fallthrough to Job
82  case ResolverFocus::Job:
83  solver_set_flag( &satSolver_r, SOLVER_FLAG_FOCUS_INSTALLED, 0 );
84  solver_set_flag( &satSolver_r, SOLVER_FLAG_FOCUS_BEST, 0 );
85  break;
87  solver_set_flag( &satSolver_r, SOLVER_FLAG_FOCUS_INSTALLED, 1 );
88  solver_set_flag( &satSolver_r, SOLVER_FLAG_FOCUS_BEST, 0 );
89  break;
91  solver_set_flag( &satSolver_r, SOLVER_FLAG_FOCUS_INSTALLED, 0 );
92  solver_set_flag( &satSolver_r, SOLVER_FLAG_FOCUS_BEST, 1 );
93  break;
94  }
95  }
96 
100  inline sat::Queue collectPseudoInstalled( const ResPool & pool_r )
101  {
102  sat::Queue ret;
103  for ( const PoolItem & pi : pool_r )
104  if ( traits::isPseudoInstalled( pi.kind() ) ) ret.push( pi.id() );
105  return ret;
106  }
107 
111  inline void solverCopyBackWeak( sat::detail::CSolver & satSolver_r, PoolItemList & orphanedItems_r )
112  {
113  // NOTE: assert all items weak stati are reset (resetWeak was called)
114  {
115  sat::Queue recommendations;
116  sat::Queue suggestions;
117  ::solver_get_recommendations( &satSolver_r, recommendations, suggestions, 0 );
118  for ( sat::Queue::size_type i = 0; i < recommendations.size(); ++i )
119  PoolItem(sat::Solvable(recommendations[i])).status().setRecommended( true );
120  for ( sat::Queue::size_type i = 0; i < suggestions.size(); ++i )
121  PoolItem(sat::Solvable(suggestions[i])).status().setSuggested( true );
122  }
123  {
124  orphanedItems_r.clear(); // cached on the fly
125  sat::Queue orphaned;
126  ::solver_get_orphaned( &satSolver_r, orphaned );
127  for ( sat::Queue::size_type i = 0; i < orphaned.size(); ++i )
128  {
129  PoolItem pi { sat::Solvable(orphaned[i]) };
130  pi.status().setOrphaned( true );
131  orphanedItems_r.push_back( pi );
132  }
133  }
134  {
135  sat::Queue unneeded;
136  ::solver_get_unneeded( &satSolver_r, unneeded, 1 );
137  for ( sat::Queue::size_type i = 0; i < unneeded.size(); ++i )
138  PoolItem(sat::Solvable(unneeded[i])).status().setUnneeded( true );
139  }
140  }
141 
143  inline void solverCopyBackValidate( sat::detail::CSolver & satSolver_r, const ResPool & pool_r )
144  {
145  sat::Queue pseudoItems { collectPseudoInstalled( pool_r ) };
146  if ( ! pseudoItems.empty() )
147  {
148  sat::Queue pseudoFlags;
149  ::solver_trivial_installable( &satSolver_r, pseudoItems, pseudoFlags );
150 
151  for ( sat::Queue::size_type i = 0; i < pseudoItems.size(); ++i )
152  {
153  PoolItem pi { sat::Solvable(pseudoItems[i]) };
154  switch ( pseudoFlags[i] )
155  {
156  case 0: pi.status().setBroken(); break;
157  case 1: pi.status().setSatisfied(); break;
158  case -1: pi.status().setNonRelevant(); break;
159  default: pi.status().setUndetermined(); break;
160  }
161  }
162  }
163  }
164 
165  } //namespace
167 
168 
169 
170 IMPL_PTR_TYPE(SATResolver);
171 
172 #define MAYBE_CLEANDEPS (cleandepsOnRemove()?SOLVER_CLEANDEPS:0)
173 
174 //---------------------------------------------------------------------------
175 // Callbacks for SAT policies
176 //---------------------------------------------------------------------------
177 
178 int vendorCheck( sat::detail::CPool *pool, Solvable *solvable1, Solvable *solvable2 )
179 { return VendorAttr::instance().equivalent( IdString(solvable1->vendor), IdString(solvable2->vendor) ) ? 0 : 1; }
180 
181 int relaxedVendorCheck( sat::detail::CPool *pool, Solvable *solvable1, Solvable *solvable2 )
182 { return VendorAttr::instance().relaxedEquivalent( IdString(solvable1->vendor), IdString(solvable2->vendor) ) ? 0 : 1; }
183 
188 void establish( sat::Queue & pseudoItems_r, sat::Queue & pseudoFlags_r )
189 {
190  pseudoItems_r = collectPseudoInstalled( ResPool::instance() );
191  if ( ! pseudoItems_r.empty() )
192  {
193  auto satPool = sat::Pool::instance();
194  MIL << "Establish..." << endl;
195  sat::detail::CPool * cPool { satPool.get() };
196  ::pool_set_custom_vendorcheck( cPool, &vendorCheck );
197 
198  sat::Queue jobQueue;
199  // Add rules for parallel installable resolvables with different versions
200  for ( const sat::Solvable & solv : satPool.multiversion() )
201  {
202  jobQueue.push( SOLVER_NOOBSOLETES | SOLVER_SOLVABLE );
203  jobQueue.push( solv.id() );
204  }
205 
206  AutoDispose<sat::detail::CSolver*> cSolver { ::solver_create( cPool ), ::solver_free };
207  satPool.prepare();
208  if ( ::solver_solve( cSolver, jobQueue ) != 0 )
209  INT << "How can establish fail?" << endl;
210 
211  ::solver_trivial_installable( cSolver, pseudoItems_r, pseudoFlags_r );
212 
213  for ( sat::Queue::size_type i = 0; i < pseudoItems_r.size(); ++i )
214  {
215  PoolItem pi { sat::Solvable(pseudoItems_r[i]) };
216  switch ( pseudoFlags_r[i] )
217  {
218  case 0: pi.status().setBroken(); break;
219  case 1: pi.status().setSatisfied(); break;
220  case -1: pi.status().setNonRelevant(); break;
221  default: pi.status().setUndetermined(); break;
222  }
223  }
224  MIL << "Establish DONE" << endl;
225  }
226  else
227  MIL << "Establish not needed." << endl;
228 }
229 
230 inline std::string itemToString( const PoolItem & item )
231 {
232  if ( !item )
233  return std::string();
234 
235  sat::Solvable slv( item.satSolvable() );
236  std::string ret( slv.asString() ); // n-v-r.a
237  if ( ! slv.isSystem() )
238  {
239  ret += "[";
240  ret += slv.repository().alias();
241  ret += "]";
242  }
243  return ret;
244 }
245 
246 //---------------------------------------------------------------------------
247 
248 std::ostream &
249 SATResolver::dumpOn( std::ostream & os ) const
250 {
251  os << "<resolver>" << endl;
252  if (_satSolver) {
253 #define OUTS(X) os << " " << #X << "\t= " << solver_get_flag(_satSolver, SOLVER_FLAG_##X) << endl
254  OUTS( ALLOW_DOWNGRADE );
255  OUTS( ALLOW_ARCHCHANGE );
256  OUTS( ALLOW_VENDORCHANGE );
257  OUTS( ALLOW_NAMECHANGE );
258  OUTS( ALLOW_UNINSTALL );
259  OUTS( NO_UPDATEPROVIDE );
260  OUTS( SPLITPROVIDES );
261  OUTS( ONLY_NAMESPACE_RECOMMENDED );
262  OUTS( ADD_ALREADY_RECOMMENDED );
263  OUTS( NO_INFARCHCHECK );
264  OUTS( KEEP_EXPLICIT_OBSOLETES );
265  OUTS( BEST_OBEY_POLICY );
266  OUTS( NO_AUTOTARGET );
267  OUTS( DUP_ALLOW_DOWNGRADE );
268  OUTS( DUP_ALLOW_ARCHCHANGE );
269  OUTS( DUP_ALLOW_VENDORCHANGE );
270  OUTS( DUP_ALLOW_NAMECHANGE );
271  OUTS( KEEP_ORPHANS );
272  OUTS( BREAK_ORPHANS );
273  OUTS( YUM_OBSOLETES );
274 #undef OUTS
275  os << " focus = " << _focus << endl;
276  os << " distupgrade = " << _distupgrade << endl;
277  os << " removeOrphaned = " << _removeOrphaned << endl;
278  os << " solveSrcPackages = " << _solveSrcPackages << endl;
279  os << " cleandepsOnRemove = " << _cleandepsOnRemove << endl;
280  os << " fixsystem = " << _fixsystem << endl;
281  } else {
282  os << "<NULL>";
283  }
284  return os << "<resolver/>" << endl;
285 }
286 
287 //---------------------------------------------------------------------------
288 
289 // NOTE: flag defaults must be in sync with ZVARDEFAULT in Resolver.cc
290 SATResolver::SATResolver (ResPool pool, sat::detail::CPool *satPool)
291  : _pool(std::move(pool))
292  , _satPool(satPool)
293  , _satSolver(NULL)
294  , _focus ( ZConfig::instance().solver_focus() )
295  , _fixsystem(false)
296  , _allowdowngrade ( false )
297  , _allownamechange ( true ) // bsc#1071466
298  , _allowarchchange ( false )
299  , _allowvendorchange ( ZConfig::instance().solver_allowVendorChange() )
300  , _allowuninstall ( false )
301  , _updatesystem(false)
302  , _noupdateprovide ( false )
303  , _dosplitprovides ( true )
304  , _onlyRequires (ZConfig::instance().solver_onlyRequires())
305  , _ignorealreadyrecommended(true)
306  , _distupgrade(false)
307  , _removeOrphaned(false)
308  , _removeUnneeded(false)
309  , _dup_allowdowngrade ( ZConfig::instance().solver_dupAllowDowngrade() )
310  , _dup_allownamechange ( ZConfig::instance().solver_dupAllowNameChange() )
311  , _dup_allowarchchange ( ZConfig::instance().solver_dupAllowArchChange() )
312  , _dup_allowvendorchange ( ZConfig::instance().solver_dupAllowVendorChange() )
313  , _solveSrcPackages(false)
314  , _cleandepsOnRemove(ZConfig::instance().solver_cleandepsOnRemove())
315 {
316 }
317 
318 
319 SATResolver::~SATResolver()
320 {
321  solverEnd();
322 }
323 
324 //---------------------------------------------------------------------------
325 
326 ResPool
327 SATResolver::pool (void) const
328 {
329  return _pool;
330 }
331 
332 //---------------------------------------------------------------------------
333 
334 // copy marked item from solution back to pool
335 // if data != NULL, set as APPL_LOW (from establishPool())
336 
337 static void
338 SATSolutionToPool (const PoolItem& item, const ResStatus & status, const ResStatus::TransactByValue causer)
339 {
340  // resetting
341  item.status().resetTransact (causer);
342  item.status().resetWeak ();
343 
344  bool r = false;
345 
346  // installation/deletion
347  if (status.isToBeInstalled()) {
348  r = item.status().setToBeInstalled (causer);
349  XDEBUG("SATSolutionToPool install returns " << item << ", " << r);
350  }
351  else if (status.isToBeUninstalledDueToUpgrade()) {
352  r = item.status().setToBeUninstalledDueToUpgrade (causer);
353  XDEBUG("SATSolutionToPool upgrade returns " << item << ", " << r);
354  }
355  else if (status.isToBeUninstalled()) {
356  r = item.status().setToBeUninstalled (causer);
357  XDEBUG("SATSolutionToPool remove returns " << item << ", " << r);
358  }
359 
360  return;
361 }
362 
363 //----------------------------------------------------------------------------
364 //----------------------------------------------------------------------------
365 // solverInit
366 //----------------------------------------------------------------------------
367 //----------------------------------------------------------------------------
376 {
377  SATCollectTransact( PoolItemList & items_to_install_r,
378  PoolItemList & items_to_remove_r,
379  PoolItemList & items_to_lock_r,
380  PoolItemList & items_to_keep_r,
381  bool solveSrcPackages_r )
382  : _items_to_install( items_to_install_r )
383  , _items_to_remove( items_to_remove_r )
384  , _items_to_lock( items_to_lock_r )
385  , _items_to_keep( items_to_keep_r )
386  , _solveSrcPackages( solveSrcPackages_r )
387  {
388  _items_to_install.clear();
389  _items_to_remove.clear();
390  _items_to_lock.clear();
391  _items_to_keep.clear();
392  }
393 
394  bool operator()( const PoolItem & item_r )
395  {
396 
397  ResStatus & itemStatus( item_r.status() );
398  bool by_solver = ( itemStatus.isBySolver() || itemStatus.isByApplLow() );
399 
400  if ( by_solver )
401  {
402  // Clear former solver/establish resultd
403  itemStatus.resetTransact( ResStatus::APPL_LOW );
404  return true; // -> back out here, don't re-queue former results
405  }
406 
407  if ( !_solveSrcPackages && item_r.isKind<SrcPackage>() )
408  {
409  // Later we may continue on a per source package base.
410  return true; // dont process this source package.
411  }
412 
413  switch ( itemStatus.getTransactValue() )
414  {
415  case ResStatus::TRANSACT:
416  itemStatus.isUninstalled() ? _items_to_install.push_back( item_r )
417  : _items_to_remove.push_back( item_r ); break;
418  case ResStatus::LOCKED: _items_to_lock.push_back( item_r ); break;
419  case ResStatus::KEEP_STATE: _items_to_keep.push_back( item_r ); break;
420  }
421  return true;
422  }
423 
424 private:
425  PoolItemList & _items_to_install;
426  PoolItemList & _items_to_remove;
427  PoolItemList & _items_to_lock;
428  PoolItemList & _items_to_keep;
430 
431 };
433 
434 void
435 SATResolver::solverEnd()
436 {
437  // cleanup
438  if ( _satSolver )
439  {
440  solver_free(_satSolver);
441  _satSolver = NULL;
442  queue_free( &(_jobQueue) );
443  }
444 }
445 
446 void
447 SATResolver::solverInit(const PoolItemList & weakItems)
448 {
449  MIL << "SATResolver::solverInit()" << endl;
450 
451  // Remove old stuff and create a new jobqueue
452  solverEnd();
453  _satSolver = solver_create( _satPool );
454  queue_init( &_jobQueue );
455 
456  {
457  // bsc#1182629: in dup allow an available -release package providing 'dup-vendor-relax(suse)'
458  // to let (suse/opensuse) vendor being treated as being equivalent.
459  bool toRelax = false;
460  if ( _distupgrade ) {
461  for ( sat::Solvable solv : sat::WhatProvides( Capability("dup-vendor-relax(suse)") ) ) {
462  if ( ! solv.isSystem() ) {
463  MIL << "Relaxed vendor check requested by " << solv << endl;
464  toRelax = true;
465  break;
466  }
467  }
468  }
469  ::pool_set_custom_vendorcheck( _satPool, toRelax ? &relaxedVendorCheck : &vendorCheck );
470  }
471 
472  // Add rules for user/auto installed packages
473  ::pool_add_userinstalled_jobs(_satPool, sat::Pool::instance().autoInstalled(), &(_jobQueue), GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED);
474 
475  // Collect PoolItem's tasks and cleanup Pool for solving.
476  // Todos are kept in _items_to_install, _items_to_remove, _items_to_lock, _items_to_keep
477  {
478  SATCollectTransact collector( _items_to_install, _items_to_remove, _items_to_lock, _items_to_keep, solveSrcPackages() );
479  invokeOnEach ( _pool.begin(), _pool.end(), std::ref( collector ) );
480  }
481 
482  // Add rules for previous ProblemSolutions "break %s by ignoring some of its dependencies"
483  for (PoolItemList::const_iterator iter = weakItems.begin(); iter != weakItems.end(); iter++) {
484  Id id = iter->id();
485  if (id == ID_NULL) {
486  ERR << "Weaken: " << *iter << " not found" << endl;
487  }
488  MIL << "Weaken dependencies of " << *iter << endl;
489  queue_push( &(_jobQueue), SOLVER_WEAKENDEPS | SOLVER_SOLVABLE );
490  queue_push( &(_jobQueue), id );
491  }
492 
493  // Add rules for retracted patches and packages
494  {
495  queue_push( &(_jobQueue), SOLVER_BLACKLIST|SOLVER_SOLVABLE_PROVIDES );
496  queue_push( &(_jobQueue), sat::Solvable::retractedToken.id() );
497  queue_push( &(_jobQueue), SOLVER_BLACKLIST|SOLVER_SOLVABLE_PROVIDES );
498  queue_push( &(_jobQueue), sat::Solvable::ptfMasterToken.id() );
499  // bsc#1186503: ptfPackageToken should not be blacklisted
500  }
501 
502  // Add rules for changed requestedLocales
503  {
504  const auto & trackedLocaleIds( myPool().trackedLocaleIds() );
505 
506  // just track changed locakes
507  for ( const auto & locale : trackedLocaleIds.added() )
508  {
509  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
510  queue_push( &(_jobQueue), Capability( ResolverNamespace::language, IdString(locale) ).id() );
511  }
512 
513  for ( const auto & locale : trackedLocaleIds.removed() )
514  {
515  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | SOLVER_CLEANDEPS ); // needs uncond. SOLVER_CLEANDEPS!
516  queue_push( &(_jobQueue), Capability( ResolverNamespace::language, IdString(locale) ).id() );
517  }
518  }
519 
520  // Add rules for parallel installable resolvables with different versions
521  for ( const sat::Solvable & solv : myPool().multiversionList() )
522  {
523  queue_push( &(_jobQueue), SOLVER_NOOBSOLETES | SOLVER_SOLVABLE );
524  queue_push( &(_jobQueue), solv.id() );
525  }
526 
527  // Add rules to protect PTF removal without repos (bsc#1203248)
528  // Removing a PTF its packages should be replaced by the official
529  // versions again. If just the system repo is present, they'd get
530  // removed instead.
531  {
532  _protectPTFs = sat::Pool::instance().reposSize() == 1;
533  if ( _protectPTFs ) {
534  for ( const auto & solv : sat::AllPTFs() ) {
535  if ( solv.isSystem() ) {
536  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
537  queue_push( &(_jobQueue), solv.id() );
538  }
539  }
540  }
541  }
542 
543  // set requirements for a running system
544  solverInitSetSystemRequirements();
545 
546  // set locks for the solver
547  solverInitSetLocks();
548 
549  // set mode (verify,up,dup) specific jobs and solver flags
550  solverInitSetModeJobsAndFlags();
551 }
552 
553 void SATResolver::solverInitSetSystemRequirements()
554 {
555  CapabilitySet system_requires = SystemCheck::instance().requiredSystemCap();
556  CapabilitySet system_conflicts = SystemCheck::instance().conflictSystemCap();
557 
558  for (CapabilitySet::const_iterator iter = system_requires.begin(); iter != system_requires.end(); ++iter) {
559  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
560  queue_push( &(_jobQueue), iter->id() );
561  MIL << "SYSTEM Requires " << *iter << endl;
562  }
563 
564  for (CapabilitySet::const_iterator iter = system_conflicts.begin(); iter != system_conflicts.end(); ++iter) {
565  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS );
566  queue_push( &(_jobQueue), iter->id() );
567  MIL << "SYSTEM Conflicts " << *iter << endl;
568  }
569 
570  // Lock the architecture of the running systems rpm
571  // package on distupgrade.
572  if ( _distupgrade && ZConfig::instance().systemRoot() == "/" )
573  {
574  ResPool pool( ResPool::instance() );
575  IdString rpm( "rpm" );
576  for_( it, pool.byIdentBegin(rpm), pool.byIdentEnd(rpm) )
577  {
578  if ( (*it)->isSystem() )
579  {
580  Capability archrule( (*it)->arch(), rpm.c_str(), Capability::PARSED );
581  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_NAME | SOLVER_ESSENTIAL );
582  queue_push( &(_jobQueue), archrule.id() );
583 
584  }
585  }
586  }
587 }
588 
589 void SATResolver::solverInitSetLocks()
590 {
591  unsigned icnt = 0;
592  unsigned acnt = 0;
593 
594  for (PoolItemList::const_iterator iter = _items_to_lock.begin(); iter != _items_to_lock.end(); ++iter) {
595  sat::detail::SolvableIdType id( iter->id() );
596  if (iter->status().isInstalled()) {
597  ++icnt;
598  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
599  queue_push( &(_jobQueue), id );
600  } else {
601  ++acnt;
602  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE | MAYBE_CLEANDEPS );
603  queue_push( &(_jobQueue), id );
604  }
605  }
606  MIL << "Locked " << icnt << " installed items and " << acnt << " NOT installed items." << endl;
607 
609  // Weak locks: Ignore if an item with this name is already installed.
610  // If it's not installed try to keep it this way using a weak delete
612  std::set<IdString> unifiedByName;
613  for (PoolItemList::const_iterator iter = _items_to_keep.begin(); iter != _items_to_keep.end(); ++iter) {
614  IdString ident( iter->ident() );
615  if ( unifiedByName.insert( ident ).second )
616  {
617  if ( ! ui::Selectable::get( *iter )->hasInstalledObj() )
618  {
619  MIL << "Keep NOT installed name " << ident << " (" << *iter << ")" << endl;
620  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | SOLVER_WEAK | MAYBE_CLEANDEPS );
621  queue_push( &(_jobQueue), ident.id() );
622  }
623  }
624  }
625 }
626 
627 void SATResolver::solverInitSetModeJobsAndFlags()
628 {
629  if (_fixsystem) {
630  queue_push( &(_jobQueue), SOLVER_VERIFY|SOLVER_SOLVABLE_ALL);
631  queue_push( &(_jobQueue), 0 );
632  }
633  if (_updatesystem) {
634  queue_push( &(_jobQueue), SOLVER_UPDATE|SOLVER_SOLVABLE_ALL);
635  queue_push( &(_jobQueue), 0 );
636  }
637  if (_distupgrade) {
638  queue_push( &(_jobQueue), SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL);
639  queue_push( &(_jobQueue), 0 );
640  // By now libsolv supports orphan handling just in dup.
641  // We keep it here in _distupgrade to make sure nothing bad happens
642  // in case libsolv changes and it's used in remove commands which
643  // have no repos enabled. I.e. everything would be orphaned.
644  if (_removeOrphaned) {
645  queue_push( &(_jobQueue), SOLVER_DROP_ORPHANED|SOLVER_SOLVABLE_ALL);
646  queue_push( &(_jobQueue), 0 );
647  }
648  }
649  if (_removeUnneeded) {
650  invokeOnEach ( _pool.begin(), _pool.end(), [this]( const PoolItem & pi_r ) {
651  if ( pi_r.status().isUnneeded() ) {
652  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_NAME | SOLVER_WEAK | MAYBE_CLEANDEPS );
653  queue_push( &(_jobQueue), pi_r.ident().id() );
654  }
655  return true;
656  } );
657  }
658 
659  solverSetFocus( *_satSolver, _focus );
660  solver_set_flag(_satSolver, SOLVER_FLAG_ADD_ALREADY_RECOMMENDED, !_ignorealreadyrecommended);
661  solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_DOWNGRADE, _allowdowngrade);
662  solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_NAMECHANGE, _allownamechange);
663  solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_ARCHCHANGE, _allowarchchange);
664  solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_VENDORCHANGE, _allowvendorchange);
665  solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
666  solver_set_flag(_satSolver, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
667  solver_set_flag(_satSolver, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
668  solver_set_flag(_satSolver, SOLVER_FLAG_IGNORE_RECOMMENDED, false); // resolve recommended namespaces
669  solver_set_flag(_satSolver, SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED, _onlyRequires); //
670  solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_DOWNGRADE, _dup_allowdowngrade );
671  solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_NAMECHANGE, _dup_allownamechange );
672  solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE, _dup_allowarchchange );
673  solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_VENDORCHANGE, _dup_allowvendorchange );
674 }
675 
676 //----------------------------------------------------------------------------
677 //----------------------------------------------------------------------------
678 // solving.....
679 //----------------------------------------------------------------------------
680 //----------------------------------------------------------------------------
681 
683 {
684  public:
687 
688  CheckIfUpdate( const sat::Solvable & installed_r )
689  : is_updated( false )
690  , _installed( installed_r )
691  {}
692 
693  // check this item will be updated
694 
695  bool operator()( const PoolItem & item )
696  {
697  if ( item.status().isToBeInstalled() )
698  {
699  if ( ! item.multiversionInstall() || sameNVRA( _installed, item ) )
700  {
701  is_updated = true;
702  return false;
703  }
704  }
705  return true;
706  }
707 };
708 
709 
710 bool
711 SATResolver::solving(const CapabilitySet & requires_caps,
712  const CapabilitySet & conflict_caps)
713 {
715 
716  // Solve !
717  MIL << "Starting solving...." << endl;
718  MIL << *this;
719  if ( solver_solve( _satSolver, &(_jobQueue) ) == 0 )
720  {
721  // bsc#1155819: Weakremovers of future product not evaluated.
722  // Do a 2nd run to cleanup weakremovers() of to be installed
723  // Produtcs unless removeunsupported is active (cleans up all).
724  if ( _distupgrade )
725  {
726  if ( _removeOrphaned )
727  MIL << "Droplist processing not needed. RemoveUnsupported is On." << endl;
728  else if ( ! ZConfig::instance().solverUpgradeRemoveDroppedPackages() )
729  MIL << "Droplist processing is disabled in ZConfig." << endl;
730  else
731  {
732  bool resolve = false;
733  MIL << "Checking droplists ..." << endl;
734  // get Solvables to be installed...
735  sat::SolvableQueue decisionq;
736  solver_get_decisionqueue( _satSolver, decisionq );
737  for ( sat::detail::IdType id : decisionq )
738  {
739  if ( id < 0 )
740  continue;
742  // get product buddies (they carry the weakremover)...
743  static const Capability productCap { "product()" };
744  if ( slv && slv.provides().matches( productCap ) )
745  {
746  CapabilitySet droplist { slv.valuesOfNamespace( "weakremover" ) };
747  MIL << "Droplist for " << slv << ": size " << droplist.size() << endl;
748  if ( !droplist.empty() )
749  {
750  for ( const auto & cap : droplist )
751  {
752  queue_push( &_jobQueue, SOLVER_DROP_ORPHANED | SOLVER_SOLVABLE_NAME );
753  queue_push( &_jobQueue, cap.id() );
754  }
755  // PIN product - a safety net to prevent cleanup from changing the decision for this product
756  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
757  queue_push( &(_jobQueue), id );
758  resolve = true;
759  }
760  }
761  }
762  if ( resolve )
763  solver_solve( _satSolver, &(_jobQueue) );
764  }
765  }
766  }
767  MIL << "....Solver end" << endl;
768 
769  // copying solution back to zypp pool
770  //-----------------------------------------
771  _result_items_to_install.clear();
772  _result_items_to_remove.clear();
773 
774  /* solvables to be installed */
775  Queue decisionq;
776  queue_init(&decisionq);
777  solver_get_decisionqueue(_satSolver, &decisionq);
778  for ( int i = 0; i < decisionq.count; ++i )
779  {
780  Id p = decisionq.elements[i];
781  if ( p < 0 )
782  continue;
783 
784  sat::Solvable slv { (sat::detail::SolvableIdType)p };
785  if ( ! slv || slv.isSystem() )
786  continue;
787 
788  PoolItem poolItem( slv );
790  _result_items_to_install.push_back( poolItem );
791  }
792  queue_free(&decisionq);
793 
794  /* solvables to be erased */
795  Repository systemRepo( sat::Pool::instance().findSystemRepo() ); // don't create if it does not exist
796  if ( systemRepo && ! systemRepo.solvablesEmpty() )
797  {
798  bool mustCheckObsoletes = false;
799  for_( it, systemRepo.solvablesBegin(), systemRepo.solvablesEnd() )
800  {
801  if (solver_get_decisionlevel(_satSolver, it->id()) > 0)
802  continue;
803 
804  // Check if this is an update
805  CheckIfUpdate info( *it );
806  PoolItem poolItem( *it );
807  invokeOnEach( _pool.byIdentBegin( poolItem ),
808  _pool.byIdentEnd( poolItem ),
809  resfilter::ByUninstalled(), // ByUninstalled
810  std::ref(info) );
811 
812  if (info.is_updated) {
814  } else {
816  if ( ! mustCheckObsoletes )
817  mustCheckObsoletes = true; // lazy check for UninstalledDueToObsolete
818  }
819  _result_items_to_remove.push_back (poolItem);
820  }
821  if ( mustCheckObsoletes )
822  {
823  sat::WhatObsoletes obsoleted( _result_items_to_install.begin(), _result_items_to_install.end() );
824  for_( it, obsoleted.poolItemBegin(), obsoleted.poolItemEnd() )
825  {
826  ResStatus & status( it->status() );
827  // WhatObsoletes contains installed items only!
828  if ( status.transacts() && ! status.isToBeUninstalledDueToUpgrade() )
829  status.setToBeUninstalledDueToObsolete();
830  }
831  }
832  }
833 
834  // copy back computed status values to pool
835  // (on the fly cache orphaned items for the UI)
836  solverCopyBackWeak( *_satSolver, _problem_items );
837  solverCopyBackValidate( *_satSolver, _pool );
838 
839  // Solvables which were selected due requirements which have been made by the user will
840  // be selected by APPL_LOW. We can't use any higher level, because this setting must
841  // not serve as a request for the next solver run. APPL_LOW is reset before solving.
842  for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
843  sat::WhatProvides rpmProviders(*iter);
844  for_( iter2, rpmProviders.begin(), rpmProviders.end() ) {
845  PoolItem poolItem(*iter2);
846  if (poolItem.status().isToBeInstalled()) {
847  MIL << "User requirement " << *iter << " sets " << poolItem << endl;
848  poolItem.status().setTransactByValue (ResStatus::APPL_LOW);
849  }
850  }
851  }
852  for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
853  sat::WhatProvides rpmProviders(*iter);
854  for_( iter2, rpmProviders.begin(), rpmProviders.end() ) {
855  PoolItem poolItem(*iter2);
856  if (poolItem.status().isToBeUninstalled()) {
857  MIL << "User conflict " << *iter << " sets " << poolItem << endl;
858  poolItem.status().setTransactByValue (ResStatus::APPL_LOW);
859  }
860  }
861  }
862 
863  if (solver_problem_count(_satSolver) > 0 )
864  {
865  ERR << "Solverrun finished with an ERROR" << endl;
866  return false;
867  }
868 
869  return true;
870 }
871 
872 void SATResolver::solverAddJobsFromPool()
873 {
874  for (PoolItemList::const_iterator iter = _items_to_install.begin(); iter != _items_to_install.end(); iter++) {
875  Id id = iter->id();
876  if (id == ID_NULL) {
877  ERR << "Install: " << *iter << " not found" << endl;
878  } else {
879  MIL << "Install " << *iter << endl;
880  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE );
881  queue_push( &(_jobQueue), id );
882  }
883  }
884 
885  for (PoolItemList::const_iterator iter = _items_to_remove.begin(); iter != _items_to_remove.end(); iter++) {
886  Id id = iter->id();
887  if (id == ID_NULL) {
888  ERR << "Delete: " << *iter << " not found" << endl;
889  } else {
890  MIL << "Delete " << *iter << endl;
891  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE | MAYBE_CLEANDEPS );
892  queue_push( &(_jobQueue), id);
893  }
894  }
895 }
896 
897 void SATResolver::solverAddJobsFromExtraQueues( const CapabilitySet & requires_caps, const CapabilitySet & conflict_caps )
898 {
899  for (CapabilitySet::const_iterator iter = requires_caps.begin(); iter != requires_caps.end(); iter++) {
900  queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
901  queue_push( &(_jobQueue), iter->id() );
902  MIL << "Requires " << *iter << endl;
903  }
904 
905  for (CapabilitySet::const_iterator iter = conflict_caps.begin(); iter != conflict_caps.end(); iter++) {
906  queue_push( &(_jobQueue), SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES | MAYBE_CLEANDEPS );
907  queue_push( &(_jobQueue), iter->id() );
908  MIL << "Conflicts " << *iter << endl;
909  }
910 }
911 
912 bool
913 SATResolver::resolvePool(const CapabilitySet & requires_caps,
914  const CapabilitySet & conflict_caps,
915  const PoolItemList & weakItems,
916  const std::set<Repository> & upgradeRepos)
917 {
918  MIL << "SATResolver::resolvePool()" << endl;
919 
920  // Initialize
921  solverInit(weakItems);
922 
923  // Add pool and extra jobs.
924  solverAddJobsFromPool();
925  solverAddJobsFromExtraQueues( requires_caps, conflict_caps );
926  // 'dup --from' jobs
927  for_( iter, upgradeRepos.begin(), upgradeRepos.end() )
928  {
929  queue_push( &(_jobQueue), SOLVER_DISTUPGRADE | SOLVER_SOLVABLE_REPO );
930  queue_push( &(_jobQueue), iter->get()->repoid );
931  MIL << "Upgrade repo " << *iter << endl;
932  }
933 
934  // Solve!
935  bool ret = solving(requires_caps, conflict_caps);
936 
937  (ret?MIL:WAR) << "SATResolver::resolvePool() done. Ret:" << ret << endl;
938  return ret;
939 }
940 
941 
942 bool
943 SATResolver::resolveQueue(const SolverQueueItemList &requestQueue,
944  const PoolItemList & weakItems)
945 {
946  MIL << "SATResolver::resolvQueue()" << endl;
947 
948  // Initialize
949  solverInit(weakItems);
950 
951  // Add request queue's jobs.
952  for (SolverQueueItemList::const_iterator iter = requestQueue.begin(); iter != requestQueue.end(); iter++) {
953  (*iter)->addRule(_jobQueue);
954  }
955 
956  // Add pool jobs; they do contain any problem resolutions.
957  solverAddJobsFromPool();
958 
959  // Solve!
960  bool ret = solving();
961 
962  (ret?MIL:WAR) << "SATResolver::resolveQueue() done. Ret:" << ret << endl;
963  return ret;
964 }
965 
966 
967 void SATResolver::doUpdate()
968 {
969  MIL << "SATResolver::doUpdate()" << endl;
970 
971  // Initialize
972  solverInit(PoolItemList());
973 
974  // By now, doUpdate has no additional jobs.
975  // It does not include any pool jobs, and so it does not create an conflicts.
976  // Combinations like patch_with_update are driven by resolvePool + _updatesystem.
977 
978  // TODO: Try to join the following with solving()
980 
981  // Solve!
982  MIL << "Starting solving for update...." << endl;
983  MIL << *this;
984  solver_solve( _satSolver, &(_jobQueue) );
985  MIL << "....Solver end" << endl;
986 
987  // copying solution back to zypp pool
988  //-----------------------------------------
989 
990  /* solvables to be installed */
991  Queue decisionq;
992  queue_init(&decisionq);
993  solver_get_decisionqueue(_satSolver, &decisionq);
994  for (int i = 0; i < decisionq.count; i++)
995  {
996  Id p = decisionq.elements[i];
997  if ( p < 0 )
998  continue;
999 
1000  sat::Solvable solv { (sat::detail::SolvableIdType)p };
1001  if ( ! solv || solv.isSystem() )
1002  continue;
1003 
1005  }
1006  queue_free(&decisionq);
1007 
1008  /* solvables to be erased */
1009  if ( _satSolver->pool->installed ) {
1010  for (int i = _satSolver->pool->installed->start; i < _satSolver->pool->installed->start + _satSolver->pool->installed->nsolvables; i++)
1011  {
1012  if (solver_get_decisionlevel(_satSolver, i) > 0)
1013  continue;
1014 
1015  PoolItem poolItem( _pool.find( sat::Solvable(i) ) );
1016  if (poolItem) {
1017  // Check if this is an update
1018  CheckIfUpdate info( (sat::Solvable(i)) );
1019  invokeOnEach( _pool.byIdentBegin( poolItem ),
1020  _pool.byIdentEnd( poolItem ),
1021  resfilter::ByUninstalled(), // ByUninstalled
1022  std::ref(info) );
1023 
1024  if (info.is_updated) {
1026  } else {
1028  }
1029  } else {
1030  ERR << "id " << i << " not found in ZYPP pool." << endl;
1031  }
1032  }
1033  }
1034 
1035  // copy back computed status values to pool
1036  // (on the fly cache orphaned items for the UI)
1037  solverCopyBackWeak( *_satSolver, _problem_items );
1038  solverCopyBackValidate( *_satSolver, _pool );
1039 
1040  MIL << "SATResolver::doUpdate() done" << endl;
1041 }
1042 
1043 
1044 
1045 //----------------------------------------------------------------------------
1046 //----------------------------------------------------------------------------
1047 // error handling
1048 //----------------------------------------------------------------------------
1049 //----------------------------------------------------------------------------
1050 
1051 //----------------------------------------------------------------------------
1052 // helper function
1053 //----------------------------------------------------------------------------
1054 
1056 {
1057  ProblemSolutionCombi *problemSolution;
1058  TransactionKind action;
1059  FindPackage (ProblemSolutionCombi *p, const TransactionKind act)
1060  : problemSolution (p)
1061  , action (act)
1062  {
1063  }
1064 
1065  bool operator()( const PoolItem& p)
1066  {
1067  problemSolution->addSingleAction (p, action);
1068  return true;
1069  }
1070 };
1071 
1072 
1073 //----------------------------------------------------------------------------
1074 // Checking if this solvable/item has a buddy which reflect the real
1075 // user visible description of an item
1076 // e.g. The release package has a buddy to the concerning product item.
1077 // This user want's the message "Product foo conflicts with product bar" and
1078 // NOT "package release-foo conflicts with package release-bar"
1079 // (ma: that's why we should map just packages to buddies, not vice versa)
1080 //----------------------------------------------------------------------------
1081 inline sat::Solvable mapBuddy( const PoolItem & item_r )
1082 {
1083  if ( item_r.isKind<Package>() )
1084  {
1085  sat::Solvable buddy = item_r.buddy();
1086  if ( buddy )
1087  return buddy;
1088  }
1089  return item_r.satSolvable();
1090 }
1092 { return mapBuddy( PoolItem( item_r ) ); }
1093 
1094 PoolItem SATResolver::mapItem ( const PoolItem & item )
1095 { return PoolItem( mapBuddy( item ) ); }
1096 
1097 sat::Solvable SATResolver::mapSolvable ( const Id & id )
1098 { return mapBuddy( sat::Solvable(id) ); }
1099 
1100 std::vector<std::string> SATResolver::SATgetCompleteProblemInfoStrings ( Id problem )
1101 {
1102  std::vector<std::string> ret;
1103  sat::Queue problems;
1104  solver_findallproblemrules( _satSolver, problem, problems );
1105 
1106  bool nobad = false;
1107 
1108  //filter out generic rule information if more explicit ones are available
1109  for ( sat::Queue::size_type i = 0; i < problems.size(); i++ ) {
1110  SolverRuleinfo ruleClass = solver_ruleclass( _satSolver, problems[i]);
1111  if ( ruleClass != SolverRuleinfo::SOLVER_RULE_UPDATE && ruleClass != SolverRuleinfo::SOLVER_RULE_JOB ) {
1112  nobad = true;
1113  break;
1114  }
1115  }
1116  for ( sat::Queue::size_type i = 0; i < problems.size(); i++ ) {
1117  SolverRuleinfo ruleClass = solver_ruleclass( _satSolver, problems[i]);
1118  if ( nobad && ( ruleClass == SolverRuleinfo::SOLVER_RULE_UPDATE || ruleClass == SolverRuleinfo::SOLVER_RULE_JOB ) ) {
1119  continue;
1120  }
1121 
1122  std::string detail;
1123  Id ignore = 0;
1124  std::string pInfo = SATproblemRuleInfoString( problems[i], detail, ignore );
1125 
1126  //we get the same string multiple times, reduce the noise
1127  if ( std::find( ret.begin(), ret.end(), pInfo ) == ret.end() )
1128  ret.push_back( pInfo );
1129  }
1130  return ret;
1131 }
1132 
1133 std::string SATResolver::SATprobleminfoString(Id problem, std::string &detail, Id &ignoreId)
1134 {
1135  // FIXME: solver_findallproblemrules to get all rules for this problem
1136  // (the 'most relevabt' one returned by solver_findproblemrule is embedded
1137  Id probr = solver_findproblemrule(_satSolver, problem);
1138  return SATproblemRuleInfoString( probr, detail, ignoreId );
1139 }
1140 
1141 std::string SATResolver::SATproblemRuleInfoString (Id probr, std::string &detail, Id &ignoreId)
1142 {
1143  std::string ret;
1144  sat::detail::CPool *pool = _satSolver->pool;
1145  Id dep = 0, source = 0, target = 0;
1146  SolverRuleinfo type = solver_ruleinfo(_satSolver, probr, &source, &target, &dep);
1147 
1148  ignoreId = 0;
1149 
1150  sat::Solvable s = mapSolvable( source );
1151  sat::Solvable s2 = mapSolvable( target );
1152 
1153  // @FIXME, these strings are a duplicate copied from the libsolv library
1154  // to provide translations. Instead of having duplicate code we should
1155  // translate those strings directly in libsolv
1156  switch ( type )
1157  {
1158  case SOLVER_RULE_DISTUPGRADE:
1159  if ( s.isSystem() )
1160  ret = str::Format(_("the installed %1% does not belong to a distupgrade repository and must be replaced") ) % s.asString();
1161  else /*just in case*/
1162  ret = str::Format(_("the to be installed %1% does not belong to a distupgrade repository") ) % s.asString();
1163  break;
1164  case SOLVER_RULE_INFARCH:
1165  if ( s.isSystem() )
1166  ret = str::Format(_("the installed %1% has inferior architecture") ) % s.asString();
1167  else
1168  ret = str::Format(_("the to be installed %1% has inferior architecture") ) % s.asString();
1169  break;
1170  case SOLVER_RULE_UPDATE:
1171  ret = str::Format(_("problem with the installed %1%") ) % s.asString();
1172  break;
1173  case SOLVER_RULE_JOB:
1174  ret = _("conflicting requests");
1175  break;
1176  case SOLVER_RULE_PKG:
1177  ret = _("some dependency problem");
1178  break;
1179  case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP:
1180  ret = str::Format(_("nothing provides the requested '%1%'") ) % pool_dep2str(pool, dep);
1181  detail += _("Have you enabled all the required repositories?");
1182  break;
1183  case SOLVER_RULE_JOB_UNKNOWN_PACKAGE:
1184  ret = str::Format(_("the requested package %1% does not exist") ) % pool_dep2str(pool, dep);
1185  detail += _("Have you enabled all the required repositories?");
1186  break;
1187  case SOLVER_RULE_JOB_UNSUPPORTED:
1188  ret = _("unsupported request");
1189  break;
1190  case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM:
1191  ret = str::Format(_("'%1%' is provided by the system and cannot be erased") ) % pool_dep2str(pool, dep);
1192  break;
1193  case SOLVER_RULE_PKG_NOT_INSTALLABLE:
1194  ret = str::Format(_("%1% is not installable") ) % s.asString();
1195  break;
1196  case SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP:
1197  ignoreId = source; // for setting weak dependencies
1198  if ( s.isSystem() )
1199  ret = str::Format(_("nothing provides '%1%' needed by the installed %2%") ) % pool_dep2str(pool, dep) % s.asString();
1200  else
1201  ret = str::Format(_("nothing provides '%1%' needed by the to be installed %2%") ) % pool_dep2str(pool, dep) % s.asString();
1202  break;
1203  case SOLVER_RULE_PKG_SAME_NAME:
1204  ret = str::Format(_("cannot install both %1% and %2%") ) % s.asString() % s2.asString();
1205  break;
1206  case SOLVER_RULE_PKG_CONFLICTS:
1207  if ( s.isSystem() ) {
1208  if ( s2.isSystem() )
1209  ret = str::Format(_("the installed %1% conflicts with '%2%' provided by the installed %3%") ) % s.asString() % pool_dep2str(pool, dep) % s2.asString();
1210  else
1211  ret = str::Format(_("the installed %1% conflicts with '%2%' provided by the to be installed %3%") ) % s.asString() % pool_dep2str(pool, dep) % s2.asString();
1212  }
1213  else {
1214  if ( s2.isSystem() )
1215  ret = str::Format(_("the to be installed %1% conflicts with '%2%' provided by the installed %3%") ) % s.asString() % pool_dep2str(pool, dep) % s2.asString();
1216  else
1217  ret = str::Format(_("the to be installed %1% conflicts with '%2%' provided by the to be installed %3%") ) % s.asString() % pool_dep2str(pool, dep) % s2.asString();
1218  }
1219  break;
1220  case SOLVER_RULE_PKG_OBSOLETES:
1221  case SOLVER_RULE_PKG_INSTALLED_OBSOLETES:
1222  if ( s.isSystem() ) {
1223  if ( s2.isSystem() )
1224  ret = str::Format(_("the installed %1% obsoletes '%2%' provided by the installed %3%") ) % s.asString() % pool_dep2str(pool, dep) % s2.asString();
1225  else
1226  ret = str::Format(_("the installed %1% obsoletes '%2%' provided by the to be installed %3%") ) % s.asString() % pool_dep2str(pool, dep) % s2.asString();
1227  }
1228  else {
1229  if ( s2.isSystem() )
1230  ret = str::Format(_("the to be installed %1% obsoletes '%2%' provided by the installed %3%") ) % s.asString() % pool_dep2str(pool, dep) % s2.asString();
1231  else
1232  ret = str::Format(_("the to be installed %1% obsoletes '%2%' provided by the to be installed %3%") ) % s.asString() % pool_dep2str(pool, dep) % s2.asString();
1233  }
1234  break;
1235  case SOLVER_RULE_PKG_SELF_CONFLICT:
1236  if ( s.isSystem() )
1237  ret = str::Format(_("the installed %1% conflicts with '%2%' provided by itself") ) % s.asString() % pool_dep2str(pool, dep);
1238  else
1239  ret = str::Format(_("the to be installed %1% conflicts with '%2%' provided by itself") ) % s.asString() % pool_dep2str(pool, dep);
1240  break;
1241  case SOLVER_RULE_PKG_REQUIRES: {
1242  ignoreId = source; // for setting weak dependencies
1243  Capability cap(dep);
1244  sat::WhatProvides possibleProviders(cap);
1245 
1246  // check, if a provider will be deleted
1247  typedef std::list<PoolItem> ProviderList;
1248  ProviderList providerlistInstalled, providerlistUninstalled;
1249  for_( iter1, possibleProviders.begin(), possibleProviders.end() ) {
1250  PoolItem provider1 = ResPool::instance().find( *iter1 );
1251  // find pair of an installed/uninstalled item with the same NVR
1252  bool found = false;
1253  for_( iter2, possibleProviders.begin(), possibleProviders.end() ) {
1254  PoolItem provider2 = ResPool::instance().find( *iter2 );
1255  if (compareByNVR (provider1,provider2) == 0
1256  && ( (provider1.status().isInstalled() && provider2.status().isUninstalled())
1257  || (provider2.status().isInstalled() && provider1.status().isUninstalled()) )) {
1258  found = true;
1259  break;
1260  }
1261  }
1262  if (!found) {
1263  if (provider1.status().isInstalled())
1264  providerlistInstalled.push_back(provider1);
1265  else
1266  providerlistUninstalled.push_back(provider1);
1267  }
1268  }
1269 
1270  if ( s.isSystem() )
1271  ret = str::Format(_("the installed %1% requires '%2%', but this requirement cannot be provided") ) % s.asString() % pool_dep2str(pool, dep);
1272  else
1273  ret = str::Format(_("the to be installed %1% requires '%2%', but this requirement cannot be provided") ) % s.asString() % pool_dep2str(pool, dep);
1274  if (providerlistInstalled.size() > 0) {
1275  detail += _("deleted providers: ");
1276  for (ProviderList::const_iterator iter = providerlistInstalled.begin(); iter != providerlistInstalled.end(); iter++) {
1277  if (iter == providerlistInstalled.begin())
1278  detail += itemToString( *iter );
1279  else
1280  detail += "\n " + itemToString( mapItem(*iter) );
1281  }
1282  }
1283  if (providerlistUninstalled.size() > 0) {
1284  if (detail.size() > 0)
1285  detail += _("\nnot installable providers: ");
1286  else
1287  detail = _("not installable providers: ");
1288  for (ProviderList::const_iterator iter = providerlistUninstalled.begin(); iter != providerlistUninstalled.end(); iter++) {
1289  if (iter == providerlistUninstalled.begin())
1290  detail += itemToString( *iter );
1291  else
1292  detail += "\n " + itemToString( mapItem(*iter) );
1293  }
1294  }
1295  break;
1296  }
1297  default: {
1298  DBG << "Unknown rule type(" << type << ") going to query libsolv for rule information." << endl;
1299  ret = str::asString( ::solver_problemruleinfo2str( _satSolver, type, static_cast<Id>(s.id()), static_cast<Id>(s2.id()), dep ) );
1300  break;
1301  }
1302  }
1303  return ret;
1304 }
1305 
1307 namespace {
1309  struct PtfPatchHint
1310  {
1311  void notInstallPatch( sat::Solvable slv_r )
1312  { _patch.push_back( slv_r.ident() ); }
1313 
1314  void removePtf( sat::Solvable slv_r, bool showremoveProtectHint_r = false )
1315  { _ptf.push_back( slv_r.ident() ); if ( showremoveProtectHint_r ) _showremoveProtectHint = true; }
1316 
1317  bool applies() const
1318  { return not _ptf.empty(); }
1319 
1320  std::string description() const {
1321  if ( not _patch.empty() ) {
1322  return str::Str()
1323  // translator: %1% is the name of a PTF, %2% the name of a patch.
1324  << (str::Format( _("%1% is not yet fully integrated into %2%.") ) % printlist(_ptf) % printlist(_patch)) << endl
1325  << _("Typically you want to keep the PTF and choose to not install the maintenance patches.");
1326  }
1327  //else: a common problem due to an installed ptf
1328 
1329  if ( _showremoveProtectHint ) { // bsc#1203248
1330  const std::string & removeptfCommand { str::Format("zypper removeptf %1%") % printlist(_ptf) };
1331  return str::Str()
1332  // translator: %1% is the name of a PTF.
1333  << (str::Format( _("Removing the installed %1% in this context will remove (not replace!) the included PTF-packages too." ) ) % printlist(_ptf)) << endl
1334  << (str::Format( _("The PTF should be removed by calling '%1%'. This will update the included PTF-packages rather than removing them." ) ) % removeptfCommand) << endl
1335  << _("Typically you want to keep the PTF or choose to cancel the action."); // ma: When translated, it should replace the '..and choose..' below too
1336  }
1337 
1338  return str::Str()
1339  // translator: %1% is the name of a PTF.
1340  << (str::Format( _("The installed %1% blocks the desired action.") ) % printlist(_ptf)) << endl
1341  << _("Typically you want to keep the PTF and choose to cancel the action.");
1342  }
1343  private:
1344  using StoreType = IdString;
1345  static std::string printlist( const std::vector<StoreType> & list_r )
1346  { str::Str ret; dumpRange( ret.stream(), list_r.begin(), list_r.end(), "", "", ", ", "", "" ); return ret; }
1347 
1348  std::vector<StoreType> _ptf;
1349  std::vector<StoreType> _patch;
1351  };
1352 }
1354 
1356 SATResolver::problems ()
1357 {
1358  ResolverProblemList resolverProblems;
1359  if (_satSolver && solver_problem_count(_satSolver)) {
1360  sat::detail::CPool *pool = _satSolver->pool;
1361  int pcnt = 0;
1362  Id p = 0, rp = 0, what = 0;
1363  Id problem = 0, solution = 0, element = 0;
1364  sat::Solvable s, sd;
1365 
1366  CapabilitySet system_requires = SystemCheck::instance().requiredSystemCap();
1367  CapabilitySet system_conflicts = SystemCheck::instance().conflictSystemCap();
1368 
1369  MIL << "Encountered problems! Here are the solutions:\n" << endl;
1370  pcnt = 1;
1371  problem = 0;
1372  while ((problem = solver_next_problem(_satSolver, problem)) != 0) {
1373  MIL << "Problem " << pcnt++ << ":" << endl;
1374  MIL << "====================================" << endl;
1375  std::string detail;
1376  Id ignoreId = 0;
1377  std::string whatString = SATprobleminfoString (problem,detail,ignoreId);
1378  MIL << whatString << endl;
1379  MIL << "------------------------------------" << endl;
1380  ResolverProblem_Ptr resolverProblem = new ResolverProblem (whatString, detail, SATgetCompleteProblemInfoStrings( problem ));
1381  PtfPatchHint ptfPatchHint; // bsc#1194848 hint on ptf<>patch conflicts
1382  solution = 0;
1383  while ((solution = solver_next_solution(_satSolver, problem, solution)) != 0) {
1384  element = 0;
1385  ProblemSolutionCombi *problemSolution = new ProblemSolutionCombi;
1386  while ((element = solver_next_solutionelement(_satSolver, problem, solution, element, &p, &rp)) != 0) {
1387  if (p == SOLVER_SOLUTION_JOB) {
1388  /* job, rp is index into job queue */
1389  what = _jobQueue.elements[rp];
1390  switch (_jobQueue.elements[rp-1]&(SOLVER_SELECTMASK|SOLVER_JOBMASK))
1391  {
1392  case SOLVER_INSTALL | SOLVER_SOLVABLE: {
1393  s = mapSolvable (what);
1394  PoolItem poolItem = _pool.find (s);
1395  if (poolItem) {
1396  if (pool->installed && s.get()->repo == pool->installed) {
1397  problemSolution->addSingleAction (poolItem, REMOVE);
1398  std::string description = str::Format(_("remove lock to allow removal of %1%") ) % s.asString();
1399  MIL << description << endl;
1400  problemSolution->addDescription (description);
1401  if ( _protectPTFs && s.isPtfMaster() )
1402  ptfPatchHint.removePtf( s, _protectPTFs ); // bsc#1203248
1403  } else {
1404  problemSolution->addSingleAction (poolItem, KEEP);
1405  std::string description = str::Format(_("do not install %1%") ) % s.asString();
1406  MIL << description << endl;
1407  problemSolution->addDescription (description);
1408  if ( s.isKind<Patch>() )
1409  ptfPatchHint.notInstallPatch( s );
1410  }
1411  } else {
1412  ERR << "SOLVER_INSTALL_SOLVABLE: No item found for " << s.asString() << endl;
1413  }
1414  }
1415  break;
1416  case SOLVER_ERASE | SOLVER_SOLVABLE: {
1417  s = mapSolvable (what);
1418  PoolItem poolItem = _pool.find (s);
1419  if (poolItem) {
1420  if (pool->installed && s.get()->repo == pool->installed) {
1421  problemSolution->addSingleAction (poolItem, KEEP);
1422  std::string description = str::Format(_("keep %1%") ) % s.asString();
1423  MIL << description << endl;
1424  problemSolution->addDescription (description);
1425  } else {
1426  problemSolution->addSingleAction (poolItem, UNLOCK);
1427  std::string description = str::Format(_("remove lock to allow installation of %1%") ) % itemToString( poolItem );
1428  MIL << description << endl;
1429  problemSolution->addDescription (description);
1430  }
1431  } else {
1432  ERR << "SOLVER_ERASE_SOLVABLE: No item found for " << s.asString() << endl;
1433  }
1434  }
1435  break;
1436  case SOLVER_INSTALL | SOLVER_SOLVABLE_NAME:
1437  {
1438  IdString ident( what );
1439  SolverQueueItemInstall_Ptr install =
1440  new SolverQueueItemInstall(_pool, ident.asString(), false );
1441  problemSolution->addSingleAction (install, REMOVE_SOLVE_QUEUE_ITEM);
1442 
1443  std::string description = str::Format(_("do not install %1%") ) % ident;
1444  MIL << description << endl;
1445  problemSolution->addDescription (description);
1446  }
1447  break;
1448  case SOLVER_ERASE | SOLVER_SOLVABLE_NAME:
1449  {
1450  // As we do not know, if this request has come from resolvePool or
1451  // resolveQueue we will have to take care for both cases.
1452  IdString ident( what );
1453  FindPackage info (problemSolution, KEEP);
1454  invokeOnEach( _pool.byIdentBegin( ident ),
1455  _pool.byIdentEnd( ident ),
1456  functor::chain (resfilter::ByInstalled (), // ByInstalled
1457  resfilter::ByTransact ()), // will be deinstalled
1458  std::ref(info) );
1459 
1460  SolverQueueItemDelete_Ptr del =
1461  new SolverQueueItemDelete(_pool, ident.asString(), false );
1462  problemSolution->addSingleAction (del, REMOVE_SOLVE_QUEUE_ITEM);
1463 
1464  std::string description = str::Format(_("keep %1%") ) % ident;
1465  MIL << description << endl;
1466  problemSolution->addDescription (description);
1467  }
1468  break;
1469  case SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES:
1470  {
1471  problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_REQUIRE);
1472  std::string description = "";
1473 
1474  // Checking if this problem solution would break your system
1475  if (system_requires.find(Capability(what)) != system_requires.end()) {
1476  // Show a better warning
1477  resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() );
1478  resolverProblem->setDescription(_("This request will break your system!"));
1479  description = _("ignore the warning of a broken system");
1480  description += std::string(" (requires:")+pool_dep2str(pool, what)+")";
1481  MIL << description << endl;
1482  problemSolution->addFrontDescription (description);
1483  } else {
1484  description = str::Format(_("do not ask to install a solvable providing %1%") ) % pool_dep2str(pool, what);
1485  MIL << description << endl;
1486  problemSolution->addDescription (description);
1487  }
1488  }
1489  break;
1490  case SOLVER_ERASE | SOLVER_SOLVABLE_PROVIDES:
1491  {
1492  problemSolution->addSingleAction (Capability(what), REMOVE_EXTRA_CONFLICT);
1493  std::string description = "";
1494 
1495  // Checking if this problem solution would break your system
1496  if (system_conflicts.find(Capability(what)) != system_conflicts.end()) {
1497  // Show a better warning
1498  resolverProblem->setDetails( resolverProblem->description() + "\n" + resolverProblem->details() );
1499  resolverProblem->setDescription(_("This request will break your system!"));
1500  description = _("ignore the warning of a broken system");
1501  description += std::string(" (conflicts:")+pool_dep2str(pool, what)+")";
1502  MIL << description << endl;
1503  problemSolution->addFrontDescription (description);
1504 
1505  } else {
1506  description = str::Format(_("do not ask to delete all solvables providing %1%") ) % pool_dep2str(pool, what);
1507  MIL << description << endl;
1508  problemSolution->addDescription (description);
1509  }
1510  }
1511  break;
1512  case SOLVER_UPDATE | SOLVER_SOLVABLE:
1513  {
1514  s = mapSolvable (what);
1515  PoolItem poolItem = _pool.find (s);
1516  if (poolItem) {
1517  if (pool->installed && s.get()->repo == pool->installed) {
1518  problemSolution->addSingleAction (poolItem, KEEP);
1519  std::string description = str::Format(_("do not install most recent version of %1%") ) % s.asString();
1520  MIL << description << endl;
1521  problemSolution->addDescription (description);
1522  } else {
1523  ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE " << poolItem << " is not selected for installation" << endl;
1524  }
1525  } else {
1526  ERR << "SOLVER_INSTALL_SOLVABLE_UPDATE: No item found for " << s.asString() << endl;
1527  }
1528  }
1529  break;
1530  default:
1531  MIL << "- do something different" << endl;
1532  ERR << "No valid solution available" << endl;
1533  break;
1534  }
1535  } else if (p == SOLVER_SOLUTION_INFARCH) {
1536  s = mapSolvable (rp);
1537  PoolItem poolItem = _pool.find (s);
1538  if (pool->installed && s.get()->repo == pool->installed) {
1539  problemSolution->addSingleAction (poolItem, LOCK);
1540  std::string description = str::Format(_("keep %1% despite the inferior architecture") ) % s.asString();
1541  MIL << description << endl;
1542  problemSolution->addDescription (description);
1543  } else {
1544  problemSolution->addSingleAction (poolItem, INSTALL);
1545  std::string description = str::Format(_("install %1% despite the inferior architecture") ) % s.asString();
1546  MIL << description << endl;
1547  problemSolution->addDescription (description);
1548  }
1549  } else if (p == SOLVER_SOLUTION_DISTUPGRADE) {
1550  s = mapSolvable (rp);
1551  PoolItem poolItem = _pool.find (s);
1552  if (pool->installed && s.get()->repo == pool->installed) {
1553  problemSolution->addSingleAction (poolItem, LOCK);
1554  std::string description = str::Format(_("keep obsolete %1%") ) % s.asString();
1555  MIL << description << endl;
1556  problemSolution->addDescription (description);
1557  } else {
1558  problemSolution->addSingleAction (poolItem, INSTALL);
1559  std::string description = str::Format(_("install %1% from excluded repository") ) % s.asString();
1560  MIL << description << endl;
1561  problemSolution->addDescription (description);
1562  }
1563  } else if ( p == SOLVER_SOLUTION_BLACK ) {
1564  // Allow to install a blacklisted package (PTF, retracted,...).
1565  // For not-installed items only
1566  s = mapSolvable (rp);
1567  PoolItem poolItem = _pool.find (s);
1568 
1569  problemSolution->addSingleAction (poolItem, INSTALL);
1570  std::string description;
1571  if ( s.isRetracted() ) {
1572  // translator: %1% is a package name
1573  description = str::Format(_("install %1% although it has been retracted")) % s.asString();
1574  } else if ( s.isPtf() ) {
1575  // translator: %1% is a package name
1576  description = str::Format(_("allow installing the PTF %1%")) % s.asString();
1577  } else {
1578  // translator: %1% is a package name
1579  description = str::Format(_("install %1% although it is blacklisted")) % s.asString();
1580  }
1581  MIL << description << endl;
1582  problemSolution->addDescription( description );
1583  } else if ( p > 0 ) {
1584  /* policy, replace p with rp */
1585  s = mapSolvable (p);
1586  PoolItem itemFrom = _pool.find (s);
1587  if (rp)
1588  {
1589  int gotone = 0;
1590 
1591  sd = mapSolvable (rp);
1592  PoolItem itemTo = _pool.find (sd);
1593  if (itemFrom && itemTo) {
1594  problemSolution->addSingleAction (itemTo, INSTALL);
1595  int illegal = policy_is_illegal(_satSolver, s.get(), sd.get(), 0);
1596 
1597  if ((illegal & POLICY_ILLEGAL_DOWNGRADE) != 0)
1598  {
1599  std::string description = str::Format(_("downgrade of %1% to %2%") ) % s.asString() % sd.asString();
1600  MIL << description << endl;
1601  problemSolution->addDescription (description);
1602  gotone = 1;
1603  }
1604  if ((illegal & POLICY_ILLEGAL_ARCHCHANGE) != 0)
1605  {
1606  std::string description = str::Format(_("architecture change of %1% to %2%") ) % s.asString() % sd.asString();
1607  MIL << description << endl;
1608  problemSolution->addDescription (description);
1609  gotone = 1;
1610  }
1611  if ((illegal & POLICY_ILLEGAL_VENDORCHANGE) != 0)
1612  {
1613  IdString s_vendor( s.vendor() );
1614  IdString sd_vendor( sd.vendor() );
1615  std::string description;
1616  if ( s == sd ) // FIXME? Actually .ident() must be eq. But the more verbose 'else' isn't bad either.
1617  description = str::Format(_("install %1% (with vendor change)\n %2% --> %3%") )
1618  % sd.asString()
1619  % ( s_vendor ? s_vendor.c_str() : " (no vendor) " )
1620  % ( sd_vendor ? sd_vendor.c_str() : " (no vendor) " );
1621  else
1622  description = str::Format(_("install %1% from vendor %2%\n replacing %3% from vendor %4%") )
1623  % sd.asString() % ( sd_vendor ? sd_vendor.c_str() : " (no vendor) " )
1624  % s.asString() % ( s_vendor ? s_vendor.c_str() : " (no vendor) " );
1625 
1626  MIL << description << endl;
1627  problemSolution->addDescription (description);
1628  gotone = 1;
1629  }
1630  if (!gotone) {
1631  std::string description = str::Format(_("replacement of %1% with %2%") ) % s.asString() % sd.asString();
1632  MIL << description << endl;
1633  problemSolution->addDescription (description);
1634  }
1635  } else {
1636  ERR << s.asString() << " or " << sd.asString() << " not found" << endl;
1637  }
1638  }
1639  else
1640  {
1641  if (itemFrom) {
1642  std::string description = str::Format(_("deinstallation of %1%") ) % s.asString();
1643  MIL << description << endl;
1644  problemSolution->addDescription (description);
1645  problemSolution->addSingleAction (itemFrom, REMOVE);
1646  if ( s.isPtfMaster() )
1647  ptfPatchHint.removePtf( s );
1648  }
1649  }
1650  }
1651  else
1652  {
1653  INT << "Unknown solution " << p << endl;
1654  }
1655 
1656  }
1657  resolverProblem->addSolution (problemSolution,
1658  problemSolution->actionCount() > 1 ? true : false); // Solutions with more than 1 action will be shown first.
1659  MIL << "------------------------------------" << endl;
1660  }
1661 
1662  if (ignoreId > 0) {
1663  // There is a possibility to ignore this error by setting weak dependencies
1664  PoolItem item = _pool.find (sat::Solvable(ignoreId));
1665  ProblemSolutionIgnore *problemSolution = new ProblemSolutionIgnore(item);
1666  resolverProblem->addSolution (problemSolution,
1667  false); // Solutions will be shown at the end
1668  MIL << "ignore some dependencies of " << item << endl;
1669  MIL << "------------------------------------" << endl;
1670  }
1671 
1672  // bsc#1194848 hint on ptf<>patch conflicts
1673  if ( ptfPatchHint.applies() ) {
1674  resolverProblem->setDescription( str::Str() << ptfPatchHint.description() << endl << "(" << resolverProblem->description() << ")" );
1675  }
1676  // save problem
1677  resolverProblems.push_back (resolverProblem);
1678  }
1679  }
1680  return resolverProblems;
1681 }
1682 
1683 void SATResolver::applySolutions( const ProblemSolutionList & solutions )
1684 { Resolver( _pool ).applySolutions( solutions ); }
1685 
1686 sat::StringQueue SATResolver::autoInstalled() const
1687 {
1688  sat::StringQueue ret;
1689  if ( _satSolver )
1690  ::solver_get_userinstalled( _satSolver, ret, GET_USERINSTALLED_NAMES|GET_USERINSTALLED_INVERTED );
1691  return ret;
1692 }
1693 
1694 sat::StringQueue SATResolver::userInstalled() const
1695 {
1696  sat::StringQueue ret;
1697  if ( _satSolver )
1698  ::solver_get_userinstalled( _satSolver, ret, GET_USERINSTALLED_NAMES );
1699  return ret;
1700 }
1701 
1702 
1704 };// namespace detail
1707  };// namespace solver
1710 };// namespace zypp
bool empty() const
Definition: Queue.cc:46
Interface to gettext.
#define MIL
Definition: Logger.h:100
static const IdString ptfMasterToken
Indicator provides ptf()
Definition: Solvable.h:59
A Solvable object within the sat Pool.
Definition: Solvable.h:53
Container of Solvable providing a Capability (read only).
Definition: WhatProvides.h:87
bool operator()(const PoolItem &p)
Focus on updating requested packages and their dependencies as much as possible.
#define _(MSG)
Definition: Gettext.h:39
::s_Solver CSolver
Wrapped libsolv C data type exposed as backdoor.
Definition: PoolMember.h:65
static ZConfig & instance()
Singleton ctor.
Definition: ZConfig.cc:925
bool isToBeInstalled() const
Definition: ResStatus.h:259
bool equivalent(const Vendor &lVendor, const Vendor &rVendor) const
Return whether two vendor strings should be treated as the same vendor.
Definition: VendorAttr.cc:313
Queue StringQueue
Queue with String ids.
Definition: Queue.h:28
ProblemSolutionCombi * problemSolution
PoolItem find(const sat::Solvable &slv_r) const
Return the corresponding PoolItem.
Definition: ResPool.cc:74
ResolverFocus
The resolver&#39;s general attitude.
Definition: ResolverFocus.h:23
bool _showremoveProtectHint
#define INT
Definition: Logger.h:104
std::ostream & dumpRange(std::ostream &str, TIterator begin, TIterator end, const std::string &intro="{", const std::string &pfx="\ ", const std::string &sep="\ ", const std::string &sfx="\, const std::string &extro="}")
Print range defined by iterators (multiline style).
Definition: LogTools.h:120
ResStatus & status() const
Returns the current status.
Definition: PoolItem.cc:212
static const ResStatus toBeInstalled
Definition: ResStatus.h:667
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
sat::Solvable buddy() const
Return the buddy we share our status object with.
Definition: PoolItem.cc:215
const std::string & asString(const std::string &t)
Global asString() that works with std::string too.
Definition: String.h:139
#define OUTS(X)
Definition: Arch.h:363
int IdType
Generic Id type.
Definition: PoolMember.h:104
Access to the sat-pools string space.
Definition: IdString.h:43
bool sameNVRA(const SolvableType< Derived > &lhs, const Solvable &rhs)
Definition: SolvableType.h:232
Request the standard behavior (as defined in zypp.conf or &#39;Job&#39;)
bool resetTransact(TransactByValue causer_r)
Not the same as setTransact( false ).
Definition: ResStatus.h:490
size_type reposSize() const
Number of repos in Pool.
Definition: Pool.cc:73
#define ERR
Definition: Logger.h:102
static void SATSolutionToPool(const PoolItem &item, const ResStatus &status, const ResStatus::TransactByValue causer)
Definition: SATResolver.cc:338
bool setToBeUninstalledDueToUpgrade(TransactByValue causer)
Definition: ResStatus.h:574
#define MAYBE_CLEANDEPS
Definition: SATResolver.cc:172
std::vector< StoreType > _patch
static const ResStatus toBeUninstalledDueToUpgrade
Definition: ResStatus.h:669
void prepare() const
Update housekeeping data if necessary (e.g.
Definition: Pool.cc:61
CheckIfUpdate(const sat::Solvable &installed_r)
Definition: SATResolver.cc:688
Repository repository() const
The Repository this Solvable belongs to.
Definition: Solvable.cc:364
void push(value_type val_r)
Push a value to the end off the Queue.
Definition: Queue.cc:103
void establish(sat::Queue &pseudoItems_r, sat::Queue &pseudoFlags_r)
ResPool helper to compute the initial status of Patches etc.
Definition: SATResolver.cc:188
static Pool instance()
Singleton ctor.
Definition: Pool.h:55
Commit helper functor distributing PoolItem by status into lists.
Definition: SATResolver.cc:375
bool operator()(const PoolItem &item)
Definition: SATResolver.cc:695
int relaxedVendorCheck(sat::detail::CPool *pool, Solvable *solvable1, Solvable *solvable2)
Definition: SATResolver.cc:181
unsigned int size_type
Definition: Queue.h:38
int vendorCheck(sat::detail::CPool *pool, Solvable *solvable1, Solvable *solvable2)
Definition: SATResolver.cc:178
Package interface.
Definition: Package.h:33
#define WAR
Definition: Logger.h:101
Focus on applying as little changes to the installed packages as needed.
bool multiversionInstall() const
Definition: SolvableType.h:82
bool relaxedEquivalent(const Vendor &lVendor, const Vendor &rVendor) const
Like equivalent but always unifies suse and openSUSE vendor.
Definition: VendorAttr.cc:326
std::ostream & dumpOn(std::ostream &str, const Capability &obj)
Definition: Capability.cc:580
SATCollectTransact(PoolItemList &items_to_install_r, PoolItemList &items_to_remove_r, PoolItemList &items_to_lock_r, PoolItemList &items_to_keep_r, bool solveSrcPackages_r)
Definition: SATResolver.cc:377
bool operator()(const PoolItem &item_r)
Definition: SATResolver.cc:394
std::list< SolverQueueItem_Ptr > SolverQueueItemList
Definition: Types.h:45
bool setToBeUninstalled(TransactByValue causer)
Definition: ResStatus.h:550
FindPackage(ProblemSolutionCombi *p, const TransactionKind act)
size_type size() const
Definition: Queue.cc:49
std::unordered_set< Capability > CapabilitySet
Definition: Capability.h:35
Libsolv Id queue wrapper.
Definition: Queue.h:35
bool compareByNVR(const SolvableType< Derived > &lhs, const Solvable &rhs)
Definition: SolvableType.h:260
static Ptr get(const pool::ByIdent &ident_r)
Get the Selctable.
Definition: Selectable.cc:29
SrcPackage interface.
Definition: SrcPackage.h:29
sat::Solvable mapBuddy(sat::Solvable item_r)
std::string alias() const
Short unique string to identify a repo.
Definition: Repository.cc:60
std::list< ResolverProblem_Ptr > ResolverProblemList
Definition: ProblemTypes.h:46
bool isToBeUninstalled() const
Definition: ResStatus.h:267
A sat capability.
Definition: Capability.h:62
::s_Pool CPool
Wrapped libsolv C data type exposed as backdoor.
Definition: PoolMember.h:61
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:94
Chain< TACondition, TBCondition > chain(TACondition conda_r, TBCondition condb_r)
Convenience function for creating a Chain from two conditions conda_r and condb_r.
Definition: Functional.h:185
bool setToBeInstalled(TransactByValue causer)
Definition: ResStatus.h:536
bool isPseudoInstalled(const ResKind &kind_r)
Those are denoted to be installed, if the solver verifies them as being satisfied.
Definition: ResTraits.h:28
Status bitfield.
Definition: ResStatus.h:54
IMPL_PTR_TYPE(SATResolver)
unsigned int SolvableIdType
Id type to connect Solvable and sat-solvable.
Definition: PoolMember.h:125
Combining sat::Solvable and ResStatus.
Definition: PoolItem.h:50
Pathname systemRoot() const
The target root directory.
Definition: ZConfig.cc:953
static const IdString retractedToken
Indicator provides retracted-patch-package()
Definition: Solvable.h:58
std::string asString() const
Conversion to std::string
Definition: IdString.h:99
bool isKind(const ResKind &kind_r) const
Definition: SolvableType.h:64
void resetWeak()
Definition: ResStatus.h:203
static const VendorAttr & instance()
(Pseudo)Singleton, mapped to the current Target::vendorAttr settings or to noTargetInstance.
Definition: VendorAttr.cc:230
int invokeOnEach(TIterator begin_r, TIterator end_r, TFilter filter_r, TFunction fnc_r)
Iterate through [begin_r,end_r) and invoke fnc_r on each item that passes filter_r.
Definition: Algorithm.h:30
std::string itemToString(const PoolItem &item)
Definition: SATResolver.cc:230
#define XDEBUG(x)
Definition: SATResolver.cc:59
Easy-to use interface to the ZYPP dependency resolver.
Definition: Application.cc:19
Solvable satSolvable() const
Return the corresponding sat::Solvable.
Definition: SolvableType.h:57
Focus on installing the best version of the requested packages.
zypp::IdString IdString
Definition: idstring.h:16
static const ResStatus toBeUninstalled
Definition: ResStatus.h:668
std::vector< StoreType > _ptf
bool isToBeUninstalledDueToUpgrade() const
Definition: ResStatus.h:324
#define DBG
Definition: Logger.h:99
std::list< ProblemSolution_Ptr > ProblemSolutionList
Definition: ProblemTypes.h:43
static ResPool instance()
Singleton ctor.
Definition: ResPool.cc:38