diff --git a/cmd/agent/subcommands/jmx/command.go b/cmd/agent/subcommands/jmx/command.go index 3017ba894d7da..ce4cbbd9f721d 100644 --- a/cmd/agent/subcommands/jmx/command.go +++ b/cmd/agent/subcommands/jmx/command.go @@ -226,12 +226,6 @@ func disableCmdPort() { // runJmxCommandConsole sets up the common utils necessary for JMX, and executes the command // with the Console reporter func runJmxCommandConsole(log log.Component, config config.Component, cliParams *cliParams) error { - // Always disable SBOM collection in `jmx` command to avoid BoltDB flock issue - // and consuming CPU & Memory for asynchronous scans that would not be shown in `agent jmx` output. - pkgconfig.Datadog.Set("sbom.host.enabled", "false") - pkgconfig.Datadog.Set("sbom.container_image.enabled", "false") - pkgconfig.Datadog.Set("runtime_security_config.sbom.enabled", "false") - err := pkgconfig.SetupJMXLogger(cliParams.logFile, "", false, true, false) if err != nil { return fmt.Errorf("Unable to set up JMX logger: %v", err) diff --git a/pkg/cli/subcommands/check/command.go b/pkg/cli/subcommands/check/command.go index 8fac8b054f41a..b62bb6f8ef404 100644 --- a/pkg/cli/subcommands/check/command.go +++ b/pkg/cli/subcommands/check/command.go @@ -181,12 +181,6 @@ func run(log log.Component, config config.Component, sysprobeconfig sysprobeconf return nil } - // Always disable SBOM collection in `check` command to avoid BoltDB flock issue - // and consuming CPU & Memory for asynchronous scans that would not be shown in `agent check` output. - pkgconfig.Datadog.Set("sbom.host.enabled", "false") - pkgconfig.Datadog.Set("sbom.container_image.enabled", "false") - pkgconfig.Datadog.Set("runtime_security_config.sbom.enabled", "false") - hostnameDetected, err := hostname.Get(context.TODO()) if err != nil { fmt.Printf("Cannot get hostname, exiting: %v\n", err) diff --git a/pkg/diagnose/check.go b/pkg/diagnose/check.go index 68a409e3623bf..8a24ecaee4ea6 100644 --- a/pkg/diagnose/check.go +++ b/pkg/diagnose/check.go @@ -83,10 +83,6 @@ func diagnoseChecksInCLIProcess(diagCfg diagnosis.Config, senderManager sender.S // run() github.com\DataDog\datadog-agent\pkg\cli\subcommands\check\command.go // runCheck() github.com\DataDog\datadog-agent\cmd\agent\gui\checks.go - // Always disable SBOM collection in `check` command to avoid BoltDB flock issue - // and consuming CPU & Memory for asynchronous scans that would not be shown in `agent check` output. - pkgconfig.Datadog.Set("container_image_collection.sbom.enabled", "false") - hostnameDetected, err := hostname.Get(context.TODO()) if err != nil { return []diagnosis.Diagnosis{ diff --git a/pkg/sbom/collectors/containerd/containerd.go b/pkg/sbom/collectors/containerd/containerd.go index 997892d76c428..1c29270054d4a 100644 --- a/pkg/sbom/collectors/containerd/containerd.go +++ b/pkg/sbom/collectors/containerd/containerd.go @@ -61,7 +61,7 @@ type Collector struct { // CleanCache cleans the cache func (c *Collector) CleanCache() error { - return c.trivyCollector.GetCacheCleaner().Clean() + return c.trivyCollector.CleanCache() } // Init initializes the collector diff --git a/pkg/sbom/collectors/docker/docker.go b/pkg/sbom/collectors/docker/docker.go index 49b62fed3a4f2..4db4b9a78f60e 100644 --- a/pkg/sbom/collectors/docker/docker.go +++ b/pkg/sbom/collectors/docker/docker.go @@ -52,12 +52,12 @@ type Collector struct { trivyCollector *trivy.Collector } -// CleanCache clean the cache +// CleanCache cleans the cache func (c *Collector) CleanCache() error { - return c.trivyCollector.GetCacheCleaner().Clean() + return c.trivyCollector.CleanCache() } -// Init initialize the collector +// Init initializes the collector func (c *Collector) Init(cfg config.Config) error { trivyCollector, err := trivy.GetGlobalCollector(cfg) if err != nil { diff --git a/pkg/sbom/collectors/host/host.go b/pkg/sbom/collectors/host/host.go index 88634d1456da4..c783167c76738 100644 --- a/pkg/sbom/collectors/host/host.go +++ b/pkg/sbom/collectors/host/host.go @@ -50,7 +50,7 @@ type Collector struct { // CleanCache cleans the cache func (c *Collector) CleanCache() error { - return c.trivyCollector.GetCacheCleaner().Clean() + return c.trivyCollector.CleanCache() } // Init initialize the host collector diff --git a/pkg/util/trivy/trivy.go b/pkg/util/trivy/trivy.go index 4dafbebe03fa2..b98f7f5287dea 100644 --- a/pkg/util/trivy/trivy.go +++ b/pkg/util/trivy/trivy.go @@ -13,6 +13,7 @@ import ( "os" "path/filepath" "sort" + "sync" "time" "github.com/DataDog/datadog-agent/pkg/config" @@ -60,13 +61,13 @@ type CollectorConfig struct { // Collector uses trivy to generate a SBOM type Collector struct { - config CollectorConfig - cache cache.Cache - cacheCleaner CacheCleaner - detector local.OspkgDetector - dbConfig db.Config - vulnClient vulnerability.Client - marshaler *cyclonedx.Marshaler + config CollectorConfig + cacheInitialized sync.Once + cache cache.Cache + cacheCleaner CacheCleaner + detector local.OspkgDetector + vulnClient vulnerability.Client + marshaler *cyclonedx.Marshaler } var globalCollector *Collector @@ -162,20 +163,11 @@ func NewCollector(cfg config.Config) (*Collector, error) { config := defaultCollectorConfig(cfg.GetString("sbom.cache_directory")) config.ClearCacheOnClose = cfg.GetBool("sbom.clear_cache_on_exit") - dbConfig := db.Config{} - fanalCache, cacheCleaner, err := config.CacheProvider() - if err != nil { - return nil, err - } - return &Collector{ - config: config, - cache: fanalCache, - cacheCleaner: cacheCleaner, - detector: ospkg.Detector{}, - dbConfig: dbConfig, - vulnClient: vulnerability.NewClient(dbConfig), - marshaler: cyclonedx.NewMarshaler(""), + config: config, + detector: ospkg.Detector{}, + vulnClient: vulnerability.NewClient(db.Config{}), + marshaler: cyclonedx.NewMarshaler(""), }, nil } @@ -196,6 +188,10 @@ func GetGlobalCollector(cfg config.Config) (*Collector, error) { // Close closes the collector func (c *Collector) Close() error { + if c.cache == nil { + return nil + } + if c.config.ClearCacheOnClose { if err := c.cache.Clear(); err != nil { return fmt.Errorf("error when clearing trivy cache: %w", err) @@ -205,9 +201,25 @@ func (c *Collector) Close() error { return c.cache.Close() } -// GetCacheCleaner gets the cache cleaner -func (c *Collector) GetCacheCleaner() CacheCleaner { - return c.cacheCleaner +// CleanCache cleans the cache +func (c *Collector) CleanCache() error { + if c.cacheCleaner != nil { + return c.cacheCleaner.Clean() + } + return nil +} + +func (c *Collector) getCache() (cache.Cache, CacheCleaner, error) { + var err error + c.cacheInitialized.Do(func() { + c.cache, c.cacheCleaner, err = c.config.CacheProvider() + }) + + if err != nil { + return nil, nil, err + } + + return c.cache, c.cacheCleaner, nil } // ScanDockerImage scans a docker image @@ -272,7 +284,11 @@ func (c *Collector) ScanContainerdImageFromFilesystem(ctx context.Context, imgMe } func (c *Collector) scanFilesystem(ctx context.Context, path string, imgMeta *workloadmeta.ContainerImageMetadata, scanOptions sbom.ScanOptions) (sbom.Report, error) { - cache := c.cache + cache, _, err := c.getCache() + if err != nil { + return nil, err + } + if scanOptions.NoCache { cache = &memoryCache{} } @@ -322,12 +338,17 @@ func (c *Collector) scan(ctx context.Context, artifact artifact.Artifact, applie } func (c *Collector) scanImage(ctx context.Context, fanalImage ftypes.Image, imgMeta *workloadmeta.ContainerImageMetadata, scanOptions sbom.ScanOptions) (sbom.Report, error) { - imageArtifact, err := image2.NewArtifact(fanalImage, c.cache, getDefaultArtifactOption("", scanOptions)) + cache, _, err := c.getCache() + if err != nil { + return nil, err + } + + imageArtifact, err := image2.NewArtifact(fanalImage, cache, getDefaultArtifactOption("", scanOptions)) if err != nil { return nil, fmt.Errorf("unable to create artifact from image, err: %w", err) } - bom, err := c.scan(ctx, imageArtifact, applier.NewApplier(c.cache), imgMeta) + bom, err := c.scan(ctx, imageArtifact, applier.NewApplier(cache), imgMeta) if err != nil { return nil, fmt.Errorf("unable to marshal report to sbom format, err: %w", err) }