Merge pull request #1848 from kubescape/fixgrype

close grype DB at the very end of processing
This commit is contained in:
Matthias Bertschy
2025-07-25 11:23:56 +02:00
committed by GitHub
5 changed files with 50 additions and 23 deletions

View File

@@ -165,7 +165,12 @@ func (ks *Kubescape) ScanImage(imgScanInfo *ksmetav1.ImageScanInfo, scanInfo *ca
logger.L().Start(fmt.Sprintf("Scanning image %s...", imgScanInfo.Image))
dbCfg, _ := imagescan.NewDefaultDBConfig()
svc := imagescan.NewScanService(dbCfg)
svc, err := imagescan.NewScanService(dbCfg)
if err != nil {
logger.L().StopError(fmt.Sprintf("Failed to initialize image scanner: %s", err))
return nil, err
}
defer svc.Close()
creds := imagescan.RegistryCredentials{
Username: imgScanInfo.Username,

View File

@@ -31,7 +31,12 @@ func (ks *Kubescape) Patch(patchInfo *ksmetav1.PatchInfo, scanInfo *cautils.Scan
// Setup the scan service
dbCfg, _ := imagescan.NewDefaultDBConfig()
svc := imagescan.NewScanService(dbCfg)
svc, err := imagescan.NewScanService(dbCfg)
if err != nil {
logger.L().StopError(fmt.Sprintf("Failed to initialize image scanner: %s", err))
return nil, err
}
defer svc.Close()
creds := imagescan.RegistryCredentials{
Username: patchInfo.Username,
Password: patchInfo.Password,

View File

@@ -244,7 +244,12 @@ func scanImages(scanType cautils.ScanTypes, scanData *cautils.OPASessionObj, ctx
}
dbCfg, _ := imagescan.NewDefaultDBConfig()
svc := imagescan.NewScanService(dbCfg)
svc, err := imagescan.NewScanService(dbCfg)
if err != nil {
logger.L().StopError(fmt.Sprintf("Failed to initialize image scanner: %s", err))
return
}
defer svc.Close()
for _, img := range imagesToScan {
logger.L().Start("Scanning", helpers.String("image", img))
@@ -255,7 +260,7 @@ func scanImages(scanType cautils.ScanTypes, scanData *cautils.OPASessionObj, ctx
}
}
func scanSingleImage(ctx context.Context, img string, svc imagescan.Service, resultsHandling *resultshandling.ResultsHandler) error {
func scanSingleImage(ctx context.Context, img string, svc *imagescan.Service, resultsHandling *resultshandling.ResultsHandler) error {
scanResults, err := svc.Scan(ctx, img, imagescan.RegistryCredentials{}, nil, nil)
if err != nil {

View File

@@ -115,7 +115,10 @@ func getProviderConfig(creds RegistryCredentials) pkg.ProviderConfig {
//
// It performs image scanning and everything needed in between.
type Service struct {
dbCfg db.Config
dbCfg db.Config
dbCloser *db.Closer
dbStatus *db.Status
dbStore *store.Store
}
func getIgnoredMatches(vulnerabilityExceptions []string, store *store.Store, packages []pkg.Package, pkgContext pkg.Context) (*match.Matches, []match.IgnoredMatch, error) {
@@ -178,47 +181,51 @@ func filterMatchesBasedOnSeverity(severityExceptions []string, remainingMatches
return filteredMatches
}
func (s *Service) Scan(ctx context.Context, userInput string, creds RegistryCredentials, vulnerabilityExceptions, severityExceptions []string) (*models.PresenterConfig, error) {
store, status, dbCloser, err := NewVulnerabilityDB(s.dbCfg, true)
if err = validateDBLoad(err, status); err != nil {
return nil, err
}
func (s *Service) Scan(_ context.Context, userInput string, creds RegistryCredentials, vulnerabilityExceptions, severityExceptions []string) (*models.PresenterConfig, error) {
packages, pkgContext, sbom, err := pkg.Provide(userInput, getProviderConfig(creds))
if err != nil {
return nil, err
}
if dbCloser != nil {
defer dbCloser.Close()
}
remainingMatches, ignoredMatches, err := getIgnoredMatches(vulnerabilityExceptions, store, packages, pkgContext)
remainingMatches, ignoredMatches, err := getIgnoredMatches(vulnerabilityExceptions, s.dbStore, packages, pkgContext)
if err != nil {
return nil, err
}
filteredMatches := filterMatchesBasedOnSeverity(severityExceptions, *remainingMatches, store)
filteredMatches := filterMatchesBasedOnSeverity(severityExceptions, *remainingMatches, s.dbStore)
pb := models.PresenterConfig{
Matches: filteredMatches,
IgnoredMatches: ignoredMatches,
Packages: packages,
Context: pkgContext,
MetadataProvider: store,
MetadataProvider: s.dbStore,
SBOM: sbom,
AppConfig: nil,
DBStatus: status,
DBStatus: s.dbStatus,
}
return &pb, nil
}
func (s *Service) Close() {
s.dbCloser.Close()
}
func NewVulnerabilityDB(cfg db.Config, update bool) (*store.Store, *db.Status, *db.Closer, error) {
return grype.LoadVulnerabilityDB(cfg, update)
}
func NewScanService(dbCfg db.Config) Service {
return Service{dbCfg: dbCfg}
func NewScanService(dbCfg db.Config) (*Service, error) {
dbStore, dbStatus, dbCloser, err := NewVulnerabilityDB(dbCfg, true)
if err = validateDBLoad(err, dbStatus); err != nil {
return nil, err
}
return &Service{
dbCfg: dbCfg,
dbCloser: dbCloser,
dbStatus: dbStatus,
dbStore: dbStore,
}, nil
}
// ParseSeverity returns a Grype severity given a severity string

View File

@@ -17,6 +17,7 @@ import (
syftPkg "github.com/anchore/syft/syft/pkg"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestVulnerabilityAndSeverityExceptions(t *testing.T) {
@@ -27,7 +28,9 @@ func TestVulnerabilityAndSeverityExceptions(t *testing.T) {
DBRootDir: path.Join(xdg.CacheHome, "grype-light", "db"),
ListingURL: "http://localhost:8000/listing.json",
}
svc := NewScanService(dbCfg)
svc, err := NewScanService(dbCfg)
require.NoError(t, err)
defer svc.Close()
creds := RegistryCredentials{}
tests := []struct {
@@ -338,7 +341,9 @@ func TestGetProviderConfig(t *testing.T) {
func TestNewScanService(t *testing.T) {
defaultConfig, _ := NewDefaultDBConfig()
svc := NewScanService(defaultConfig)
svc, err := NewScanService(defaultConfig)
require.NoError(t, err)
defer svc.Close()
assert.Equal(t, defaultConfig, svc.dbCfg)
}