#
SET(LIBZYPP_MAJOR "15")
SET(LIBZYPP_COMPATMINOR "19")
-SET(LIBZYPP_MINOR "20")
+SET(LIBZYPP_MINOR "21")
SET(LIBZYPP_PATCH "0")
#
-# LAST RELEASED: 15.20.0 (19)
+# LAST RELEASED: 15.21.0 (19)
# (The number in parenthesis is LIBZYPP_COMPATMINOR)
#=======
-------------------------------------------------------------------
+Wed Jan 20 17:12:42 CET 2016 - ma@suse.de
+
+- Filter unwanted btrfs subvolumes (fixes #54, closes #55, bnc#949945)
+- RepoInfo: Provide access to repo content keywords
+- Build with boost-1.60.0
+- version 15.21.0 (19)
+
+-------------------------------------------------------------------
+Thu Jan 14 01:13:17 CET 2016 - ma@suse.de
+
+- Update zypp-po.tar.bz2
+
+-------------------------------------------------------------------
+Thu Jan 7 01:13:28 CET 2016 - ma@suse.de
+
+- Update zypp-po.tar.bz2
+
+-------------------------------------------------------------------
+Thu Dec 24 01:13:13 CET 2015 - ma@suse.de
+
+- Update zypp-po.tar.bz2
+
+-------------------------------------------------------------------
Fri Dec 11 19:07:09 CET 2015 - ma@suse.de
- ResPoolProxy: make begin/end pairs Iterable
#include "zypp/Arch.h"
// Boost.Test
-#include <boost/test/floating_point_comparison.hpp>
#include <boost/test/auto_unit_test.hpp>
using boost::unit_test::test_suite;
using boost::unit_test::test_case;
-using boost::test_tools::close_at_tolerance;
using namespace std;
using namespace zypp;
#include <string>
// Boost.Test
-#include <boost/test/floating_point_comparison.hpp>
#include <boost/test/auto_unit_test.hpp>
#include "TestSetup.h"
using boost::unit_test::test_suite;
using boost::unit_test::test_case;
-using boost::test_tools::close_at_tolerance;
using namespace std;
using namespace zypp;
cerr << " -o/-O turn on/off looking for obsoletes (default off)" << endl;
cerr << " -m/-M turn on/off looking for recommends (default off)" << endl;
cerr << " -s/-S turn on/off looking for supplements (default off)" << endl;
+ cerr << " -e/-E turn on/off looking for enhan./sugg.(default off)" << endl;
cerr << " -a short for -n -p -r" << endl;
cerr << " -A short for -n -P -R" << endl;
cerr << " -D <pkg> dump dependencies of <pkg>" << endl;
bool obsoletes ( false );
bool recommends ( false );
bool supplements ( false );
+ bool enhacements ( false );
for ( ; argc; --argc,++argv )
{
case 'M': recommends = false; break;
case 's': supplements = true; break;
case 'S': supplements = false; break;
+ case 'e': enhacements = true; break;
+ case 'E': enhacements = false; break;
}
continue;
}
q.addDependency( sat::SolvAttr::recommends );
if ( supplements )
q.addDependency( sat::SolvAttr::supplements );
+ if ( enhacements )
+ {
+ q.addDependency( sat::SolvAttr::enhances );
+ q.addDependency( sat::SolvAttr::suggests );
+ }
}
message << *argv << " [" << (ignorecase?'i':'_') << (names?'n':'_') << (requires?'r':'_') << (provides?'p':'_')
- << (conflicts?'c':'_') << (obsoletes?'o':'_') << (recommends?'m':'_') << (supplements?'s':'_') << "] {" << endl;
+ << (conflicts?'c':'_') << (obsoletes?'o':'_') << (recommends?'m':'_') << (supplements?'s':'_') << (enhacements?'e':'_')
+ << "] {" << endl;
for_( it, q.begin(), q.end() )
{
{
DiskUsageCounter::MountPointSet ret;
+ typedef std::map<ulong, MountPoint> Btrfsfilter;
+ Btrfsfilter btrfsfilter; // see btrfs hack below
+
std::ifstream procmounts( "/proc/mounts" );
if ( !procmounts ) {
//
const char * mpunwanted[] = {
"/mnt", "/media", "/mounts", "/floppy", "/cdrom",
- "/suse", "/var/tmp", "/var/adm/mount", "/var/adm/YaST",
+ "/suse", "/tmp", "/var/tmp", "/var/adm/mount", "/var/adm/YaST",
/*last*/0/*entry*/
};
//
// check for snapshotting btrfs
//
+ bool btrfshack = false;
if ( words[2] == "btrfs" )
{
+ btrfshack = true;
if ( geteuid() != 0 )
{
DBG << "Assume snapshots on " << words[1] << ": non-root user can't check" << std::endl;
DBG << "Filter zero-sized mount point : " << l << std::endl;
continue;
}
+ if ( btrfshack )
+ {
+ // HACK:
+ // Collect just the top/1st mountpoint of each btrfs volume
+ // (by file system ID). This filters away nested subvolumes
+ // which otherwise break per package disk usage computation.
+ // FIX: Computation must learn to handle multiple mount points
+ // contributing to the same file system.
+ MountPoint & bmp( btrfsfilter[sb.f_fsid] );
+ if ( bmp.fstype.empty() ) // 1st occurance
+ {
+ bmp = DiskUsageCounter::MountPoint( mp, words[2], sb.f_bsize,
+ ((long long)sb.f_blocks)*sb.f_bsize/1024,
+ ((long long)(sb.f_blocks - sb.f_bfree))*sb.f_bsize/1024, 0LL, hints );
+ }
+ else if ( bmp.dir > mp )
+ bmp.dir = mp;
+ continue;
+ }
ret.insert( DiskUsageCounter::MountPoint( mp, words[2], sb.f_bsize,
((long long)sb.f_blocks)*sb.f_bsize/1024,
((long long)(sb.f_blocks - sb.f_bfree))*sb.f_bsize/1024, 0LL, hints ) );
}
}
+ // collect filtered btrfs volumes
+ for ( auto && bmp : btrfsfilter )
+ ret.insert( std::move(bmp.second) );
+
return ret;
}
{ return !emptybaseurls && !_baseUrls.empty(); }
+ const std::set<std::string> & contentKeywords() const
+ { hasContent()/*init if not yet done*/; return _keywords.second; }
+
void addContent( const std::string & keyword_r )
- { _keywords.insert( keyword_r ); }
+ { _keywords.second.insert( keyword_r ); if ( ! hasContent() ) _keywords.first = true; }
- bool hasContent( const std::string & keyword_r ) const
+ bool hasContent() const
{
- if ( _keywords.empty() && ! metadatapath.empty() )
+ if ( !_keywords.first && ! metadatapath.empty() )
{
// HACK directly check master index file until RepoManager offers
- // some content probing ans zypepr uses it.
+ // some content probing and zypper uses it.
/////////////////////////////////////////////////////////////////
MIL << "Empty keywords...." << metadatapath << endl;
Pathname master;
xml::Reader reader( master );
while ( reader.seekToNode( 2, "content" ) )
{
- _keywords.insert( reader.nodeText().asString() );
+ _keywords.second.insert( reader.nodeText().asString() );
reader.seekToEndNode( 2, "content" );
}
- _keywords.insert( "" ); // valid content in _keywords even if empty
+ _keywords.first = true; // valid content in _keywords even if empty
}
else if ( PathInfo( (master=metadatapath/"/content") ).isFile() )
{
if ( str::split( line_r, std::back_inserter(words) ) > 1
&& words[0].length() == 12 /*"REPOKEYWORDS"*/ )
{
- this->_keywords.insert( ++words.begin(), words.end() );
+ this->_keywords.second.insert( ++words.begin(), words.end() );
}
return true; // mult. occurrances are ok.
}
return( ! str::startsWith( line_r, "META " ) ); // no need to parse into META section.
} );
- _keywords.insert( "" );
+ _keywords.first = true; // valid content in _keywords even if empty
}
/////////////////////////////////////////////////////////////////
}
- return( _keywords.find( keyword_r ) != _keywords.end() );
+ return _keywords.first;
}
+ bool hasContent( const std::string & keyword_r ) const
+ { return( hasContent() && _keywords.second.find( keyword_r ) != _keywords.second.end() ); }
+
/** Signature check result needs to be stored/retrieved from _metadatapath.
* Don't call them from outside validRepoSignature/setValidRepoSignature
*/
private:
mutable RepoVariablesReplacedUrlList _baseUrls;
- mutable std::set<std::string> _keywords;
+ mutable std::pair<FalseBool, std::set<std::string> > _keywords;
friend Impl * rwcowClone<Impl>( const Impl * rhs );
/** clone for RWCOW_pointer */
bool RepoInfo::baseUrlSet() const
{ return _pimpl->baseurl2dump(); }
+ const std::set<std::string> & RepoInfo::contentKeywords() const
+ { return _pimpl->contentKeywords(); }
void RepoInfo::addContent( const std::string & keyword_r )
{ _pimpl->addContent( keyword_r ); }
+ bool RepoInfo::hasContent() const
+ { return _pimpl->hasContent(); }
+
bool RepoInfo::hasContent( const std::string & keyword_r ) const
{ return _pimpl->hasContent( keyword_r ); }
*/
void setTargetDistribution(const std::string & targetDistribution);
+
+ /** Content keywords defined. */
+ const std::set<std::string> & contentKeywords() const;
+
/** Add content keywords */
void addContent( const std::string & keyword_r );
/** \overload add keywords from container */
{ addContentFrom( container_r.begin(), container_r.end() ); }
/** Check for content keywords.
- * Checking for an empty string returns whether content kewords are
- * known at all. They may be missing due to missing metadata in disabled
- * repos.
+ * They may be missing due to missing metadata in disabled repos.
*/
- bool hasContent( const std::string & keyword_r = std::string() ) const;
+ bool hasContent() const;
+ /** \overload check for a keywords being present */
+ bool hasContent( const std::string & keyword_r ) const;
/** \overload check for \b all keywords being present */
template <class TIterator>
bool hasContentAll( TIterator begin_r, TIterator end_r ) const