SET(LIBZYPP_MAJOR "17")
SET(LIBZYPP_COMPATMINOR "9")
SET(LIBZYPP_MINOR "10")
-SET(LIBZYPP_PATCH "1")
+SET(LIBZYPP_PATCH "2")
#
-# LAST RELEASED: 17.10.1 (9)
+# LAST RELEASED: 17.10.2 (9)
# (The number in parenthesis is LIBZYPP_COMPATMINOR)
#=======
BuildRequires: pkg-config
%endif
-BuildRequires: libsolv-devel >= 0.7.1
+BuildRequires: libsolv-devel >= 0.7.2
%if 0%{?suse_version} >= 1100
BuildRequires: libsolv-tools
%requires_eq libsolv-tools
%config(noreplace) %{_sysconfdir}/zypp/systemCheck
%config(noreplace) %{_sysconfdir}/logrotate.d/zypp-history.lr
%dir %{_var}/lib/zypp
-%dir %{_var}/log/zypp
+%dir %attr(750,root,root) %{_var}/log/zypp
%dir %{_var}/cache/zypp
%{_prefix}/lib/zypp
%{_datadir}/zypp
-------------------------------------------------------------------
+Mon Dec 10 16:57:34 CET 2018 - ma@suse.de
+
+- commit: set `SYSTEMD_OFFLINE=1` during chrooted commits (bsc#1118758)
+- no-recommends: Nevertheless consider resolver namespaces (hardware,
+ language,..supporting packages) (FATE#325513)
+- BuildRequires: libsolv-devel >= 0.7.2
+ (SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED)
+- Remove world-readable bit from /var/log/zypp (bsc#1099019)
+- version 17.10.2 (9)
+
+-------------------------------------------------------------------
Wed Nov 28 14:40:26 CET 2018 - ma@suse.de
- Adapt to changes in upcoming Boost 1.69.0
--- /dev/null
+<channel><subchannel>
+
+<package>
+ <name>aspell</name>
+ <history>
+ <update>
+ <arch>x86_64</arch>
+ <version>0</version><release>0</release>
+ </update>
+ </history>
+ <recommends>
+ <dep name='aspell-en' />
+ <dep name='recommended-pkg' />
+ </recommends>
+</package>
+
+<package>
+ <name>aspell-en</name>
+ <history>
+ <update>
+ <arch>x86_64</arch>
+ <version>0</version><release>0</release>
+ </update>
+ </history>
+ <provides>
+ <dep name='locale(aspell:en)' />
+ </provides>
+ <supplements>
+ <!--- ignoring '(aspell and namespace:language(en))' -->
+ </supplements>
+</package>
+
+<package>
+ <name>glibc</name>
+ <history>
+ <update>
+ <arch>x86_64</arch>
+ <version>0</version><release>0</release>
+ </update>
+ </history>
+ <provides>
+ <dep name='glibc' op='==' version='0' release='0' />
+ </provides>
+</package>
+</subchannel></channel>
--- /dev/null
+<?xml version="1.0"?>
+<test>
+<setup arch="x86_64">
+ <system file="solver-system.xml"/>
+ <!--
+ - alias : update
+ - url : http://foo.org/distribution/update
+ -->
+ <channel file="update.xml" name="update"/>
+ <locale name="en_US" />
+ <locale name="de" />
+</setup>
+</test>
--- /dev/null
+<channel><subchannel>
+
+<package>
+ <name>aspell</name>
+ <history>
+ <update>
+ <arch>x86_64</arch>
+ <version>1</version><release>1</release>
+ </update>
+ </history>
+ <recommends>
+ <dep name='aspell-en' />
+ <dep name='recommended-pkg' />
+ </recommends>
+</package>
+
+<package>
+ <name>aspell-en</name>
+ <history>
+ <update>
+ <arch>x86_64</arch>
+ <version>1</version><release>1</release>
+ </update>
+ </history>
+ <provides>
+ <dep name='locale(aspell:en)' />
+ </provides>
+ <supplements>
+ <!--- ignoring '(aspell and namespace:language(en))' -->
+ </supplements>
+</package>
+
+<package>
+ <name>aspell-de</name>
+ <history>
+ <update>
+ <arch>x86_64</arch>
+ <version>1</version><release>1</release>
+ </update>
+ </history>
+ <provides>
+ <dep name='locale(aspell:de)' />
+ </provides>
+ <supplements>
+ <!--- ignoring '(aspell and namespace:language(de))' -->
+ </supplements>
+</package>
+
+<package>
+ <name>aspell-fr</name>
+ <history>
+ <update>
+ <arch>x86_64</arch>
+ <version>1</version><release>1</release>
+ </update>
+ </history>
+ <provides>
+ <dep name='locale(aspell:fr)' />
+ </provides>
+ <supplements>
+ <!--- ignoring '(aspell and namespace:language(de))' -->
+ </supplements>
+</package>
+
+<package>
+ <name>recommended-pkg</name>
+ <history>
+ <update>
+ <arch>x86_64</arch>
+ <version>1</version><release>1</release>
+ </update>
+ </history>
+</package>
+
+</subchannel></channel>
RepoManager
RepoStatus
ResKind
+ Resolver
ResStatus
Selectable
SetRelationMixin
--- /dev/null
+#include <boost/test/auto_unit_test.hpp>
+#define BOOST_CHECK_MODULE Resolver
+using namespace boost::unit_test;
+
+#include "TestSetup.h"
+#include "zypp/ResPool.h"
+#include "zypp/ResPoolProxy.h"
+#include "zypp/pool/PoolStats.h"
+#include "zypp/ui/Selectable.h"
+
+static TestSetup test;
+
+struct BAD_TESTCASE {};
+
+typedef std::set<PoolItem> PoolItemSet;
+
+constexpr const unsigned onlyRequires = 0x1;
+constexpr const unsigned inrMode = 0x2;
+
+PoolItemSet resolve( unsigned flags_r = 0 )
+{
+ test.resolver().setOnlyRequires ( flags_r & onlyRequires );
+ test.resolver().setIgnoreAlreadyRecommended( ! ( flags_r & inrMode ) );
+ if ( ! test.resolver().resolvePool() )
+ throw BAD_TESTCASE();
+
+ return { make_filter_begin<resfilter::ByTransact>(test.pool()), make_filter_end<resfilter::ByTransact>(test.pool()) };
+}
+
+inline PoolItem getPi( const std::string & name_r, bool installed_r )
+{
+ for ( const auto & pi : test.pool().byName( name_r ) )
+ { if ( pi.isSystem() == installed_r ) return pi; }
+ throw BAD_TESTCASE();
+}
+inline PoolItem getIPi( const std::string & name_r )
+{ return getPi( name_r, true ); }
+inline PoolItem getAPi( const std::string & name_r )
+{ return getPi( name_r, false ); }
+
+/////////////////////////////////////////////////////////////////////////////
+// Pool content:
+PoolItem Ip; // IA: aspell
+PoolItem Ap;
+PoolItem Ipen; // IA: aspell-en (wanted locale)
+PoolItem Apen;
+PoolItem Apde; // A: aspell-de (wanted locale)
+PoolItem Apfr; // A: aspell-fr (unwanted locale)
+PoolItem Aprec; // A: recommended-pkg (by aspell)
+
+BOOST_AUTO_TEST_CASE(testcase_init)
+{
+ test.loadTestcaseRepos( TESTS_SRC_DIR"/data/TCNamespaceRecommends" );
+ Ip = getIPi( "aspell" );
+ Ap = getAPi( "aspell" );
+ Ipen = getIPi( "aspell-en" );
+ Apen = getAPi( "aspell-en" );
+ Apde = getAPi( "aspell-de" );
+ Apfr = getAPi( "aspell-fr" );
+ Aprec = getAPi( "recommended-pkg" );
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+inline void BOOST_checkresult( const PoolItemSet & resolved_r, const PoolItemSet & expected_r )
+{ BOOST_CHECK_EQUAL( resolved_r, expected_r ); }
+
+
+BOOST_AUTO_TEST_CASE(install)
+{
+ Ap.status().setTransact( true, ResStatus::USER );
+ // Upadte aspell, add all recommends
+ BOOST_checkresult( resolve(), { Ap, Ip, Apde, Aprec } );
+ Ap.status().setTransact( false, ResStatus::USER );
+}
+
+BOOST_AUTO_TEST_CASE(installOnlyRequires)
+{
+ Ap.status().setTransact( true, ResStatus::USER );
+ // Upadte aspell, add only namespace recommends
+ BOOST_checkresult( resolve( onlyRequires ), { Ap, Ip, Apde } );
+ Ap.status().setTransact( false, ResStatus::USER );
+}
+
+BOOST_AUTO_TEST_CASE(inr)
+{
+ // Fillup all recommends
+ BOOST_checkresult( resolve( inrMode ), { Apde, Aprec } );
+}
+
+BOOST_AUTO_TEST_CASE(inrOnlyRequires)
+{
+ // Fillup only namespace recommends
+ BOOST_checkresult( resolve( inrMode|onlyRequires ), { Apde } );
+}
##
-## Whether required packages are installed ONLY
-## So recommended packages, language packages and packages which depend
-## on hardware (modalias) will not be regarded.
+## Whether only required packages are installed.
+##
+## Recommended packages, will not be regarded.
##
## Valid values: boolean
## Default value: false
base/DrunkenBishop.h
base/SerialNumber.h
base/Easy.h
+ base/Env.h
base/Errno.h
base/Random.h
base/Algorithm.h
bool RepoInfo::repoGpgCheck() const
- { return gpgCheck() || _pimpl->cfgRepoGpgCheck(); }
+ { return gpgCheck() || bool(_pimpl->cfgRepoGpgCheck()); }
bool RepoInfo::repoGpgCheckIsMandatory() const
{
- bool ret = ( gpgCheck() && indeterminate(_pimpl->cfgRepoGpgCheck()) ) || _pimpl->cfgRepoGpgCheck();
+ bool ret = ( gpgCheck() && indeterminate(_pimpl->cfgRepoGpgCheck()) ) || bool(_pimpl->cfgRepoGpgCheck());
if ( ret && _pimpl->internalUnsignedConfirmed() ) // relax if unsigned repo was confirmed in the past
ret = false;
return ret;
bool RepoInfo::pkgGpgCheck() const
- { return _pimpl->cfgPkgGpgCheck() || ( gpgCheck() && !bool(validRepoSignature())/*enforced*/ ) ; }
+ { return bool(_pimpl->cfgPkgGpgCheck()) || ( gpgCheck() && !bool(validRepoSignature())/*enforced*/ ) ; }
bool RepoInfo::pkgGpgCheckIsMandatory() const
- { return _pimpl->cfgPkgGpgCheck() || ( gpgCheck() && indeterminate(_pimpl->cfgPkgGpgCheck()) && !bool(validRepoSignature())/*enforced*/ ); }
+ { return bool(_pimpl->cfgPkgGpgCheck()) || ( gpgCheck() && indeterminate(_pimpl->cfgPkgGpgCheck()) && !bool(validRepoSignature())/*enforced*/ ); }
void RepoInfo::setPkgGpgCheck( TriBool value_r )
{ _pimpl->rawPkgGpgCheck( value_r ); }
// Make sure the service repo is created with the appropriate enablement
if ( ! indeterminate(toBeEnabled) )
- it->setEnabled( toBeEnabled );
+ it->setEnabled( ( bool ) toBeEnabled );
DBG << "Service adds repo " << it->alias() << " " << (it->enabled()?"enabled":"disabled") << endl;
addRepository( *it );
void Resolver::setIgnoreAlreadyRecommended( bool yesno_r) { _pimpl->setIgnoreAlreadyRecommended( yesno_r ); }
bool Resolver::ignoreAlreadyRecommended() const { return _pimpl->ignoreAlreadyRecommended(); }
- void Resolver::setInr( ResolverNamespaces namespaces_r ) { _pimpl->setInr( namespaces_r ); }
- void Resolver::resetInr() { setInr( ResolverNamespaces() ); }
- ResolverNamespaces Resolver::inr() const { return _pimpl->inr(); }
-
void Resolver::setOnlyRequires( bool yesno_r ) { _pimpl->setOnlyRequires( yesno_r ); }
void Resolver::resetOnlyRequires() { _pimpl->setOnlyRequires( indeterminate ); }
bool Resolver::onlyRequires() const { return _pimpl->onlyRequires(); }
bool ignoreAlreadyRecommended() const;
/**
- * Weak form of \ref ignoreAlreadyRecommended \c =false.
- * Try to re-evaluate recommendations for specific namespaces only.
- * \note May not support all namespaces.
- */
- void setInr( ResolverNamespaces namespaces_r );
- void resetInr();
- ResolverNamespaces inr() const;
-
- /**
* Setting whether required packages are installed ONLY
* So recommended packages, language packages and packages which depend
* on hardware (modalias) will not be regarded.
/** Return the root set for this target */
Pathname root() const;
+ /** Whether the targets \ref root is not \c "/". */
+ bool chrooted() const
+ { return( ! root().emptyOrRoot() ); }
+
/** Return the path prefixed by the target root, unless it already is prefixed. */
Pathname assertRootPrefix( const Pathname & path_r ) const
{ return Pathname::assertprefix( root(), path_r ); }
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/base/Env.h
+ */
+#ifndef ZYPP_BASE_ENV_H
+#define ZYPP_BASE_ENV_H
+
+#include <cstdlib>
+#include <string>
+#include <memory>
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{
+ ///////////////////////////////////////////////////////////////////
+ namespace env
+ {
+ ///////////////////////////////////////////////////////////////////
+ /// \class ScopedSet
+ /// \brief Temporarily set/unset an environment variable
+ /// \ingroup g_RAII
+ struct ScopedSet
+ {
+ ScopedSet( const ScopedSet & ) = delete;
+ ScopedSet & operator=( const ScopedSet & ) = delete;
+
+ ScopedSet( ScopedSet && ) = default;
+ ScopedSet & operator=( ScopedSet && ) = default;
+
+ public:
+ /** Default ctor (NOOP). */
+ ScopedSet()
+ {}
+
+ /** Set \a var_r to \a val_r (unsets \a var_r if \a val_r is a \c nullptr). */
+ ScopedSet( std::string var_r, const char * val_r )
+ : _var { std::move(var_r) }
+ {
+ if ( !_var.empty() )
+ {
+ if ( const char * orig = ::getenv( _var.c_str() ) )
+ _val.reset( new std::string( orig ) );
+ setval( val_r );
+ }
+ }
+
+ /** Restore the original setting. */
+ ~ScopedSet()
+ {
+ if ( !_var.empty() )
+ setval( _val ? _val->c_str() : nullptr );
+ }
+
+ private:
+ void setval( const char * val_r )
+ {
+ if ( val_r )
+ ::setenv( _var.c_str(), val_r, 1 );
+ else
+ ::unsetenv( _var.c_str() );
+ }
+
+ private:
+ std::string _var;
+ std::unique_ptr<std::string> _val;
+ };
+
+ } // namespace env
+ ///////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_BASE_ENV_H
else
WAR << "No executable " << prog << endl;
}
- return _last;
+ return ( bool ) _last;
}
/******************************************************************
OUTS( _solveSrcPackages );
OUTS( _cleandepsOnRemove );
OUTS( _ignoreAlreadyRecommended );
- OUTS( _inr );
#undef OUT
return os << "<resolver/>";
}
, _solveSrcPackages ( false )
, _cleandepsOnRemove ( ZConfig::instance().solver_cleandepsOnRemove() )
, _ignoreAlreadyRecommended ( true )
- // _inr defaults to ResolverNamespaces()
-
{
sat::Pool satPool( sat::Pool::instance() );
_satResolver = new SATResolver(_pool, satPool.get());
_satResolver->setFixsystem ( isVerifyingMode() );
_satResolver->setIgnorealreadyrecommended ( ignoreAlreadyRecommended() );
- _satResolver->setInr ( inr() );
_satResolver->setOnlyRequires ( onlyRequires() );
_satResolver->setUpdatesystem (_updateMode);
_satResolver->setSolveSrcPackages ( solveSrcPackages() );
bool _cleandepsOnRemove; // whether removing a package should also remove no longer needed requirements
bool _ignoreAlreadyRecommended; //ignore recommended packages that have already been recommended by the installed packages
- ResolverNamespaces _inr; // Try to re-evaluate recommendations for these namespaces
//@}
// Additional QueueItems which has to be regarded by the solver
bool ignoreAlreadyRecommended() const { return _ignoreAlreadyRecommended; }
void setIgnoreAlreadyRecommended( bool yesno_r ) { _ignoreAlreadyRecommended = yesno_r; }
- ResolverNamespaces inr() const { return _inr; }
- void setInr( ResolverNamespaces namespaces_r ) { _inr = namespaces_r; }
-
bool onlyRequires () const { return _onlyRequires; }
void setOnlyRequires( TriBool state_r );
os << " solveSrcPackages = " << _solveSrcPackages << endl;
os << " cleandepsOnRemove = " << _cleandepsOnRemove << endl;
os << " fixsystem = " << _fixsystem << endl;
- os << " inr namespace = " << _inr << endl;
} else {
os << "<NULL>";
}
, _updatesystem(false)
, _noupdateprovide ( false )
, _dosplitprovides ( true )
- , _onlyRequires(ZConfig::instance().solver_onlyRequires())
+ , _onlyRequires (ZConfig::instance().solver_onlyRequires())
, _ignorealreadyrecommended(true)
, _distupgrade(false)
, _distupgrade_removeunsupported(false)
solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
solver_set_flag(_satSolver, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
solver_set_flag(_satSolver, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
- solver_set_flag(_satSolver, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
+ solver_set_flag(_satSolver, SOLVER_FLAG_IGNORE_RECOMMENDED, false); // resolve recommended namespaces
+ solver_set_flag(_satSolver, SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED, _onlyRequires); //
solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_DOWNGRADE, _dup_allowdowngrade );
solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_NAMECHANGE, _dup_allownamechange );
solver_set_flag(_satSolver, SOLVER_FLAG_DUP_ALLOW_ARCHCHANGE, _dup_allowarchchange );
}
// Ad rules for changed requestedLocales
- const auto & trackedLocaleIds( myPool().trackedLocaleIds() );
- if ( _inr.testFlag( ResolverNamespace::language ) )
- {
- // inr mode
- for ( const auto & locale : trackedLocaleIds.current() )
- {
- queue_push( &(_jobQueue), SOLVER_INSTALL | SOLVER_SOLVABLE_PROVIDES );
- queue_push( &(_jobQueue), Capability( ResolverNamespace::language, IdString(locale) ).id() );
- }
- // TODO cleanup not requested locale packages?
- }
- else
{
+ const auto & trackedLocaleIds( myPool().trackedLocaleIds() );
+
// just track changed locakes
for ( const auto & locale : trackedLocaleIds.added() )
{
solver_set_flag(_satSolver, SOLVER_FLAG_ALLOW_UNINSTALL, _allowuninstall);
solver_set_flag(_satSolver, SOLVER_FLAG_NO_UPDATEPROVIDE, _noupdateprovide);
solver_set_flag(_satSolver, SOLVER_FLAG_SPLITPROVIDES, _dosplitprovides);
- solver_set_flag(_satSolver, SOLVER_FLAG_IGNORE_RECOMMENDED, _onlyRequires);
+ solver_set_flag(_satSolver, SOLVER_FLAG_IGNORE_RECOMMENDED, false); // resolve recommended namespaces
+ solver_set_flag(_satSolver, SOLVER_FLAG_ONLY_NAMESPACE_RECOMMENDED, _onlyRequires); //
sat::Pool::instance().prepare();
bool _updatesystem:1; // update
bool _noupdateprovide:1; // true: update packages needs not to provide old package
bool _dosplitprovides:1; // true: consider legacy split provides
- bool _onlyRequires:1; // true: consider required packages only
+ bool _onlyRequires:1; // true: consider required packages only (but recommended namespaces)
bool _ignorealreadyrecommended:1; // true: ignore recommended packages that were already recommended by the installed packages
bool _distupgrade:1;
bool _distupgrade_removeunsupported:1;
bool _cleandepsOnRemove:1; // whether removing a package should also remove no longer needed requirements
private:
- ResolverNamespaces _inr; // Try to re-evaluate recommendations for these namespaces
- private:
// ---------------------------------- methods
std::string SATprobleminfoString (Id problem, std::string &detail, Id &ignoreId);
void resetItemTransaction (PoolItem item);
bool ignorealreadyrecommended () const {return _ignorealreadyrecommended;}
void setIgnorealreadyrecommended ( const bool ignorealreadyrecommended) { _ignorealreadyrecommended = ignorealreadyrecommended;}
- ResolverNamespaces inr() const { return _inr; }
- void setInr( ResolverNamespaces namespaces_r ) { _inr = namespaces_r; }
-
bool distupgrade () const {return _distupgrade;}
void setDistupgrade ( const bool distupgrade) { _distupgrade = distupgrade;}
void deleteResolvable( const PoolItem & pi_r );
void addDependencies (const CapabilitySet &capRequire, const CapabilitySet &capConflict);
void addUpgradeRepos( const std::set<Repository> & upgradeRepos_r );
- void addInr( ResolverNamespaces namespaces_r );
std::string filename () { return dumpFile; }
};
}
}
-void HelixControl::addInr( ResolverNamespaces namespaces_r )
-{
- if ( namespaces_r )
- *file << "<inrNamespaces str=\"" << namespaces_r << "\" int=\"" << str::numstring((namespaces_r)) << "\"/>" << endl;
-}
-
//---------------------------------------------------------------------------
Testcase::Testcase()
control.addDependencies (SystemCheck::instance().requiredSystemCap(),
SystemCheck::instance().conflictSystemCap());
control.addUpgradeRepos( resolver.upgradeRepos() );
- control.addInr( resolver.inr() );
control.addTagIf( "distupgrade", resolver.isUpgradeMode() );
control.addTagIf( "update", resolver.isUpdateMode() );
return true;
});
}
-
- INT << "Needreboot " << needrebootSpec << endl;
satpool.setNeedrebootSpec( std::move(needrebootSpec) );
}
#include "zypp/TmpPath.h"
#include "zypp/base/Logger.h"
#include "zypp/base/String.h"
+#include "zypp/base/Env.h"
#include "zypp/zypp_detail/ZYppImpl.h"
#include "zypp/target/TargetImpl.h"
* and target used for transact. */
ZYppCommitResult ZYppImpl::commit( const ZYppCommitPolicy & policy_r )
{
- setenv( "ZYPP_IS_RUNNING", str::numstring(getpid()).c_str(), 1 );
-
if ( getenv("ZYPP_TESTSUITE_FAKE_ARCH") )
{
ZYPP_THROW( Exception("ZYPP_TESTSUITE_FAKE_ARCH set. Commit not allowed and disabled.") );
if (! _target)
ZYPP_THROW( Exception("Target not initialized.") );
+
+ env::ScopedSet ea { "ZYPP_IS_RUNNING", str::numstring(getpid()).c_str() };
+ env::ScopedSet eb;
+ if ( _target->chrooted() )
+ eb = env::ScopedSet( "SYSTEMD_OFFLINE", "1" ); // bsc#1118758 - indicate no systemd if chrooted install
+
ZYppCommitResult res = _target->_pimpl->commit( pool(), policy_r );
if (! policy_r.dryRun() )