github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/bitnami/package.go (about) 1 package bitnami 2 3 import ( 4 "fmt" 5 "path" 6 "path/filepath" 7 "slices" 8 "strings" 9 10 "github.com/bitnami/go-version/pkg/version" 11 12 "github.com/anchore/packageurl-go" 13 "github.com/anchore/syft/syft/artifact" 14 "github.com/anchore/syft/syft/file" 15 "github.com/anchore/syft/syft/pkg" 16 ) 17 18 func parseBitnamiPURL(p string) (*pkg.BitnamiSBOMEntry, error) { 19 purl, err := packageurl.FromString(p) 20 if err != nil { 21 return nil, err 22 } 23 24 v, err := version.Parse(purl.Version) 25 if err != nil { 26 return nil, err 27 } 28 29 entry := pkg.BitnamiSBOMEntry{ 30 Name: purl.Name, 31 Version: strings.TrimSuffix(v.String(), fmt.Sprintf("-%s", v.Revision().String())), 32 Revision: v.Revision().String(), 33 } 34 35 for _, q := range purl.Qualifiers { 36 switch q.Key { 37 case "arch": 38 entry.Architecture = q.Value 39 case "distro": 40 entry.Distro = q.Value 41 } 42 } 43 44 return &entry, nil 45 } 46 47 // packageFiles goes through the list of relationships and finds the files that 48 // are owned by the given package 49 func packageFiles(relationships []artifact.Relationship, p pkg.Package, baseDirectory string) []string { 50 var result []string 51 for _, r := range relationships { 52 if r.Type != artifact.ContainsRelationship { 53 continue 54 } 55 56 if from, ok := r.From.(pkg.Package); ok { 57 if from.PURL == p.PURL { 58 if to, ok := r.To.(pkg.Package); ok { 59 result = append(result, packageFiles(relationships, to, baseDirectory)...) 60 } 61 if value, ok := r.To.(file.Location); ok { 62 // note: the file.Location is from the SBOM, and all files within the Bitnami SBOM by convention 63 // are relative to the /opt/bitnami/PRODUCT directory, so we need to prepend the base directory 64 // so that it's relative to the path found within the container image. 65 result = append(result, path.Join(baseDirectory, value.RealPath)) 66 } 67 } 68 } 69 } 70 71 return result 72 } 73 74 // mainPkgFiles returns the files owned by the main package in the SPDX file. 75 func mainPkgFiles(resolver file.Resolver, spdxFilePath string, secondaryPkgsFiles []string) ([]string, error) { 76 ownedPathGlob := fmt.Sprintf("%s/**", filepath.Dir(spdxFilePath)) 77 ownedLocations, err := resolver.FilesByGlob(ownedPathGlob) 78 if err != nil { 79 return nil, err 80 } 81 82 ownedLocationSet := file.NewLocationSet(ownedLocations...) 83 ownedFiles := ownedLocationSet.CoordinateSet().Paths() 84 85 // Remove the SPDX file and the files already assigned to other packages 86 // from the list of owned files 87 files := slices.DeleteFunc(ownedFiles, func(f string) bool { 88 return f == spdxFilePath || slices.Contains(secondaryPkgsFiles, f) 89 }) 90 91 return files, nil 92 }