diff --git a/pkg/rhelv2/rpm/rpm.go b/pkg/rhelv2/rpm/rpm.go index f23453adc..77f0adce3 100644 --- a/pkg/rhelv2/rpm/rpm.go +++ b/pkg/rhelv2/rpm/rpm.go @@ -10,6 +10,7 @@ import ( "strings" "time" + log "github.com/sirupsen/logrus" "github.com/stackrox/rox/pkg/set" "github.com/stackrox/rox/pkg/utils" "github.com/stackrox/scanner/database" @@ -89,28 +90,24 @@ func AddToDependencyMap(filename string, fileData analyzer.FileData, execToDeps, // getContentManifestSets returns the list of content sets defined in the content // manifest, if found in the files. Otherwise, `nil` or empty slice is returned. func getContentManifestSets(files analyzer.Files) ([]string, error) { - var contents []byte + var lastErr error for _, prefix := range contentManifestDirs.AsSlice() { for name, file := range files.GetFilesPrefix(prefix) { - if strings.HasSuffix(name, ".json") { - // Return the first one found, as we are currently assuming there is only one per - // layer/node. - contents = file.Contents - break + if !strings.HasSuffix(name, ".json") { + continue + } + var contentManifest database.ContentManifest + if err := json.Unmarshal(file.Contents, &contentManifest); err != nil { + log.WithFields(log.Fields{"prefix": prefix, "file": name}).WithError(err).Warn("failed to parse content manifest, skipping") + lastErr = err + continue + } + if len(contentManifest.ContentSets) > 0 { + return contentManifest.ContentSets, nil } } - if contents != nil { - break - } - } - if contents == nil { - return nil, nil - } - var contentManifest database.ContentManifest - if err := json.Unmarshal(contents, &contentManifest); err != nil { - return nil, err } - return contentManifest.ContentSets, nil + return nil, lastErr } func getFeaturesFromRPMDatabase(files analyzer.Files, testing bool) ([]*database.RHELv2Package, error) { diff --git a/pkg/rhelv2/rpm/rpm_test.go b/pkg/rhelv2/rpm/rpm_test.go index bc936d5f9..24eee5b68 100644 --- a/pkg/rhelv2/rpm/rpm_test.go +++ b/pkg/rhelv2/rpm/rpm_test.go @@ -321,7 +321,41 @@ func Test_getContentManifestSets(t *testing.T) { }), wantErr: assert.Error, }, - + { + name: "when labels.json without content sets and content-sets.json with content sets, then return content sets", + filesArg: tarutil.CreateNewLayerFiles(map[string]analyzer.FileData{ + "root/buildinfo/content_manifests/labels.json": { + Contents: []byte(`{"name": "ubi9/ubi", "version": "9.7"}`), + }, + "root/buildinfo/content_manifests/content-sets.json": { + Contents: []byte(`{ + "content_sets": [ + "rhel-9-for-x86_64-baseos-rpms", + "rhel-9-for-x86_64-appstream-rpms" + ] +}`), + }, + }), + want: []string{"rhel-9-for-x86_64-baseos-rpms", "rhel-9-for-x86_64-appstream-rpms"}, + wantErr: assert.NoError, + }, + { + name: "when invalid json alongside valid content sets, then return content sets", + filesArg: tarutil.CreateNewLayerFiles(map[string]analyzer.FileData{ + "root/buildinfo/content_manifests/broken.json": { + Contents: []byte("not json"), + }, + "root/buildinfo/content_manifests/content-sets.json": { + Contents: []byte(`{ + "content_sets": [ + "rhel-8-for-x86_64-baseos-rpms" + ] +}`), + }, + }), + want: []string{"rhel-8-for-x86_64-baseos-rpms"}, + wantErr: assert.NoError, + }, { name: "when rhel content sets found, then return", filesArg: tarutil.CreateNewLayerFiles(map[string]analyzer.FileData{