libzypp  17.24.1
PurgeKernels.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
13 #include <zypp/base/String.h>
14 #include <zypp/base/Logger.h>
15 #include <zypp/base/Regex.h>
16 #include <zypp/base/Iterator.h>
17 #include <zypp/ui/Selectable.h>
18 #include <zypp/PurgeKernels.h>
19 #include <zypp/PoolQuery.h>
20 #include <zypp/ResPool.h>
21 #include <zypp/Resolver.h>
22 #include <zypp/Filter.h>
23 #include <zypp/ZConfig.h>
24 
25 #include <iostream>
26 #include <fstream>
27 #include <map>
28 #include <unordered_map>
29 #include <sys/utsname.h>
30 #include <functional>
31 #include <array>
32 
33 #undef ZYPP_BASE_LOGGER_LOGGROUP
34 #define ZYPP_BASE_LOGGER_LOGGROUP "PurgeKernels"
35 
36 namespace zypp {
37 
38  using Flavour = std::string;
39  using SolvableList = std::list<sat::Solvable::IdType>;
40  using EditionToSolvableMap = std::map<Edition, SolvableList >;
41  using ArchToEditionMap = std::map<Arch, EditionToSolvableMap >;
42 
43  struct GroupInfo {
44 
45  enum GroupType {
46  None, //<< Just here to support default construction
47  Kernels, //<< Map contains kernel packages, so need to receive special handling and flavour matching
48  RelatedBinaries, //<< Map contains related binary packages, so need to receive special handling and flavour matching
49  Sources //<< Map contains source packages, so when matching those against running we ignore the flavour
50  } groupType;
51 
52  GroupInfo( const GroupType type = None, std::string flav = "") : groupType(type), groupFlavour( std::move(flav) ) { }
53 
54  ArchToEditionMap archToEdMap; //<< Map of actual packages
55  std::string groupFlavour; //<< This would contain a specific flavour if there is one calculated
56  };
57  using GroupMap = std::unordered_map<std::string, GroupInfo>;
58 
60 
61  Impl() {
62  struct utsname unameData;
63  if ( uname( &unameData) == 0 ) {
64 
65  const auto archStr = str::regex_substitute( unameData.machine, str::regex( "^i.86$", str::regex::match_extended ), "i586" );
66 
67  _kernelArch = Arch( archStr );
68  setUnameR( std::string( unameData.release ) );
69 
70  _detectedRunning = true;
71 
72  MIL << "Detected running kernel: " << _runningKernelEdition << " " << _runningKernelFlavour << " " << _kernelArch << std::endl;
73 
74  } else {
75  MIL << "Failed to detect running kernel: " << errno << std::endl;
76  }
77  }
78 
79  void setUnameR ( const std::string &uname ) {
80 
81  _uname_r = uname;
82 
83  MIL << "Set uname " << uname << std::endl;
84 
85  const std::string flavour = str::regex_substitute( _uname_r, str::regex( ".*-", str::regex::match_extended ), "", true );
86  std::string version = str::regex_substitute( _uname_r, str::regex( "-[^-]*$", str::regex::match_extended | str::regex::newline ), "", true );
87 
88  const std::string release = str::regex_substitute( version, str::regex( ".*-", str::regex::match_extended ), "", true );
89 
90  version = str::regex_substitute( version, str::regex( "-[^-]*$", str::regex::match_extended | str::regex::newline ), "", true );
91 
92  // from purge-kernels script, was copied from kernel-source/rpm/mkspec
93  version = str::regex_substitute( version, str::regex( "\\.0-rc", str::regex::match_extended ), ".rc", true );
94  version = str::regex_substitute( version, str::regex( "-rc\\d+", str::regex::match_extended ), "", true );
95  version = str::regex_substitute( version, str::regex( "-", str::regex::match_extended ), ".", true );
96 
97  _runningKernelEdition = Edition( version, release );
98  _runningKernelFlavour = flavour;
99 
100  MIL << "Parsed info from uname: " << std::endl;
101  MIL << "Kernel Flavour: " << _runningKernelFlavour << std::endl;
102  MIL << "Kernel Edition: " << _runningKernelEdition << std::endl;
103  }
104 
105  bool removePackageAndCheck( const sat::Solvable::IdType id, const std::set<sat::Solvable::IdType> &keepList , const std::set<sat::Solvable::IdType> &removeList ) const;
106  static bool versionMatch ( const Edition &a, const Edition &b );
107  void parseKeepSpec();
108  void fillKeepList(const GroupMap &installedKernels, std::set<sat::Solvable::IdType> &keepList , std::set<sat::Solvable::IdType> &removeList ) const;
109 
110  std::set<size_t> _keepLatestOffsets = { 0 };
111  std::set<size_t> _keepOldestOffsets;
112  std::set<Edition> _keepSpecificEditions;
113  std::string _uname_r;
118  bool _keepRunning = true;
119  bool _detectedRunning = false;
120  };
121 
126  bool PurgeKernels::Impl::removePackageAndCheck( const sat::Solvable::IdType id, const std::set<sat::Solvable::IdType> &keepList , const std::set<sat::Solvable::IdType> &removeList ) const
127  {
128  const filter::ByStatus toBeUninstalledFilter( &ResStatus::isToBeUninstalled );
129 
130  PoolItem pi ( (sat::Solvable(id)) );
131 
132  auto pool = ResPool::instance();
133 
134  // make sure the pool is clean
135  if ( !pool.resolver().resolvePool() ) {
136  MIL << "Pool failed to resolve, not doing anything" << std::endl;
137  return false;
138  }
139 
140  MIL << "Request to remove package: " << pi << std::endl;
141 
142  //list of packages that are allowed to be removed automatically.
143  const str::regex validRemovals("(kernel-syms(-.*)?|kgraft-patch(-.*)?|kernel-livepatch(-.*)?|.*-kmp(-.*)?)");
144 
145  if ( ui::asSelectable()( pi )->hasLocks() ) {
146  MIL << "Package " << pi << " is locked by the user, not removing." << std::endl;
147  return false;
148  }
149 
150  //remember which packages are already marked for removal, we do not need to check them again
151  std::set< sat::Solvable::IdType> currentSetOfRemovals;
152  for ( auto it = pool.byStatusBegin( toBeUninstalledFilter ); it != pool.byStatusEnd( toBeUninstalledFilter ); it++ ) {
153  currentSetOfRemovals.insert( it->id() );
154  }
155 
157 
158  if ( !pool.resolver().resolvePool() ) {
159  MIL << "Failed to resolve pool, skipping " << pi << std::endl;
160  pool.resolver().problems();
161  pi.statusReset();
162 
163  return false;
164  }
165 
166  std::set<sat::Solvable::IdType> removedInThisRun;
167  removedInThisRun.insert( pi.id() );
168 
169  for ( auto it = pool.byStatusBegin( toBeUninstalledFilter ); it != pool.byStatusEnd( toBeUninstalledFilter ); it++ ) {
170 
171  //check if that package is removeable
172  if ( it->status().isByUser() //this was set by us, ignore it
173  || (currentSetOfRemovals.find( it->id() ) != currentSetOfRemovals.end()) //this was marked by a previous removal, ignore them
174  )
175  continue;
176 
177  // remember for later we need remove the debugsource and debuginfo packages as well
178  removedInThisRun.insert( it->id() );
179 
180  MIL << "Package " << PoolItem(*it) << " was marked by the solver for removal." << std::endl;
181 
182  // if we do not plan to remove that package anyway, we need to check if its allowed to be removed ( package in removelist can never be in keep list )
183  if ( removeList.find( it->id() ) != removeList.end() )
184  continue;
185 
186  if ( keepList.find( it->id() ) != keepList.end() ) {
187  MIL << "Package " << PoolItem(*it) << " is in keep spec, skipping" << pi << std::endl;
188  pi.statusReset();
189  return false;
190  }
191 
192  str::smatch what;
193  if ( !str::regex_match( it->name(), what, validRemovals) ) {
194  MIL << "Package " << PoolItem(*it) << " should not be removed, skipping " << pi << std::endl;
195  pi.statusReset();
196  return false;
197  }
198  }
199 
200  MIL << "Successfully marked package: " << pi << " for removal."<<std::endl;
201 
202  //now check and mark the -debugsource and -debuginfo packages for this package and all the packages that were removed. Maybe collect it before and just remove here
203  MIL << "Trying to remove debuginfo for: " << pi <<"."<<std::endl;
204  for ( const auto id : removedInThisRun ) {
205 
206  const auto solvable = sat::Solvable(id);
207  if ( solvable.arch() == Arch_noarch ||
208  solvable.arch() == Arch_empty )
209  continue;
210 
211  for ( const auto suffix : { "-debugsource", "-debuginfo" } ) {
212  PoolQuery q;
214  q.addDependency( sat::SolvAttr::provides, Capability( solvable.name()+suffix, Rel::EQ, solvable.edition() ) );
215  q.setInstalledOnly();
216  q.setMatchExact();
217 
218  for ( const auto debugPackage : q ) {
219 
220  if ( debugPackage.arch() != solvable.arch() )
221  continue;
222 
223  MIL << "Found debug package for " << solvable << " : " << debugPackage << std::endl;
224  //if removing the package fails it will not stop us from going on , so no need to check
225  removePackageAndCheck( debugPackage.id(), keepList, removeList );
226  }
227  }
228  }
229  MIL << "Finished removing debuginfo for: " << pi <<"."<<std::endl;
230 
231  return true;
232  }
233 
238  {
239  // the build counter should not be considered here, so if there is one we cut it off
240  const auto dotOffset = b.release().find_last_of(".");
241  if ( dotOffset != std::string::npos ) {
242  return a == zypp::Edition( b.version(), b.release().substr( 0, dotOffset ), b.epoch() );
243  }
244  return a == b;
245  }
246 
251  {
252  //keep spec parse regex, make sure to edit the group offsets if changing this regex
253  const str::regex specRegex( "^(latest|oldest)([+-][0-9]+)?$", str::regex::match_extended );
254 
255  const unsigned tokenGrp = 1; //index of the group matching the token
256  const unsigned modifierGrp = 2; //index of the group matching the offset modifier
257 
258 
259  MIL << "Parsing keep spec: " << _keepSpec << std::endl;
260 
261  std::vector<std::string> words;
262  str::split( _keepSpec, std::back_inserter(words), ",", str::TRIM );
263  if ( words.empty() ) {
264  WAR << "Invalid keep spec: " << _keepSpec << " using default latest,running." << std::endl;
265  return;
266  }
267 
268  _keepRunning = false;
269  _keepLatestOffsets.clear();
270  _keepOldestOffsets.clear();
271 
272  for ( const std::string &word : words ) {
273  if ( word == "running" ) {
274  _keepRunning = true;
275  } else {
276  str::smatch what;
277  if ( !str::regex_match( word, what, specRegex ) ) {
278  _keepSpecificEditions.insert( Edition(word) );
279  continue;
280  }
281 
282  auto addKeepOff = []( const auto &off, auto &set, const auto &constraint ){
283  const off_t num = off.empty() ? 0 : str::strtonum<off_t>( off );
284  if ( !constraint(num) ) return false;
285  set.insert( static_cast<size_t>(std::abs(num)) );
286  return true;
287  };
288 
289  if ( what[tokenGrp] == "oldest" ) {
290  addKeepOff( what[modifierGrp], _keepOldestOffsets, [ &word ]( off_t num ) {
291  if ( num < 0 ) {
292  WAR << "Ignoring invalid modifier in keep spec: " << word << ", oldest supports only positive modifiers." << std::endl;
293  return false;
294  }
295  return true;
296  });
297  } else {
298  addKeepOff( what[modifierGrp], _keepLatestOffsets, [ &word ]( off_t num ) {
299  if ( num > 0 ) {
300  WAR << "Ignoring invalid modifier in keep spec: " << word << ", latest supports only negative modifiers." << std::endl;
301  return false;
302  }
303  return true;
304  });
305  }
306  }
307  }
308  }
309 
319  void PurgeKernels::Impl::fillKeepList( const GroupMap &installedKernels, std::set<sat::Solvable::IdType> &keepList, std::set<sat::Solvable::IdType> &removeList ) const
320  {
321 
322  const auto markAsKeep = [ &keepList, &removeList ]( const auto &pck ) {
323  MIL << "Marking package " << sat::Solvable(pck) << " as to keep." << std::endl;
324  keepList.insert( pck ) ;
325  removeList.erase( pck );
326  };
327 
328  const auto versionPredicate = []( const auto &edition ){
329  return [ &edition ]( const auto &elem ) {
330  return versionMatch( edition, elem.first );
331  };
332  };
333 
334  for ( const auto &groupInfo : installedKernels ) {
335 
336  MIL << "Starting with group " << groupInfo.first << std::endl;
337 
338  for ( const auto &archMap : groupInfo.second.archToEdMap ) {
339 
340  MIL << "Starting with arch " << archMap.first << std::endl;
341 
342  size_t currOff = 0; //the current "oldest" offset ( runs from map start to end )
343  size_t currROff = archMap.second.size() - 1; // the current "latest" offset ( runs from map end to start )
344 
345 
346  const EditionToSolvableMap &map = archMap.second;
347 
348  if ( _keepRunning
349  && ( ( archMap.first == _kernelArch && groupInfo.second.groupFlavour == _runningKernelFlavour )
350  || groupInfo.second.groupType == GroupInfo::Sources ) ) {
351 
352  MIL << "Matching packages against running kernel "<< _runningKernelEdition << "-" << _runningKernelFlavour << "-" <<_kernelArch << std::endl;
353 
354  auto it = std::find_if( map.begin(), map.end(), versionPredicate( _runningKernelEdition ) );
355  if ( it == map.end() ) {
356 
357  // If we look at Sources we cannot match the flavour but we still want to keep on checking the rest of the keep spec
358  if ( groupInfo.second.groupType != GroupInfo::Sources ) {
359  MIL << "Running kernel "<< _runningKernelEdition << "-" << _runningKernelFlavour << "-" <<_kernelArch << " not installed."<<std::endl;
360  MIL << "NOT removing any packages for flavor "<<_runningKernelFlavour<<"-"<<_kernelArch<<" ."<<std::endl;
361 
362  for ( const auto &kernelMap : map ) {
363  for( const auto &pck : kernelMap.second )
364  markAsKeep(pck);
365  }
366  continue;
367  }
368 
369  } else {
370  // there could be multiple matches here because of rebuild counter, lets try to find the last one
371  MIL << "Found possible running candidate edition: " << it->first << std::endl;
372  auto nit = it;
373  for ( nit++ ; nit != map.end() && versionMatch( _runningKernelEdition, nit->first ) ; nit++ ) {
374  MIL << "Found possible more recent running candidate edition: " << nit->first << std::endl;
375  it = nit;
376  }
377  }
378 
379  // mark all packages of the running version as keep
380  if ( it != map.end() ) {
381  for( const auto &pck : it->second ) {
382  markAsKeep(pck);
383  }
384  }
385  }
386 
387  for ( const auto &kernelMap : map ) {
388  //if we find one of the running offsets in the keepspec, we add the kernel id the the list of packages to keep
389  if ( _keepOldestOffsets.find( currOff ) != _keepOldestOffsets.end()
390  || _keepLatestOffsets.find( currROff ) != _keepLatestOffsets.end()
391  // a kernel might be explicitely locked by version
392  // this will currently keep all editions that match, so if keep spec has 1-1 , this will keep 1-1 but also all 1-1.n
393  || std::find_if( _keepSpecificEditions.begin(), _keepSpecificEditions.end(),
394  [ edition = &kernelMap.first ]( const auto &elem ) { return versionMatch( *edition, elem ); } ) != _keepSpecificEditions.end() ) {
395 
396  for( const auto &pck : kernelMap.second ) {
397  markAsKeep(pck);
398  }
399  }
400  currOff++;
401  currROff--;
402  }
403  }
404  }
405  }
406 
408  : _pimpl( new Impl() )
409  {
410 
411  }
412 
414  {
415  MIL << std::endl << "--------------------- Starting to mark obsolete kernels ---------------------"<<std::endl;
416 
417  if ( _pimpl->_keepSpec.empty() ) {
418  WAR << "Keep spec is empty, removing nothing." << std::endl;
419  return;
420  }
421 
423 
425  WAR << "Unable to detect running kernel, but keeping the running kernel was requested. Not removing any packages." << std::endl;
426  return;
427  }
428 
429  auto pool = ResPool::instance();
430  pool.resolver().setForceResolve( true ); // set allow uninstall flag
431 
432  const filter::ByStatus toBeUninstalledFilter( &ResStatus::isToBeUninstalled );
433 
434  // kernel flavour regex
435  const str::regex kernelFlavourRegex("^kernel-(.*)$");
436 
437  // the map of all installed kernel packages, grouped by Flavour -> Arch -> Version -> (List of all packages in that category)
438  // devel and source packages are grouped together
439  GroupMap installedKrnlPackages;
440 
441 
442  // packages that we plan to remove
443  std::set<sat::Solvable::IdType> packagesToRemove;
444 
445  const auto addPackageToMap = [&installedKrnlPackages, &packagesToRemove] ( const GroupInfo::GroupType type, const std::string &ident, const std::string &flavour, const auto &installedKrnlPck ) {
446 
447  if ( !installedKrnlPackages.count( ident ) )
448  installedKrnlPackages.insert( std::make_pair( ident, GroupInfo(type, flavour) ) );
449 
450  auto &groupInfo = installedKrnlPackages[ ident ];
451  if ( groupInfo.groupType != type || groupInfo.groupFlavour != flavour ) {
452  ERR << "Got inconsistent type and flavour for ident this is a BUG: " << ident << std::endl
453  << "Original Flavour-Type: "<<groupInfo.groupFlavour<<"-"<<groupInfo.groupType << std::endl
454  << "Competing Flavour-Type: "<< flavour << "-" << type << std::endl;
455  }
456 
457  const auto currArch = installedKrnlPck.arch();
458  if ( !groupInfo.archToEdMap.count( currArch ) )
459  groupInfo.archToEdMap.insert( std::make_pair( currArch , EditionToSolvableMap {} ) );
460 
461  auto &editionToSolvableMap = groupInfo.archToEdMap[ currArch ];
462 
463  const auto currEd = installedKrnlPck.edition();
464  if ( !editionToSolvableMap.count( currEd ) )
465  editionToSolvableMap.insert( std::make_pair( currEd, SolvableList{} ) );
466 
467  editionToSolvableMap[currEd].push_back( installedKrnlPck.id() );
468 
469  //in the first step we collect all packages in this list, then later we will remove the packages we want to explicitely keep
470  packagesToRemove.insert( installedKrnlPck.id() );
471  };
472 
473  // the set of package IDs that have to be kept always
474  std::set<sat::Solvable::IdType> packagesToKeep;
475 
476  //collect the list of installed kernel packages
477  PoolQuery q;
479  q.addAttribute( sat::SolvAttr::provides, "multiversion(kernel)" );
480  q.setInstalledOnly();
481  q.setMatchExact();
482 
483  MIL << "Searching for obsolete multiversion kernel packages." << std::endl;
484 
485  for ( auto installedKrnlPck : q ) {
486 
487  MIL << "Found installed multiversion kernel package " << installedKrnlPck << std::endl;
488 
489  if ( installedKrnlPck.provides().matches(Capability("kernel-uname-r")) ) {
490  MIL << "Identified as a kernel package " << std::endl;
491 
492  // we group kernel packages by flavour
493  str::smatch what;
494  str::regex_match( installedKrnlPck.name(), what, kernelFlavourRegex );
495  if ( what[1].empty() ) {
496  WAR << "Could not detect flavour for: " << installedKrnlPck << " ...skipping" << std::endl;
497  continue;
498  }
499 
500  std::string flavour = what[1];
501 
502  // XXX: No dashes in flavor names
503  const auto dash = flavour.find_first_of('-');
504  if ( dash != std::string::npos ) {
505  flavour = flavour.substr( 0, dash );
506  }
507 
508  // the ident for kernels is the flavour, to also handle cases like kernel-base and kernel which should be in the same group handled together
509  addPackageToMap( GroupInfo::Kernels, flavour, flavour, installedKrnlPck );
510 
511  } else {
512 
513  const str::regex explicitelyHandled("kernel-syms(-.*)?|kernel(-.*)?-devel");
514 
515  MIL << "Not a kernel package, inspecting more closely " << std::endl;
516 
517  // we directly handle all noarch packages that export multiversion(kernel)
518  if ( installedKrnlPck.arch() == Arch_noarch ) {
519 
520  MIL << "Handling package explicitely due to architecture (noarch)."<< std::endl;
521  addPackageToMap( GroupInfo::Sources, installedKrnlPck.name(), "", installedKrnlPck );
522 
523  } else if ( str::smatch match; str::regex_match( installedKrnlPck.name(), match, explicitelyHandled ) ) {
524 
525  // try to get the flavour from the name
526  // if we have a kernel-syms getting no flavour means we have the "default" one, otherwise we use the flavour
527  // getting no flavour for a kernel(-*)?-devel means we have the kernel-devel package otherwise the flavour specific one
528  // ...yes this is horrible
529  std::string flav;
530  if ( match.size() > 1 ) {
531  flav = match[2].substr(1);
532  } else if ( installedKrnlPck.name() == "kernel-syms" ) {
533  flav = "default";
534  }
535 
536  MIL << "Handling package explicitely due to name match."<< std::endl;
537  addPackageToMap ( GroupInfo::RelatedBinaries, installedKrnlPck.name(), flav, installedKrnlPck );
538 
539  } else {
540  MIL << "Package not explicitely handled" << std::endl;
541  }
542  }
543 
544  }
545 
546  MIL << "Grouped packages: " << std::endl;
547  std::for_each( installedKrnlPackages.begin(), installedKrnlPackages.end(),[]( const auto &ident ){
548  MIL << "\tGroup ident: "<<ident.first<<std::endl;
549  MIL << "\t Group type: "<<ident.second.groupType<<std::endl;
550  MIL << "\t Group flav: "<<ident.second.groupFlavour<<std::endl;
551  std::for_each( ident.second.archToEdMap.begin(), ident.second.archToEdMap.end(), []( const auto &arch) {
552  MIL << "\t\tArch: "<<arch.first<<std::endl;
553  std::for_each( arch.second.begin(), arch.second.end(), []( const auto &edition) {
554  MIL << "\t\t\tEdition: "<<edition.first<<std::endl;
555  std::for_each( edition.second.begin(), edition.second.end(), []( const auto &packageId) {
556  MIL << "\t\t\t\t "<<sat::Solvable(packageId)<<std::endl;
557  });
558  });
559  });
560  });
561 
562  _pimpl->fillKeepList( installedKrnlPackages, packagesToKeep, packagesToRemove );
563 
564  for ( const auto id : packagesToRemove )
565  _pimpl->removePackageAndCheck( id, packagesToKeep, packagesToRemove );
566  }
567 
568  void PurgeKernels::setUnameR( const std::string &val )
569  {
570  _pimpl->setUnameR( val );
571  }
572 
573  std::string PurgeKernels::unameR() const
574  {
575  return _pimpl->_uname_r;
576  }
577 
579  {
580  _pimpl->_kernelArch = arch;
581  }
582 
584  {
585  return _pimpl->_kernelArch;
586  }
587 
588  void PurgeKernels::setKeepSpec( const std::string &val )
589  {
590  _pimpl->_keepSpec = val;
591  }
592 
593  std::string PurgeKernels::keepSpec() const
594  {
595  return _pimpl->_keepSpec;
596  }
597 
598 }
ResPool.h
zypp::PoolItem
Combining sat::Solvable and ResStatus.
Definition: PoolItem.h:50
PurgeKernels.h
zypp::sat::Solvable
A Solvable object within the sat Pool.
Definition: Solvable.h:53
zypp::filter::ByStatus
Filter solvables according to their status.
Definition: Filter.h:141
zypp::PurgeKernels::keepSpec
std::string keepSpec() const
Definition: PurgeKernels.cc:593
zypp::PurgeKernels::unameR
std::string unameR() const
Definition: PurgeKernels.cc:573
zypp::str::regex_substitute
std::string regex_substitute(const std::string &s, const regex &regex, const std::string &replacement, bool global=true)
Replaces the matched regex with the string passed in replacement.
Definition: Regex.cc:121
zypp::PoolQuery
Meta-data query API.
Definition: PoolQuery.h:90
zypp::PurgeKernels::markObsoleteKernels
void markObsoleteKernels()
Definition: PurgeKernels.cc:413
zypp::PoolQuery::addAttribute
void addAttribute(const sat::SolvAttr &attr, const std::string &value="")
Filter by the value of the specified attr attribute.
Definition: PoolQuery.cc:873
zypp::PurgeKernels::Impl::Impl
Impl()
Definition: PurgeKernels.cc:61
zypp::PurgeKernels::Impl::parseKeepSpec
void parseKeepSpec()
Definition: PurgeKernels.cc:250
zypp::GroupInfo::Kernels
Definition: PurgeKernels.cc:47
zypp::PurgeKernels::Impl::_keepOldestOffsets
std::set< size_t > _keepOldestOffsets
Definition: PurgeKernels.cc:111
zypp::PoolQuery::addDependency
void addDependency(const sat::SolvAttr &attr, const std::string &name, const Rel &op, const Edition &edition)
Query "name|global op edition".
Definition: PoolQuery.cc:876
ZConfig.h
zypp::GroupInfo::groupFlavour
std::string groupFlavour
Definition: PurgeKernels.cc:55
zypp::Edition::epoch
epoch_t epoch() const
Epoch.
Definition: Edition.cc:82
zypp::GroupInfo::Sources
Definition: PurgeKernels.cc:49
MIL
#define MIL
Definition: Logger.h:79
zypp::Flavour
std::string Flavour
Definition: PurgeKernels.cc:38
zypp::Edition
Edition represents [epoch:]version[-release]
Definition: Edition.h:60
zypp::ArchToEditionMap
std::map< Arch, EditionToSolvableMap > ArchToEditionMap
Definition: PurgeKernels.cc:41
zypp::ResKind::package
static const ResKind package
Definition: ResKind.h:40
zypp::str::regex::newline
Match newline.
Definition: Regex.h:102
zypp::GroupInfo::archToEdMap
ArchToEditionMap archToEdMap
Definition: PurgeKernels.cc:54
zypp::ZConfig::multiversionKernels
std::string multiversionKernels() const
Definition: ZConfig.cc:1190
zypp::ResPool::instance
static ResPool instance()
Singleton ctor.
Definition: ResPool.cc:37
zypp::PurgeKernels::Impl::versionMatch
static bool versionMatch(const Edition &a, const Edition &b)
Definition: PurgeKernels.cc:237
zypp::PoolQuery::addKind
void addKind(const ResKind &kind)
Filter by selectable kind.
Definition: PoolQuery.cc:867
zypp::PurgeKernels::Impl::_keepLatestOffsets
std::set< size_t > _keepLatestOffsets
Definition: PurgeKernels.cc:110
zypp::PurgeKernels::Impl::_keepSpec
std::string _keepSpec
Definition: PurgeKernels.cc:117
zypp::Arch
Architecture.
Definition: Arch.h:36
zypp::PurgeKernels::Impl::_keepSpecificEditions
std::set< Edition > _keepSpecificEditions
Definition: PurgeKernels.cc:112
zypp::str::TRIM
Definition: String.h:497
zypp::sat::SolvableType::id
Solvable::IdType id() const
Definition: SolvableType.h:144
zypp::Edition::release
std::string release() const
Release.
Definition: Edition.cc:110
zypp::EditionToSolvableMap
std::map< Edition, SolvableList > EditionToSolvableMap
Definition: PurgeKernels.cc:40
zypp::PurgeKernels::setUnameR
void setUnameR(const std::string &val)
Definition: PurgeKernels.cc:568
zypp::GroupInfo::GroupType
GroupType
Definition: PurgeKernels.cc:45
Resolver.h
zypp::PurgeKernels::Impl::removePackageAndCheck
bool removePackageAndCheck(const sat::Solvable::IdType id, const std::set< sat::Solvable::IdType > &keepList, const std::set< sat::Solvable::IdType > &removeList) const
Definition: PurgeKernels.cc:126
zypp::str::split
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", const Trim trim_r=NO_TRIM)
Split line_r into words.
Definition: String.h:527
zypp::SolvableList
std::list< sat::Solvable::IdType > SolvableList
Definition: PurgeKernels.cc:39
Logger.h
zypp::GroupInfo::groupType
enum zypp::GroupInfo::GroupType groupType
WAR
#define WAR
Definition: Logger.h:80
zypp::GroupMap
std::unordered_map< std::string, GroupInfo > GroupMap
Definition: PurgeKernels.cc:57
zypp::ZConfig::instance
static ZConfig & instance()
Singleton ctor.
Definition: Resolver.cc:126
zypp::PoolQuery::setInstalledOnly
void setInstalledOnly()
Return only @System repo packages.
Definition: PoolQuery.cc:963
zypp::PurgeKernels::kernelArch
Arch kernelArch() const
Definition: PurgeKernels.cc:583
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:1
zypp::Edition::version
std::string version() const
Version.
Definition: Edition.cc:94
zypp::PurgeKernels::Impl::setUnameR
void setUnameR(const std::string &uname)
Definition: PurgeKernels.cc:79
zypp::GroupInfo::RelatedBinaries
Definition: PurgeKernels.cc:48
PoolQuery.h
Regex.h
zypp::PurgeKernels::Impl::_keepRunning
bool _keepRunning
Definition: PurgeKernels.cc:118
zypp::PurgeKernels::PurgeKernels
PurgeKernels()
Definition: PurgeKernels.cc:407
Selectable.h
zypp::PurgeKernels::_pimpl
RW_pointer< Impl > _pimpl
Definition: PurgeKernels.h:66
zypp::ResStatus::setToBeUninstalled
bool setToBeUninstalled(TransactByValue causer)
Definition: ResStatus.h:545
zypp::str::smatch
Regular expression match result.
Definition: Regex.h:160
Iterator.h
zypp::Rel::EQ
static const Rel EQ
Definition: Rel.h:50
zypp::PurgeKernels::Impl::_detectedRunning
bool _detectedRunning
Definition: PurgeKernels.cc:119
zypp::PurgeKernels::setKeepSpec
void setKeepSpec(const std::string &val)
Definition: PurgeKernels.cc:588
zypp::GroupInfo
Definition: PurgeKernels.cc:43
zypp::Capability
A sat capability.
Definition: Capability.h:59
zypp::PurgeKernels::Impl::fillKeepList
void fillKeepList(const GroupMap &installedKernels, std::set< sat::Solvable::IdType > &keepList, std::set< sat::Solvable::IdType > &removeList) const
Definition: PurgeKernels.cc:319
std
Definition: Arch.h:347
zypp::ResStatus::USER
Definition: ResStatus.h:111
zypp::PoolItem::status
ResStatus & status() const
Returns the current status.
Definition: PoolItem.cc:204
zypp::ui::asSelectable
Solvable to Selectable transform functor.
Definition: Selectable.h:565
zypp::ResStatus::isToBeUninstalled
bool isToBeUninstalled() const
Definition: ResStatus.h:261
zypp::str::regex::match_extended
Use POSIX Extended Regular Expression syntax when interpreting regex.
Definition: Regex.h:101
zypp::GroupInfo::None
Definition: PurgeKernels.cc:46
zypp::PurgeKernels::Impl
Definition: PurgeKernels.cc:59
String.h
zypp::sat::SolvAttr::provides
static const SolvAttr provides
Definition: SolvAttr.h:60
zypp::PoolQuery::setMatchExact
void setMatchExact()
Set to match exact string instead of substring.
Definition: PoolQuery.cc:952
ERR
#define ERR
Definition: Logger.h:81
zypp::PurgeKernels::setKernelArch
void setKernelArch(const zypp::Arch &arch)
Definition: PurgeKernels.cc:578
zypp::Arch_empty
const Arch Arch_empty(IdString::Empty)
zypp::PurgeKernels::Impl::_uname_r
std::string _uname_r
Definition: PurgeKernels.cc:113
zypp::PurgeKernels::Impl::_runningKernelFlavour
Flavour _runningKernelFlavour
Definition: PurgeKernels.cc:115
zypp::str::regex_match
bool regex_match(const std::string &s, smatch &matches, const regex &regex)
\relates regex \ingroup ZYPP_STR_REGEX \relates regex \ingroup ZYPP_STR_REGEX
Definition: Regex.h:70
zypp::GroupInfo::GroupInfo
GroupInfo(const GroupType type=None, std::string flav="")
Definition: PurgeKernels.cc:52
zypp::str::regex
Regular expression.
Definition: Regex.h:94
zypp::sat::Solvable::IdType
sat::detail::SolvableIdType IdType
Definition: Solvable.h:56
zypp::PurgeKernels::Impl::_kernelArch
Arch _kernelArch
Definition: PurgeKernels.cc:116
zypp::PurgeKernels::Impl::_runningKernelEdition
Edition _runningKernelEdition
Definition: PurgeKernels.cc:114
zypp::PoolItem::statusReset
ResStatus & statusReset() const
Reset status.
Definition: PoolItem.cc:205
Filter.h