mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 00:13:15 +01:00
* prototype: start bitnami cataloger Bitnami images have spdx SBOMs at predictable paths, and Syft could more accurately identify the software in these images by scanning those SBOMs. Start work on this by forking the sbom-cataloger as a new bitnami-cataloger. Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com> * wire up bitnami cataloger to run on images by default Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com> * feat: add support for Bitnami cataloguer Signed-off-by: juan131 <jariza@vmware.com> * feat: use a better SPDX sample for unit tests Signed-off-by: juan131 <jariza@vmware.com> * bugfix: only report bitnami pkgs Signed-off-by: juan131 <jariza@vmware.com> * feat: adapt JSON schema, spdxutil and packagemetadata Signed-off-by: juan131 <jariza@vmware.com> * bugfix: integration tests Signed-off-by: juan131 <jariza@vmware.com> * feat: implement FileOwner interface Signed-off-by: juan131 <jariza@vmware.com> * bugfix: update json schema Signed-off-by: juan131 <jariza@vmware.com> * [wip] add bitnami owned files and fix binary package ownership filtering Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * feat: obtain bitnami pkg files based on SPDX relationships tree Signed-off-by: juan131 <jariza@vmware.com> * preserve type switches Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * rename bitnami entry metadata type Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * restrict find main pkg logic Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add missing graalvm source info Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * bugfix: integration tests Signed-off-by: juan131 <jariza@vmware.com> * bugfix: mod tidy Signed-off-by: juan131 <jariza@vmware.com> --------- Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com> Signed-off-by: juan131 <jariza@vmware.com> Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> Co-authored-by: Will Murphy <willmurphyscode@users.noreply.github.com> Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
93 lines
2.5 KiB
Go
93 lines
2.5 KiB
Go
package bitnami
|
|
|
|
import (
|
|
"fmt"
|
|
"path"
|
|
"path/filepath"
|
|
"slices"
|
|
"strings"
|
|
|
|
version "github.com/bitnami/go-version/pkg/version"
|
|
|
|
"github.com/anchore/packageurl-go"
|
|
"github.com/anchore/syft/syft/artifact"
|
|
"github.com/anchore/syft/syft/file"
|
|
"github.com/anchore/syft/syft/pkg"
|
|
)
|
|
|
|
func parseBitnamiPURL(p string) (*pkg.BitnamiSBOMEntry, error) {
|
|
purl, err := packageurl.FromString(p)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
v, err := version.Parse(purl.Version)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
entry := pkg.BitnamiSBOMEntry{
|
|
Name: purl.Name,
|
|
Version: strings.TrimSuffix(v.String(), fmt.Sprintf("-%s", v.Revision().String())),
|
|
Revision: v.Revision().String(),
|
|
}
|
|
|
|
for _, q := range purl.Qualifiers {
|
|
switch q.Key {
|
|
case "arch":
|
|
entry.Architecture = q.Value
|
|
case "distro":
|
|
entry.Distro = q.Value
|
|
}
|
|
}
|
|
|
|
return &entry, nil
|
|
}
|
|
|
|
// packageFiles goes through the list of relationships and finds the files that
|
|
// are owned by the given package
|
|
func packageFiles(relationships []artifact.Relationship, p pkg.Package, baseDirectory string) []string {
|
|
var result []string
|
|
for _, r := range relationships {
|
|
if r.Type != artifact.ContainsRelationship {
|
|
continue
|
|
}
|
|
|
|
if from, ok := r.From.(pkg.Package); ok {
|
|
if from.PURL == p.PURL {
|
|
if to, ok := r.To.(pkg.Package); ok {
|
|
result = append(result, packageFiles(relationships, to, baseDirectory)...)
|
|
}
|
|
if value, ok := r.To.(file.Location); ok {
|
|
// note: the file.Location is from the SBOM, and all files within the Bitnami SBOM by convention
|
|
// are relative to the /opt/bitnami/PRODUCT directory, so we need to prepend the base directory
|
|
// so that it's relative to the path found within the container image.
|
|
result = append(result, path.Join(baseDirectory, value.RealPath))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// mainPkgFiles returns the files owned by the main package in the SPDX file.
|
|
func mainPkgFiles(resolver file.Resolver, spdxFilePath string, secondaryPkgsFiles []string) ([]string, error) {
|
|
ownedPathGlob := fmt.Sprintf("%s/**", filepath.Dir(spdxFilePath))
|
|
ownedLocations, err := resolver.FilesByGlob(ownedPathGlob)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ownedLocationSet := file.NewLocationSet(ownedLocations...)
|
|
ownedFiles := ownedLocationSet.CoordinateSet().Paths()
|
|
|
|
// Remove the SPDX file and the files already assigned to other packages
|
|
// from the list of owned files
|
|
files := slices.DeleteFunc(ownedFiles, func(f string) bool {
|
|
return f == spdxFilePath || slices.Contains(secondaryPkgsFiles, f)
|
|
})
|
|
|
|
return files, nil
|
|
}
|