mirror of
https://github.com/anchore/grype
synced 2024-11-10 06:34:13 +00:00
add DBCloser. Clients can aviod db connection leak if vulnerability db is loaded many times (#825)
This commit is contained in:
parent
cb6bddfeeb
commit
2233736e98
8 changed files with 48 additions and 15 deletions
|
@ -284,6 +284,7 @@ func startWorker(userInput string, failOnSeverity *vulnerability.Severity) <-cha
|
|||
|
||||
var store *store.Store
|
||||
var status *db.Status
|
||||
var dbCloser *db.Closer
|
||||
var packages []pkg.Package
|
||||
var context pkg.Context
|
||||
var wg = &sync.WaitGroup{}
|
||||
|
@ -294,7 +295,7 @@ func startWorker(userInput string, failOnSeverity *vulnerability.Severity) <-cha
|
|||
go func() {
|
||||
defer wg.Done()
|
||||
log.Debug("loading DB")
|
||||
store, status, err = grype.LoadVulnerabilityDB(appConfig.DB.ToCuratorConfig(), appConfig.DB.AutoUpdate)
|
||||
store, status, dbCloser, err = grype.LoadVulnerabilityDB(appConfig.DB.ToCuratorConfig(), appConfig.DB.AutoUpdate)
|
||||
if err = validateDBLoad(err, status); err != nil {
|
||||
errs <- err
|
||||
return
|
||||
|
@ -318,6 +319,10 @@ func startWorker(userInput string, failOnSeverity *vulnerability.Severity) <-cha
|
|||
return
|
||||
}
|
||||
|
||||
if dbCloser != nil {
|
||||
defer dbCloser.Close()
|
||||
}
|
||||
|
||||
if appConfig.OnlyFixed {
|
||||
appConfig.Ignore = append(appConfig.Ignore, ignoreNonFixedMatches...)
|
||||
}
|
||||
|
|
|
@ -77,15 +77,15 @@ func (c Curator) SupportedSchema() int {
|
|||
return c.targetSchema
|
||||
}
|
||||
|
||||
func (c *Curator) GetStore() (grypeDB.StoreReader, error) {
|
||||
func (c *Curator) GetStore() (grypeDB.StoreReader, grypeDB.DBCloser, error) {
|
||||
// ensure the DB is ok
|
||||
_, err := c.validateIntegrity(c.dbDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("vulnerability database is invalid (run db update to correct): %+v", err)
|
||||
return nil, nil, fmt.Errorf("vulnerability database is invalid (run db update to correct): %+v", err)
|
||||
}
|
||||
|
||||
s, err := store.New(c.dbPath, false)
|
||||
return s, err
|
||||
return s, s, err
|
||||
}
|
||||
|
||||
func (c *Curator) Status() Status {
|
||||
|
|
9
grype/db/db_closer.go
Normal file
9
grype/db/db_closer.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package db
|
||||
|
||||
import v4 "github.com/anchore/grype/grype/db/v4"
|
||||
|
||||
// Closer lets receiver close the db connection and free any allocated db resources.
|
||||
// It's especially useful if vulnerability DB loaded repeatedly during some periodic SBOM scanning process.
|
||||
type Closer struct {
|
||||
v4.DBCloser
|
||||
}
|
|
@ -3,6 +3,7 @@ package v4
|
|||
type Store interface {
|
||||
StoreReader
|
||||
StoreWriter
|
||||
DBCloser
|
||||
}
|
||||
|
||||
type StoreReader interface {
|
||||
|
@ -18,9 +19,12 @@ type StoreWriter interface {
|
|||
VulnerabilityStoreWriter
|
||||
VulnerabilityMetadataStoreWriter
|
||||
VulnerabilityMatchExclusionStoreWriter
|
||||
Close()
|
||||
}
|
||||
|
||||
type DiffReader interface {
|
||||
DiffStore(s StoreReader) (*[]Diff, error)
|
||||
}
|
||||
|
||||
type DBCloser interface {
|
||||
Close()
|
||||
}
|
||||
|
|
|
@ -263,6 +263,11 @@ func (s *store) AddVulnerabilityMatchExclusion(exclusions ...v4.VulnerabilityMat
|
|||
|
||||
func (s *store) Close() {
|
||||
s.db.Exec("VACUUM;")
|
||||
|
||||
sqlDB, err := s.db.DB()
|
||||
if err != nil {
|
||||
_ = sqlDB.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// GetAllVulnerabilities gets all vulnerabilities in the database
|
||||
|
|
|
@ -117,16 +117,20 @@ func download(curator *db.Curator, listing *db.ListingEntry) error {
|
|||
}
|
||||
|
||||
func (d *Differ) DiffDatabases() (*[]v4.Diff, error) {
|
||||
baseStore, err := d.baseCurator.GetStore()
|
||||
baseStore, baseDBCloser, err := d.baseCurator.GetStore()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
targetStore, err := d.targetCurator.GetStore()
|
||||
defer baseDBCloser.Close()
|
||||
|
||||
targetStore, targetDBCloser, err := d.targetCurator.GetStore()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer targetDBCloser.Close()
|
||||
|
||||
return baseStore.DiffStore(targetStore)
|
||||
}
|
||||
|
||||
|
|
16
grype/lib.go
16
grype/lib.go
|
@ -38,30 +38,30 @@ func FindVulnerabilitiesForPackage(store store.Store, d *linux.Release, matchers
|
|||
return matcher.FindMatches(store, d, matchers, packages)
|
||||
}
|
||||
|
||||
func LoadVulnerabilityDB(cfg db.Config, update bool) (*store.Store, *db.Status, error) {
|
||||
func LoadVulnerabilityDB(cfg db.Config, update bool) (*store.Store, *db.Status, *db.Closer, error) {
|
||||
dbCurator, err := db.NewCurator(cfg)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
if update {
|
||||
log.Debug("looking for updates on vulnerability database")
|
||||
_, err := dbCurator.Update()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
storeReader, err := dbCurator.GetStore()
|
||||
storeReader, dbCloser, err := dbCurator.GetStore()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
status := dbCurator.Status()
|
||||
|
||||
p, err := db.NewVulnerabilityProvider(storeReader)
|
||||
if err != nil {
|
||||
return nil, &status, err
|
||||
return nil, &status, nil, err
|
||||
}
|
||||
|
||||
s := &store.Store{
|
||||
|
@ -70,7 +70,9 @@ func LoadVulnerabilityDB(cfg db.Config, update bool) (*store.Store, *db.Status,
|
|||
ExclusionProvider: db.NewMatchExclusionProvider(storeReader),
|
||||
}
|
||||
|
||||
return s, &status, nil
|
||||
closer := &db.Closer{DBCloser: dbCloser}
|
||||
|
||||
return s, &status, closer, nil
|
||||
}
|
||||
|
||||
func SetLogger(logger logger.Logger) {
|
||||
|
|
|
@ -43,13 +43,17 @@ func TestCompareSBOMInputToLibResults(t *testing.T) {
|
|||
}
|
||||
|
||||
// get a grype DB
|
||||
store, _, err := grype.LoadVulnerabilityDB(db.Config{
|
||||
store, _, closer, err := grype.LoadVulnerabilityDB(db.Config{
|
||||
DBRootDir: "test-fixtures/grype-db",
|
||||
ListingURL: getListingURL(),
|
||||
ValidateByHashOnGet: false,
|
||||
}, true)
|
||||
assert.NoError(t, err)
|
||||
|
||||
if closer != nil {
|
||||
defer closer.Close()
|
||||
}
|
||||
|
||||
definedPkgTypes := strset.New()
|
||||
for _, p := range syftPkg.AllPkgs {
|
||||
definedPkgTypes.Add(string(p))
|
||||
|
|
Loading…
Reference in a new issue