Skip to content

Avoid to use sync.Once inside trivy javadb Updater #1859

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Mar 5, 2024
100 changes: 100 additions & 0 deletions detector/javadb/javadb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//go:build !scanner
// +build !scanner

package javadb

import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"time"

"github.com/aquasecurity/go-dep-parser/pkg/java/jar"
"github.com/aquasecurity/trivy-java-db/pkg/db"
"github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/oci"
"golang.org/x/xerrors"

"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/logging"
)

func UpdateJavaDB(trivyOpts config.TrivyOpts, noProgress bool) error {
repo := fmt.Sprintf("%s:%d", trivyOpts.TrivyJavaDBRepository, db.SchemaVersion)
dbDir := filepath.Join(trivyOpts.TrivyCacheDBDir, "java-db")

metac := db.NewMetadata(dbDir)
meta, err := metac.Get()
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
return xerrors.Errorf("Failed to get Java DB metadata. err: %w", err)
} else if trivyOpts.TrivySkipJavaDBUpdate {
logging.Log.Error("Could not skip, the first run cannot skip downloading Java DB")
return xerrors.New("'--skip-java-db-update' cannot be specified on the first run")
}
}

if (meta.Version != db.SchemaVersion || meta.NextUpdate.Before(time.Now().UTC())) && !trivyOpts.TrivySkipJavaDBUpdate {
// Download DB
logging.Log.Infof("Trivy Java DB Repository: %s", repo)
logging.Log.Info("Downloading Trivy Java DB...")

var a *oci.Artifact
if a, err = oci.NewArtifact(repo, noProgress, types.RegistryOptions{}); err != nil {
return xerrors.Errorf("oci error: %w", err)
}
if err = a.Download(context.Background(), dbDir, oci.DownloadOption{MediaType: "application/vnd.aquasec.trivy.javadb.layer.v1.tar+gzip"}); err != nil {
return xerrors.Errorf("Failed to download Trivy Java DB. err: %w", err)
}

// Parse the newly downloaded metadata.json
meta, err = metac.Get()
if err != nil {
return xerrors.Errorf("Failed to get Trivy Java DB metadata. err: %w", err)
}

// Update DownloadedAt
meta.DownloadedAt = time.Now().UTC()
if err = metac.Update(meta); err != nil {
return xerrors.Errorf("Failed to update Trivy Java DB metadata. erro: %w", err)
}
}

return nil
}

type DBClient struct {
driver db.DB
}

func NewClient(cacheDBDir string) (*DBClient, error) {
driver, err := db.New(filepath.Join(cacheDBDir, "java-db"))
if err != nil {
return nil, xerrors.Errorf("Failed to open Trivy Java DB. err: %w", err)
}
return &DBClient{driver: driver}, nil
}

func (client *DBClient) Close() error {
if client == nil {
return nil
}

return client.driver.Close()
}

func (client *DBClient) SearchBySHA1(sha1 string) (jar.Properties, error) {
index, err := client.driver.SelectIndexBySha1(sha1)
if err != nil {
return jar.Properties{}, xerrors.Errorf("Failed to select from Trivy Java DB. err: %w", err)
} else if index.ArtifactID == "" {
return jar.Properties{}, xerrors.Errorf("digest %s: %w", sha1, jar.ArtifactNotFoundErr)
}
return jar.Properties{
GroupID: index.GroupID,
ArtifactID: index.ArtifactID,
Version: index.Version,
}, nil
}
14 changes: 8 additions & 6 deletions detector/library.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import (
"github.com/aquasecurity/trivy-db/pkg/metadata"
"github.com/aquasecurity/trivy/pkg/db"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/javadb"
"github.com/aquasecurity/trivy/pkg/log"
"golang.org/x/xerrors"

"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/detector/javadb"
"github.com/future-architect/vuls/logging"
"github.com/future-architect/vuls/models"
)
Expand All @@ -41,16 +41,18 @@ func DetectLibsCves(r *models.ScanResult, trivyOpts config.TrivyOpts, logOpts lo
}
defer trivydb.Close()

var javaDBClient *javadb.DB
var javaDBClient *javadb.DBClient
defer javaDBClient.Close()
for _, lib := range r.LibraryScanners {
if lib.Type == ftypes.Jar {
if javaDBClient == nil {
javadb.Init(trivyOpts.TrivyCacheDBDir, trivyOpts.TrivyJavaDBRepository, trivyOpts.TrivySkipJavaDBUpdate, noProgress, ftypes.RegistryOptions{})
if err := javadb.UpdateJavaDB(trivyOpts, noProgress); err != nil {
return xerrors.Errorf("Failed to update Trivy Java DB. err: %w", err)
}

javaDBClient, err = javadb.NewClient()
javaDBClient, err = javadb.NewClient(trivyOpts.TrivyCacheDBDir)
if err != nil {
return xerrors.Errorf("Failed to download or open trivy Java DB. err: %w", err)
return xerrors.Errorf("Failed to open Trivy Java DB. err: %w", err)
}
}
lib.JavaDBClient = javaDBClient
Expand Down Expand Up @@ -107,7 +109,7 @@ func showDBInfo(cacheDir string) error {
if err != nil {
return xerrors.Errorf("Failed to get DB metadata. err: %w", err)
}
log.Logger.Debugf("DB Schema: %d, UpdatedAt: %s, NextUpdate: %s, DownloadedAt: %s",
logging.Log.Debugf("DB Schema: %d, UpdatedAt: %s, NextUpdate: %s, DownloadedAt: %s",
meta.Version, meta.UpdatedAt, meta.NextUpdate, meta.DownloadedAt)
return nil
}
4 changes: 2 additions & 2 deletions models/library.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import (
trivyDBTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/detector/library"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/javadb"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/samber/lo"
"golang.org/x/xerrors"

"github.com/future-architect/vuls/detector/javadb"
"github.com/future-architect/vuls/logging"
)

Expand Down Expand Up @@ -51,7 +51,7 @@ type LibraryScanner struct {
// The path to the Lockfile is stored.
LockfilePath string `json:"path,omitempty"`

JavaDBClient *javadb.DB `json:"-"`
JavaDBClient *javadb.DBClient `json:"-"`
}

// Library holds the attribute of a package library
Expand Down