diff --git a/cmd/sbomgen/scanners.go b/cmd/sbomgen/scanners.go index be9bf33b3a059..04de0635c09dc 100644 --- a/cmd/sbomgen/scanners.go +++ b/cmd/sbomgen/scanners.go @@ -28,7 +28,7 @@ func runScanFS(path string, analyzers []string, fast bool) error { report, err := collector.ScanFilesystem(ctx, path, sbom.ScanOptions{ Analyzers: analyzers, Fast: fast, - }) + }, false) if err != nil { return err } diff --git a/pkg/sbom/collectors/host/host.go b/pkg/sbom/collectors/host/host.go index b8a163521ec84..13d75fbcabbc9 100644 --- a/pkg/sbom/collectors/host/host.go +++ b/pkg/sbom/collectors/host/host.go @@ -48,7 +48,7 @@ func (c *Collector) Scan(ctx context.Context, request sbom.ScanRequest) sbom.Sca path := request.ID() // for host request, ID == path log.Infof("host scan request [%v]", path) - report, err := c.trivyCollector.ScanFilesystem(ctx, path, c.opts) + report, err := c.trivyCollector.ScanFilesystem(ctx, path, c.opts, true) return sbom.ScanResult{ Error: err, Report: report, diff --git a/pkg/util/trivy/cache.go b/pkg/util/trivy/cache.go index 7062457d140cf..27d57cfc3226a 100644 --- a/pkg/util/trivy/cache.go +++ b/pkg/util/trivy/cache.go @@ -469,14 +469,16 @@ func (c *persistentCache) collectTelemetry() { } func newMemoryCache() *memoryCache { - return &memoryCache{} + return &memoryCache{ + blobs: make(map[string]types.BlobInfo), + artifacts: make(map[string]types.ArtifactInfo), + } } type memoryCache struct { - blobInfo *types.BlobInfo - blobID string - artifactInfo *types.ArtifactInfo - artifactID string + blobs map[string]types.BlobInfo + artifacts map[string]types.ArtifactInfo + blobID string } func (c *memoryCache) MissingBlobs(artifactID string, blobIDs []string) (missingArtifact bool, missingBlobIDs []string, err error) { @@ -494,45 +496,42 @@ func (c *memoryCache) MissingBlobs(artifactID string, blobIDs []string) (missing } func (c *memoryCache) PutArtifact(artifactID string, artifactInfo types.ArtifactInfo) (err error) { - c.artifactInfo = &artifactInfo - c.artifactID = artifactID + c.artifacts[artifactID] = artifactInfo return nil } func (c *memoryCache) PutBlob(blobID string, blobInfo types.BlobInfo) (err error) { - c.blobInfo = &blobInfo + c.blobs[blobID] = blobInfo c.blobID = blobID return nil } func (c *memoryCache) DeleteBlobs(blobIDs []string) error { - if c.blobInfo != nil { - for _, blobID := range blobIDs { - if blobID == c.blobID { - c.blobInfo = nil - } - } + for _, id := range blobIDs { + delete(c.blobs, id) } return nil } func (c *memoryCache) GetArtifact(artifactID string) (artifactInfo types.ArtifactInfo, err error) { - if c.artifactInfo != nil && c.artifactID == artifactID { - return *c.artifactInfo, nil + art, ok := c.artifacts[artifactID] + if !ok { + return types.ArtifactInfo{}, errors.New("not found") } - return types.ArtifactInfo{}, nil + return art, nil } func (c *memoryCache) GetBlob(blobID string) (blobInfo types.BlobInfo, err error) { - if c.blobInfo != nil && c.blobID == blobID { - return *c.blobInfo, nil + b, ok := c.blobs[blobID] + if !ok { + return types.BlobInfo{}, errors.New("not found") } - return types.BlobInfo{}, errors.New("not found") + return b, nil } func (c *memoryCache) Close() (err error) { - c.artifactInfo = nil - c.blobInfo = nil + c.artifacts = nil + c.blobs = nil return nil } diff --git a/pkg/util/trivy/containerd.go b/pkg/util/trivy/containerd.go index 0393e1179bffb..5e4e71f10af80 100644 --- a/pkg/util/trivy/containerd.go +++ b/pkg/util/trivy/containerd.go @@ -312,7 +312,7 @@ func (c *Collector) ScanContainerdImageFromFilesystem(ctx context.Context, imgMe } }() - report, err := c.ScanFilesystem(ctx, imagePath, scanOptions) + report, err := c.ScanFilesystem(ctx, imagePath, scanOptions, false) if err != nil { return nil, fmt.Errorf("unable to scan image %s, err: %w", imgMeta.ID, err) } diff --git a/pkg/util/trivy/trivy.go b/pkg/util/trivy/trivy.go index f2e7c5d875bea..19f7985ba57c9 100644 --- a/pkg/util/trivy/trivy.go +++ b/pkg/util/trivy/trivy.go @@ -285,8 +285,23 @@ func (c *Collector) getCache() (CacheWithCleaner, error) { return c.persistentCache, nil } +type fakeArtifact struct { + inner artifact.Artifact + forceType artifact.Type +} + +func (fa *fakeArtifact) Inspect(ctx context.Context) (artifact.Reference, error) { + ref, err := fa.inner.Inspect(ctx) + ref.Type = fa.forceType + return ref, err +} + +func (fa *fakeArtifact) Clean(ref artifact.Reference) error { + return fa.inner.Clean(ref) +} + // ScanFilesystem scans the specified directory and logs detailed scan steps. -func (c *Collector) ScanFilesystem(ctx context.Context, path string, scanOptions sbom.ScanOptions) (sbom.Report, error) { +func (c *Collector) ScanFilesystem(ctx context.Context, path string, scanOptions sbom.ScanOptions, removeLayer bool) (sbom.Report, error) { // For filesystem scans, it is required to walk the filesystem to get the persistentCache key so caching does not add any value. // TODO: Cache directly the trivy report for container images cache := newMemoryCache() @@ -296,7 +311,15 @@ func (c *Collector) ScanFilesystem(ctx context.Context, path string, scanOptions return nil, fmt.Errorf("unable to create artifact from fs, err: %w", err) } - trivyReport, err := c.scan(ctx, fsArtifact, applier.NewApplier(cache)) + wrapper := &fakeArtifact{ + inner: fsArtifact, + forceType: artifact.TypeContainerImage, + } + if removeLayer { + wrapper.forceType = artifact.TypeFilesystem + } + + trivyReport, err := c.scan(ctx, wrapper, applier.NewApplier(cache)) if err != nil { return nil, fmt.Errorf("unable to marshal report to sbom format, err: %w", err) }