# See './mkChangelog -h' for help.
#
SET(LIBZYPP_MAJOR "15")
-SET(LIBZYPP_COMPATMINOR "2")
-SET(LIBZYPP_MINOR "2")
+SET(LIBZYPP_COMPATMINOR "3")
+SET(LIBZYPP_MINOR "3")
SET(LIBZYPP_PATCH "0")
#
-# LAST RELEASED: 15.2.0 (2)
+# LAST RELEASED: 15.3.0 (3)
# (The number in parenthesis is LIBZYPP_COMPATMINOR)
#=======
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/zypp/repos.d
%endif
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/zypp/services.d
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/zypp/systemCheck.d
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/zypp/vendors.d
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/zypp/multiversion.d
mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/zypp
%dir %{_sysconfdir}/zypp/repos.d
%endif
%dir %{_sysconfdir}/zypp/services.d
+%dir %{_sysconfdir}/zypp/systemCheck.d
%dir %{_sysconfdir}/zypp/vendors.d
%dir %{_sysconfdir}/zypp/multiversion.d
%config(noreplace) %{_sysconfdir}/zypp/zypp.conf
-------------------------------------------------------------------
+Sun May 24 18:17:38 CEST 2015 - ma@suse.de
+
+- Downloader: Accept unsigned repository if pkgGpgCheck is ON.
+- FindFileConflicts: avoid nested exception on user abort (bnc#931601)
+- Support for *.check files in the systemCheck.d directory (#45)
+- version 15.3.0 (3)
+
+-------------------------------------------------------------------
+Sun May 24 01:13:19 CEST 2015 - ma@suse.de
+
+- Update zypp-po.tar.bz2
+
+-------------------------------------------------------------------
Mon May 18 10:46:10 CEST 2015 - ma@suse.de
- zypp.conf: Add config values for gpgcheck, repo_gpgcheck
# solver.checkSystemFile = /etc/zypp/systemCheck
##
+## This directory can contain files that contain requirements/conflicts
+## which fulfill the needs of a running system (see checkSystemFile).
+##
+## Files are read in alphabetical order.
+##
+## Default value: {configdir}/systemCheck.d
+##
+# solver.checkSystemFileDir = /etc/zypp/systemCheck.d
+
+##
## When committing a dist upgrade (e.g. 'zypper dup') a solver testcase
## is written to /var/log/updateTestcase-<date>. It is needed in bugreports.
## This option returns the number of testcases to keep on the system. Old
{
if ( PathInfo(metadatapath).isDir() )
{
- TriBool linkval( indeterminate );
- if ( triBoolFromPath( metadatapath / ".repo_gpgcheck", linkval ) && linkval == value_r )
- return; // existing symlink fits value_r
-
- filesystem::unlink( metadatapath / ".repo_gpgcheck" );
- filesystem::symlink( asString(value_r), metadatapath / ".repo_gpgcheck" );
+ Pathname gpgcheckFile( metadatapath / ".repo_gpgcheck" );
+ if ( PathInfo(gpgcheckFile).isExist() )
+ {
+ TriBool linkval( indeterminate );
+ if ( triBoolFromPath( gpgcheckFile, linkval ) && linkval == value_r )
+ return; // existing symlink fits value_r
+ else
+ filesystem::unlink( gpgcheckFile ); // will write a new one
+ }
+ filesystem::symlink( asString(value_r), gpgcheckFile );
}
_validRepoSignature = value_r;
}
{
solver_checkSystemFile = Pathname(value);
}
+ else if ( entry == "solver.checkSystemFileDir" )
+ {
+ solver_checkSystemFileDir = Pathname(value);
+ }
else if ( entry == "multiversion" )
{
str::split( value, inserter( _multiversion, _multiversion.end() ), ", \t" );
DefaultOption<bool> solverUpgradeRemoveDroppedPackages;
Pathname solver_checkSystemFile;
+ Pathname solver_checkSystemFileDir;
std::set<std::string> & multiversion() { return getMultiversion(); }
const std::set<std::string> & multiversion() const { return getMultiversion(); }
{ return ( _pimpl->solver_checkSystemFile.empty()
? (configPath()/"systemCheck") : _pimpl->solver_checkSystemFile ); }
+ Pathname ZConfig::solver_checkSystemFileDir() const
+ { return ( _pimpl->solver_checkSystemFileDir.empty()
+ ? (configPath()/"systemCheck.d") : _pimpl->solver_checkSystemFileDir ); }
+
unsigned ZConfig::solver_upgradeTestcasesToKeep() const
{ return _pimpl->solver_upgradeTestcasesToKeep; }
Pathname solver_checkSystemFile() const;
/**
+ * Directory, which may or may not contain files in which
+ * dependencies described which has to be fulfilled for a
+ * running system.
+ */
+ Pathname solver_checkSystemFileDir() const;
+
+ /**
* Whether vendor check is by default enabled.
*/
bool solver_allowVendorChange() const;
* Userdata sent:
* \param "Package" Package::constPtr of the package
* \param "Localpath" Pathname to downloaded package on disk
- * \param "CheckPackageResult" RpmDb::checkPackageResult of signature check
+ * \param "CheckPackageResult" RpmDb::CheckPackageResult of signature check
* \param "CheckPackageDetail" RpmDb::CheckPackageDetail logmessages of rpm signature check
*
* Userdata accepted:
* \param "Action" DownloadResolvableReport::Action user advice how to behave on error (ABORT).
+ * If you set just an empty value here, a default probelm report will be triggered.
*/
virtual void pkgGpgCheck( const UserData & userData_r = UserData() )
{}
if ( repoInfo().repoGpgCheck() )
{
- // only add the signature if it exists
- if ( isSigned )
- sigchecker = SignatureFileChecker( destdir_r / sigpath );
-
- KeyContext context;
- context.setRepoInfo( repoInfo() );
- // only add the key if it exists
- if ( PathInfo(destdir_r / keypath).isExist() )
- sigchecker.addPublicKey( destdir_r / keypath, context );
+ if ( isSigned || !repoInfo().pkgGpgCheck() )
+ {
+ // only add the signature if it exists
+ if ( isSigned )
+ sigchecker = SignatureFileChecker( destdir_r / sigpath );
+
+ KeyContext context;
+ context.setRepoInfo( repoInfo() );
+ // only add the key if it exists
+ if ( PathInfo(destdir_r / keypath).isExist() )
+ sigchecker.addPublicKey( destdir_r / keypath, context );
+ else
+ // set the checker context even if the key is not known (unsigned repo, key
+ // file missing; bnc #495977)
+ sigchecker.setKeyContext( context );
+
+ checker = FileChecker( ref(sigchecker) ); // ref() to the local sigchecker is important as we want back fileValidated!
+ }
else
- // set the checker context even if the key is not known (unsigned repo, key
- // file missing; bnc #495977)
- sigchecker.setKeyContext( context );
-
- checker = FileChecker( ref(sigchecker) ); // ref() to the local sigchecker is important as we want back fileValidated!
+ {
+ WAR << "Accept unsigned repository because pkgGpgCheck is on for " << repoInfo().alias() << endl;
+ }
}
else
{
typedef target::rpm::RpmDb RpmDb;
- RpmDb::checkPackageResult packageSigCheck( const Pathname & path_r, UserData & userData ) const
+ RpmDb::CheckPackageResult packageSigCheck( const Pathname & path_r, UserData & userData ) const
{
if ( !_target )
_target = getZYpp()->getTarget();
- RpmDb::checkPackageResult ret = RpmDb::CHK_ERROR;
+ RpmDb::CheckPackageResult ret = RpmDb::CHK_ERROR;
RpmDb::CheckPackageDetail detail;
if ( _target )
ret = _target->rpmDb().checkPackage( path_r, detail );
}
/** Default signature verrification error handling. */
- void defaultReportSignatureError( RpmDb::checkPackageResult ret ) const
+ void defaultReportSignatureError( RpmDb::CheckPackageResult ret ) const
{
std::string msg( str::Str() << _package->asUserString() << ": " << _("Signature verification failed") << " " << ret );
resolveSignatureErrorAction( report()->problem( _package, repo::DownloadResolvableReport::INVALID, msg ) );
UserData userData( "pkgGpgCheck" );
userData.set( "Package", _package );
userData.set( "Localpath", ret.value() );
- RpmDb::checkPackageResult res = packageSigCheck( ret, userData );
+ RpmDb::CheckPackageResult res = packageSigCheck( ret, userData );
// publish the checkresult, even if it is OK. Apps may want to report something...
report()->pkgGpgCheck( userData );
if ( res != RpmDb::CHK_OK )
{
- if ( userData.hasvalue( "Action" ) ) // pkgGpgCheck provided an user error action
+ if ( userData.hasvalue( "Action" ) ) // pkgGpgCheck report provided an user error action
{
resolveSignatureErrorAction( userData.get( "Action", repo::DownloadResolvableReport::ABORT ) );
}
+ else if ( userData.haskey( "Action" ) ) // pkgGpgCheck requests the default problem report
+ {
+ defaultReportSignatureError( res );
+ }
else // no advice from user => usedefaults
{
switch ( res )
case RpmDb::CHK_NOKEY: // Public key is unavailable
case RpmDb::CHK_NOTFOUND: // Signature is unknown type
- case RpmDb::CHK_NOTTRUSTED: // Signature is OK, but key is not trusted
- // should fail in future versions.
- break;
-
case RpmDb::CHK_FAIL: // Signature does not verify
+ case RpmDb::CHK_NOTTRUSTED: // Signature is OK, but key is not trusted
case RpmDb::CHK_ERROR: // File does not exist or can't be opened
+ default:
// report problem, throw if to abort, else retry/ignore
defaultReportSignatureError( res );
break;
{ /////////////////////////////////////////////////////////////////
Pathname _file = "";
+ Pathname _dir = "";
CapabilitySet _require;
CapabilitySet _conflict;
}
- SystemCheck::SystemCheck() {
+ SystemCheck::SystemCheck() {
if (_file.empty()) {
_file = ZConfig::instance().solver_checkSystemFile();
- loadFile();
+ loadFile(_file);
}
+ if (_dir.empty()) {
+ _dir = ZConfig::instance().solver_checkSystemFileDir();
+ loadFiles();
+ }
}
bool SystemCheck::setFile(const Pathname & file) const{
MIL << "Setting checkFile to : " << file << endl;
_file = file;
- loadFile();
+ loadFile(_file);
return true;
}
+ bool SystemCheck::setDir(const Pathname & dir) const {
+ MIL << "Setting checkFile directory to : " << dir << endl;
+ loadFile(_file);
+ _dir = dir;
+ loadFiles();
+ return true;
+ }
+
const Pathname & SystemCheck::file() {
return _file;
}
+ const Pathname & SystemCheck::dir() {
+ return _dir;
+ }
+
const CapabilitySet & SystemCheck::requiredSystemCap() const{
return _require;
}
return _conflict;
}
- bool SystemCheck::loadFile() const{
+ bool SystemCheck::loadFile(Pathname & file, bool reset_caps) const{
Target_Ptr trg( getZYpp()->getTarget() );
if ( trg )
- _file = trg->assertRootPrefix( _file );
+ file = trg->assertRootPrefix( file );
- PathInfo pi( _file );
+ PathInfo pi( file );
if ( ! pi.isFile() ) {
- WAR << "Can't read " << _file << " " << pi << endl;
+ WAR << "Can't read " << file << " " << pi << endl;
return false;
}
- _require.clear();
- _conflict.clear();
+ if (reset_caps) {
+ _require.clear();
+ _conflict.clear();
+ }
- std::ifstream infile( _file.c_str() );
+ std::ifstream infile( file.c_str() );
for( iostr::EachLine in( infile ); in; in.next() ) {
std::string l( str::trim(*in) );
if ( ! l.empty() && l[0] != '#' )
return true;
}
+ bool SystemCheck::loadFiles() const {
+
+ filesystem::dirForEach(_dir,
+ [this](const Pathname & dir_r, const char *const & name_r)->bool
+ {
+ const std::string wanted = ".check";
+ Pathname pth = dir_r/name_r;
+ if (pth.extension() != wanted) {
+ MIL << "Skipping " << pth << " (not a *.check file)" << endl;
+ return true;
+ }
+ else {
+ MIL << "Reading " << pth << endl;
+ return loadFile(pth, false /* do not reset caps */);
+ }
+ });
+ return true;
+ }
+
/******************************************************************
**
/** Return the file path. */
const Pathname & file();
+ /** Return the directory path. */
+ const Pathname & dir();
+
/** Set configuration file of system requirements
* Should be used for testcase only
*/
bool setFile(const Pathname & file) const;
+ /** Set configuration directory for files of system
+ * requirements.
+ * Should be used for testcase only
+ */
+ bool setDir(const Pathname & dir) const;
+
/** Returns a list of required system capabilities.
*/
const CapabilitySet & requiredSystemCap() const;
private:
/** Ctor taking the file to read. */
SystemCheck();
- bool loadFile() const;
-
+ bool loadFile(Pathname &file, bool reset_caps = true) const;
+ bool loadFiles() const;
};
///////////////////////////////////////////////////////////////////
// lambda receives progress trigger and translates into report
auto sendProgress = [&]( const ProgressData & progress_r )->bool {
if ( ! report->progress( progress_r, cb.noFilelist() ) )
+ {
+ progress.noSend(); // take care progress DTOR does not trigger a final report (2nd exeption)
ZYPP_THROW( AbortRequestException() );
+ }
return true;
};
progress.sendTo( sendProgress );
///////////////////////////////////////////////////////////////////
//
// METHOD NAME : RpmDb::checkPackage
-// METHOD TYPE : RpmDb::checkPackageResult
+// METHOD TYPE : RpmDb::CheckPackageResult
//
-RpmDb::checkPackageResult RpmDb::checkPackage( const Pathname & path_r, CheckPackageDetail & detail_r )
+RpmDb::CheckPackageResult RpmDb::checkPackage( const Pathname & path_r, CheckPackageDetail & detail_r )
{
PathInfo file( path_r );
if ( ! file.isFile() )
for ( unsigned i = 1; i < lines.size(); ++i )
{
std::string & line( lines[i] );
- checkPackageResult lineres = CHK_ERROR;
+ CheckPackageResult lineres = CHK_ERROR;
if ( line.find( ": OK" ) != std::string::npos )
{ lineres = CHK_OK; }
else if ( line.find( ": NOKEY" ) != std::string::npos )
detail_r.push_back( CheckPackageDetail::value_type( lineres, std::move(line) ) );
}
- checkPackageResult ret = CHK_ERROR;
+ CheckPackageResult ret = CHK_ERROR;
if ( count[CHK_FAIL] )
ret = CHK_FAIL;
return ret;
}
-RpmDb::checkPackageResult RpmDb::checkPackage( const Pathname & path_r )
+RpmDb::CheckPackageResult RpmDb::checkPackage( const Pathname & path_r )
{ CheckPackageDetail dummy; return checkPackage( path_r, dummy ); }
_backuppath = path;
}
-std::ostream & operator<<( std::ostream & str, RpmDb::checkPackageResult obj )
+std::ostream & operator<<( std::ostream & str, RpmDb::CheckPackageResult obj )
{
switch ( obj )
{
* checkPackage result
* @see checkPackage
* */
- enum checkPackageResult
+ enum CheckPackageResult
{
CHK_OK = 0, /*!< Signature is OK. */
CHK_NOTFOUND = 1, /*!< Signature is unknown type. */
/** Detailed rpm signature check log messages
* A single multiline message if \ref CHK_OK. Otherwise each message line
- * together with it's \ref checkPackageResult.
+ * together with it's \ref CheckPackageResult.
*/
- struct CheckPackageDetail : std::vector<std::pair<checkPackageResult,std::string>>
+ struct CheckPackageDetail : std::vector<std::pair<CheckPackageResult,std::string>>
{};
/**
* @param path_r which file to check
* @param detail_r Return detailed rpm log messages
*
- * @return checkPackageResult
+ * @return CheckPackageResult
*/
- checkPackageResult checkPackage( const Pathname & path_r, CheckPackageDetail & detail_r );
+ CheckPackageResult checkPackage( const Pathname & path_r, CheckPackageDetail & detail_r );
/** \overload Ignoring the \a datails_r */
- checkPackageResult checkPackage( const Pathname & path_r );
+ CheckPackageResult checkPackage( const Pathname & path_r );
/** install rpm package
*
void doRebuildDatabase(callback::SendReport<RebuildDBReport> & report);
};
-/** \relates RpmDb::checkPackageResult Stream output */
-std::ostream & operator<<( std::ostream & str, RpmDb::checkPackageResult obj );
+/** \relates RpmDb::CheckPackageResult Stream output */
+std::ostream & operator<<( std::ostream & str, RpmDb::CheckPackageResult obj );
/** \relates RpmDb::checkPackageDetail Stream output */
std::ostream & operator<<( std::ostream & str, const RpmDb::CheckPackageDetail & obj );