From 96167acb698bd10975e1041717e8853aaa22216c Mon Sep 17 00:00:00 2001 From: Michael Andres Date: Fri, 20 Nov 2009 13:29:37 +0100 Subject: [PATCH] Parse zypp.conf multiversion option and make the setting available in pool and resolver. - Let return the plain config file values (name or provides:...). - Add 'bool multiversionInstall()' method in Solvable, ResObject and Selectable. - Add sat::Pool::multiversionBegin to iterate over all multiversion installable packages. - Pass the multiversion settings to the solver. --- zypp.conf | 18 +++++++++++++++--- zypp/Resolvable.h | 11 +++++++---- zypp/ZConfig.cc | 20 +++++--------------- zypp/ZConfig.h | 15 +++++++++------ zypp/sat/Pool.cc | 6 ++++++ zypp/sat/Pool.h | 16 ++++++++++++++++ zypp/sat/Solvable.cc | 9 ++++----- zypp/sat/Solvable.h | 8 +++++++- zypp/sat/detail/PoolImpl.cc | 34 ++++++++++++++++++++++++++++++++++ zypp/sat/detail/PoolImpl.h | 24 ++++++++++++++++++++++++ zypp/solver/detail/SATResolver.cc | 8 ++++---- zypp/ui/Selectable.cc | 3 +++ zypp/ui/Selectable.h | 5 +++++ zypp/ui/SelectableImpl.h | 6 +++++- 14 files changed, 144 insertions(+), 39 deletions(-) diff --git a/zypp.conf b/zypp.conf index c62d21d..b57ca59 100644 --- a/zypp.conf +++ b/zypp.conf @@ -310,10 +310,22 @@ # solver.upgradeRemoveDroppedPackages = true ## -## Packages which are parallel installable with -## diffent versions +## Packages which can be installed in different versions at the same time. ## -# multiversion = kernel-default,kernel-smp +## Packages are selected either by name, or by provides. In the later case +## the string must start with "provides:" immediately followed by the capability. +## +## Example: +## kernel - just packages whith name 'kernel' +## provides:multiversion(kernel) - all packages providing 'multiversion(kernel)' +## (kenel and kmp packages should do this) +## Valid values: +## Comma separated list of packages. +## +## Default value: +## empty +## +# multiversion = provides:multiversion(kernel) ## ## Path to locks file. If not exist then is create. diff --git a/zypp/Resolvable.h b/zypp/Resolvable.h index 40c9a92..c7735a2 100644 --- a/zypp/Resolvable.h +++ b/zypp/Resolvable.h @@ -79,12 +79,15 @@ namespace zypp Arch arch() const { return sat::Solvable::arch(); } - /** - * Flag in the metadata indicating this should be - * installed unsing '-i' (not -U). + /** Whether different versions of this package can be installed at the same time. + * Per default \c false. \see also \ref ZConfig::multiversion. */ + bool multiversionInstall() const + { return sat::Solvable::multiversionInstall(); } + + /** \deprecated Use \ref multiversionInstall. */ bool installOnly() const - { return sat::Solvable::installOnly(); } + { return sat::Solvable::multiversionInstall(); } /** \name Dependencies. */ //@{ diff --git a/zypp/ZConfig.cc b/zypp/ZConfig.cc index 442c27d..136a6c1 100644 --- a/zypp/ZConfig.cc +++ b/zypp/ZConfig.cc @@ -367,12 +367,7 @@ namespace zypp } else if ( entry == "multiversion" ) { - std::list multi; - str::split( value, back_inserter(multi), ", \t" ); - for ( std::list::const_iterator it = multi.begin(); - it != multi.end(); it++) { - multiversion.insert (IdString(*it)); - } + str::split( value, inserter( multiversion, multiversion.end() ), ", \t" ); } else if ( entry == "locksfile.path" ) { @@ -485,7 +480,7 @@ namespace zypp Pathname solver_checkSystemFile; - std::set multiversion; + std::set multiversion; bool apply_locks_file; @@ -706,14 +701,9 @@ namespace zypp void ZConfig::setSolverUpgradeRemoveDroppedPackages( bool val_r ) { _pimpl->solverUpgradeRemoveDroppedPackages.set( val_r ); } void ZConfig::resetSolverUpgradeRemoveDroppedPackages() { _pimpl->solverUpgradeRemoveDroppedPackages.restoreToDefault(); } - std::set ZConfig::multiversion() const - { return _pimpl->multiversion; } - - void ZConfig::addMultiversion(std::string &name) - { _pimpl->multiversion.insert(IdString(name)); } - - bool ZConfig::removeMultiversion(std::string &name) - { return _pimpl->multiversion.erase(IdString(name)); } + const std::set & ZConfig::multiversionSpec() const { return _pimpl->multiversion; } + void ZConfig::addMultiversionSpec( const std::string & name_r ) { _pimpl->multiversion.insert( name_r ); } + void ZConfig::removeMultiversionSpec( const std::string & name_r ) { _pimpl->multiversion.erase( name_r ); } bool ZConfig::apply_locks_file() const { return _pimpl->apply_locks_file; } diff --git a/zypp/ZConfig.h b/zypp/ZConfig.h index badb1ec..a222594 100644 --- a/zypp/ZConfig.h +++ b/zypp/ZConfig.h @@ -265,13 +265,16 @@ namespace zypp /** Reset \ref solverUpgradeRemoveDroppedPackages to the \c zypp.conf default. */ void resetSolverUpgradeRemoveDroppedPackages(); - /** - * Packages which can be installed parallel with different versions - * Returning a set of package names (IdString) + /** \name Packages which can be installed in different versions at the same time. + * This returns the config file values (\c names or \c provides:...). For the corresponding + * packages use e.g \ref sat::Pool::multiversionBegin, or \ref sat::Solbale::multiversionInstall + * (\ref ui::Selectable::multiversionInstall). */ - std::set multiversion() const; - void addMultiversion(std::string &name); - bool removeMultiversion(std::string &name); + //@{ + const std::set & multiversionSpec() const; + void addMultiversionSpec( const std::string & name_r ); + void removeMultiversionSpec( const std::string & name_r ); + //@} /** * Path where zypp can find or create lock file (configPath()/locks) diff --git a/zypp/sat/Pool.cc b/zypp/sat/Pool.cc index ee5d607..b07df4e 100644 --- a/zypp/sat/Pool.cc +++ b/zypp/sat/Pool.cc @@ -200,6 +200,12 @@ namespace zypp bool Pool::isAvailableLocale( const Locale & locale_r ) const { return myPool().isAvailableLocale( locale_r ); } + bool Pool::multiversionEmpty() const { return myPool().multiversionList().empty(); } + size_t Pool::multiversionSize() const { return myPool().multiversionList().size(); } + Pool::MultiversionIterator Pool::multiversionBegin() const { return myPool().multiversionList().begin(); } + Pool::MultiversionIterator Pool::multiversionEnd() const { return myPool().multiversionList().end(); } + bool Pool::isMultiversion( IdString ident_r ) const { return myPool().isMultiversion( ident_r ); } + /****************************************************************** ** ** FUNCTION NAME : operator<< diff --git a/zypp/sat/Pool.h b/zypp/sat/Pool.h index a1bd62a..bcd92e3 100644 --- a/zypp/sat/Pool.h +++ b/zypp/sat/Pool.h @@ -202,6 +202,22 @@ namespace zypp //@} public: + /** \name Multiversion install. + * Ident list of all packages that can be installed in different version + * at the same time. (\see \ref ZConfig::multiversionSpec) + */ + //@{ + typedef std::tr1::unordered_set::const_iterator MultiversionIterator; + + bool multiversionEmpty() const; + size_t multiversionSize() const; + MultiversionIterator multiversionBegin() const; + MultiversionIterator multiversionEnd() const; + + bool isMultiversion( IdString ident_r ) const; + //@} + + public: /** Expert backdoor. */ ::_Pool * get() const; private: diff --git a/zypp/sat/Solvable.cc b/zypp/sat/Solvable.cc index 8802ac7..c15d169 100644 --- a/zypp/sat/Solvable.cc +++ b/zypp/sat/Solvable.cc @@ -374,14 +374,13 @@ namespace zypp //return ArchId( _solvable->arch ); } - bool Solvable::installOnly() const + bool Solvable::multiversionInstall() const { - std::set multiversion = ZConfig::instance().multiversion(); - if (multiversion.find(ident()) != multiversion.end()) - return true; - return false; + return myPool().isMultiversion( ident() ); } + bool Solvable::installOnly() const { return multiversionInstall(); } + IdString Solvable::vendor() const { NO_SOLVABLE_RETURN( IdString() ); diff --git a/zypp/sat/Solvable.h b/zypp/sat/Solvable.h index ceb8417..4637d2f 100644 --- a/zypp/sat/Solvable.h +++ b/zypp/sat/Solvable.h @@ -169,7 +169,13 @@ namespace zypp IdString vendor() const; - bool installOnly() const; + /** Whether different versions of this package can be installed at the same time. + * Per default \c false. \see also \ref ZConfig::multiversion. + */ + bool multiversionInstall() const; + + /** \deprecated Use \ref multiversionInstall. */ + bool installOnly() const ZYPP_DEPRECATED; /** String representation "ident-edition.arch" or \c "noSolvable" * \code diff --git a/zypp/sat/detail/PoolImpl.cc b/zypp/sat/detail/PoolImpl.cc index 951756f..68f9d33 100644 --- a/zypp/sat/detail/PoolImpl.cc +++ b/zypp/sat/detail/PoolImpl.cc @@ -215,6 +215,7 @@ namespace zypp } _serial.setDirty(); // pool content change _availableLocalesPtr.reset(); // available locales may change + _multiversionListPtr.reset(); // re-evaluate ZConfig::multiversionSpec. // invaldate dependency/namespace related indices: depSetDirty(); @@ -478,6 +479,39 @@ namespace zypp return *_availableLocalesPtr; } + void PoolImpl::multiversionListInit() const + { + _multiversionListPtr.reset( new MultiversionList ); + MultiversionList & multiversionList( *_multiversionListPtr ); + + const std::set & multiversionSpec( ZConfig::instance().multiversionSpec() ); + for_( it, multiversionSpec.begin(), multiversionSpec.end() ) + { + static const std::string prefix( "provides:" ); + if ( str::hasPrefix( *it, prefix ) ) + { + WhatProvides provides( Capability( it->c_str() + prefix.size() ) ); + if ( provides.empty() ) + { + MIL << "Multiversion install not provided (" << *it << ")" << endl; + } + else + { + for_( pit, provides.begin(), provides.end() ) + { + if ( multiversionList.insert( pit->ident() ).second ) + MIL << "Multiversion install " << pit->ident() << " (" << *it << ")" << endl; + } + } + } + else + { + MIL << "Multiversion install " << *it << endl; + multiversionList.insert( IdString( *it ) ); + } + } + } + ///////////////////////////////////////////////////////////////// } // namespace detail /////////////////////////////////////////////////////////////////// diff --git a/zypp/sat/detail/PoolImpl.h b/zypp/sat/detail/PoolImpl.h index ade5a97..b5f59cf 100644 --- a/zypp/sat/detail/PoolImpl.h +++ b/zypp/sat/detail/PoolImpl.h @@ -222,6 +222,26 @@ namespace zypp } //@} + public: + /** \name Multiversion install. */ + //@{ + typedef std::tr1::unordered_set MultiversionList; + + const MultiversionList & multiversionList() const + { + if ( ! _multiversionListPtr ) + multiversionListInit(); + return *_multiversionListPtr; + } + + bool isMultiversion( IdString ident_r ) const + { + const MultiversionList & l( multiversionList() ); + return l.find( ident_r ) != l.end(); + } + + //@} + private: /** sat-pool. */ ::_Pool * _pool; @@ -236,6 +256,10 @@ namespace zypp LocaleSet _requestedLocales; mutable scoped_ptr _availableLocalesPtr; mutable std::tr1::unordered_set _locale2Solver; + + /** */ + void multiversionListInit() const; + mutable scoped_ptr _multiversionListPtr; }; /////////////////////////////////////////////////////////////////// diff --git a/zypp/solver/detail/SATResolver.cc b/zypp/solver/detail/SATResolver.cc index 7826db2..909c2e4 100644 --- a/zypp/solver/detail/SATResolver.cc +++ b/zypp/solver/detail/SATResolver.cc @@ -610,10 +610,10 @@ SATResolver::solverInit(const PoolItemList & weakItems) } // Add rules for parallel installable resolvables with different versions - std::set parallel = ZConfig::instance().multiversion(); - for (std::set::const_iterator it = parallel.begin(); it != parallel.end(); ++it) { - queue_push( &(_jobQueue), SOLVER_NOOBSOLETES_SOLVABLE_NAME ); - queue_push( &(_jobQueue), it->id() ); + for_( it, sat::Pool::instance().multiversionBegin(), sat::Pool::instance().multiversionEnd() ) + { + queue_push( &(_jobQueue), SOLVER_NOOBSOLETES_SOLVABLE_NAME ); + queue_push( &(_jobQueue), it->id() ); } if ( _distupgrade ) diff --git a/zypp/ui/Selectable.cc b/zypp/ui/Selectable.cc index 451c466..491e02b 100644 --- a/zypp/ui/Selectable.cc +++ b/zypp/ui/Selectable.cc @@ -132,6 +132,9 @@ namespace zypp bool Selectable::isUnmaintained() const { return _pimpl->isUnmaintained(); } + bool Selectable::multiversionInstall() const + { return _pimpl->multiversionInstall(); } + bool Selectable::isUndetermined() const { return _pimpl->isUndetermined(); } diff --git a/zypp/ui/Selectable.h b/zypp/ui/Selectable.h index ac32377..7b0b3d0 100644 --- a/zypp/ui/Selectable.h +++ b/zypp/ui/Selectable.h @@ -267,6 +267,11 @@ namespace zypp */ bool isUnmaintained() const; + /** Whether different versions of this package can be installed at the same time. + * Per default \c false. \see also \ref ZConfig::multiversion. + */ + bool multiversionInstall() const; + /** \name Classification of available patches (pseudo installed items). * A patch is either \c not \c relevant, \c satisfied or \c broken. * The same applies to other pseudo installed kinds. diff --git a/zypp/ui/SelectableImpl.h b/zypp/ui/SelectableImpl.h index 86f1ecc..b30d772 100644 --- a/zypp/ui/SelectableImpl.h +++ b/zypp/ui/SelectableImpl.h @@ -228,6 +228,9 @@ namespace zypp bool isUnmaintained() const { return availableEmpty(); } + bool multiversionInstall() const + { return theObj().satSolvable().multiversionInstall(); } + bool isUndetermined() const { PoolItem cand( candidateObj() ); @@ -346,7 +349,8 @@ namespace zypp /** \relates Selectable::Impl Stream output */ inline std::ostream & dumpOn( std::ostream & str, const Selectable::Impl & obj ) { - str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status() << endl; + str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status() + << ( obj.multiversionInstall() ? " (multiversion)" : "") << endl; if ( obj.installedEmpty() ) str << " (I 0) {}" << endl << " "; -- 2.7.4