github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/pkg/cataloger/redhat/cataloger.go (about)

     1  /*
     2  Package redhat provides a concrete DBCataloger implementation relating to packages within the RedHat linux distribution.
     3  */
     4  package redhat
     5  
     6  import (
     7  	"database/sql"
     8  
     9  	"github.com/anchore/syft/internal/log"
    10  	"github.com/anchore/syft/syft/artifact"
    11  	"github.com/anchore/syft/syft/pkg"
    12  	"github.com/anchore/syft/syft/pkg/cataloger/generic"
    13  	"github.com/anchore/syft/syft/pkg/cataloger/internal/dependency"
    14  )
    15  
    16  // NewDBCataloger returns a new RPM DB cataloger object.
    17  func NewDBCataloger() pkg.Cataloger {
    18  	// check if a sqlite driver is available
    19  	if !isSqliteDriverAvailable() {
    20  		log.Warnf("sqlite driver is not available, newer RPM databases might not be cataloged")
    21  	}
    22  
    23  	return generic.NewCataloger("rpm-db-cataloger").
    24  		WithParserByGlobs(parseRpmDB, pkg.RpmDBGlob).
    25  		WithParserByGlobs(parseRpmManifest, pkg.RpmManifestGlob).
    26  		WithProcessors(dependency.Processor(dbEntryDependencySpecifier), denySelfReferences)
    27  }
    28  
    29  func denySelfReferences(pkgs []pkg.Package, rels []artifact.Relationship, err error) ([]pkg.Package, []artifact.Relationship, error) {
    30  	// it can be common for dependency evidence to be self-referential (e.g. bash depends on bash), which is not useful
    31  	// for the dependency graph, thus we remove these cases
    32  	for i := 0; i < len(rels); i++ {
    33  		if rels[i].Type != artifact.DependencyOfRelationship {
    34  			continue
    35  		}
    36  		if rels[i].From.ID() == rels[i].To.ID() {
    37  			rels = append(rels[:i], rels[i+1:]...)
    38  			i--
    39  		}
    40  	}
    41  	return pkgs, rels, err
    42  }
    43  
    44  // NewArchiveCataloger returns a new RPM file cataloger object.
    45  func NewArchiveCataloger() pkg.Cataloger {
    46  	return generic.NewCataloger("rpm-archive-cataloger").
    47  		WithParserByGlobs(parseRpmArchive, "**/*.rpm")
    48  }
    49  
    50  func isSqliteDriverAvailable() bool {
    51  	_, err := sql.Open("sqlite", ":memory:")
    52  	return err == nil
    53  }