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 }