mirror of
https://github.com/project-zot/zot.git
synced 2026-06-15 20:07:55 +08:00
feat(scheduler): gracefully shutdown (#1951)
wait for workers to finish before exiting should fix tests reporting they couldn't remove rootDir because it's being written by tasks Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
This commit is contained in:
@@ -256,8 +256,12 @@ func (validityT *validityTask) DoWork(ctx context.Context) error {
|
||||
validityT.log.Info().Msg("update signatures validity")
|
||||
|
||||
for signedManifest, sigs := range validityT.repo.Signatures {
|
||||
if zcommon.IsContextDone(ctx) {
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
if len(sigs[zcommon.CosignSignature]) != 0 || len(sigs[zcommon.NotationSignature]) != 0 {
|
||||
err := validityT.metaDB.UpdateSignaturesValidity(validityT.repo.Name, godigest.Digest(signedManifest))
|
||||
err := validityT.metaDB.UpdateSignaturesValidity(ctx, validityT.repo.Name, godigest.Digest(signedManifest))
|
||||
if err != nil {
|
||||
validityT.log.Info().Msg("error while verifying signatures")
|
||||
|
||||
|
||||
@@ -1215,6 +1215,13 @@ func RunVerificationTests(t *testing.T, dbDriverParams map[string]interface{}) {
|
||||
repo := "repo" //nolint:goconst
|
||||
tag := "test" //nolint:goconst
|
||||
|
||||
Convey("verify running an image trust with context done", func() {
|
||||
image := CreateRandomImage()
|
||||
|
||||
err = UploadImage(image, baseURL, repo, tag)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("verify cosign signature is trusted", func() {
|
||||
image := CreateRandomImage()
|
||||
|
||||
@@ -1291,6 +1298,18 @@ func RunVerificationTests(t *testing.T, dbDriverParams map[string]interface{}) {
|
||||
So(err, ShouldBeNil)
|
||||
So(isTrusted, ShouldBeTrue)
|
||||
So(author, ShouldNotBeEmpty)
|
||||
|
||||
Convey("run imagetrust task with context done", func() {
|
||||
repoMeta, err := ctlr.MetaDB.GetRepoMeta(context.Background(), repo)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
cancelCtx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
|
||||
task := imagetrust.NewValidityTask(ctlr.MetaDB, repoMeta, ctlr.Log)
|
||||
err = task.DoWork(cancelCtx)
|
||||
So(err, ShouldEqual, cancelCtx.Err())
|
||||
})
|
||||
})
|
||||
|
||||
Convey("verify notation signature is trusted", func() {
|
||||
|
||||
@@ -61,7 +61,7 @@ func TestCVEConvert(t *testing.T) {
|
||||
Vulnerabilities: false,
|
||||
},
|
||||
mocks.CveInfoMock{
|
||||
GetCVESummaryForImageMediaFn: func(repo string, digest, mediaType string,
|
||||
GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
return cvemodel.ImageCVESummary{}, ErrTestError
|
||||
},
|
||||
@@ -99,7 +99,7 @@ func TestCVEConvert(t *testing.T) {
|
||||
Vulnerabilities: false,
|
||||
},
|
||||
mocks.CveInfoMock{
|
||||
GetCVESummaryForImageMediaFn: func(repo string, digest, mediaType string,
|
||||
GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
return cvemodel.ImageCVESummary{
|
||||
Count: 1,
|
||||
@@ -126,7 +126,7 @@ func TestCVEConvert(t *testing.T) {
|
||||
Vulnerabilities: false,
|
||||
},
|
||||
mocks.CveInfoMock{
|
||||
GetCVESummaryForImageMediaFn: func(repo string, digest, mediaType string,
|
||||
GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
return cvemodel.ImageCVESummary{}, ErrTestError
|
||||
},
|
||||
@@ -149,7 +149,7 @@ func TestCVEConvert(t *testing.T) {
|
||||
Vulnerabilities: false,
|
||||
},
|
||||
mocks.CveInfoMock{
|
||||
GetCVESummaryForImageMediaFn: func(repo string, digest, mediaType string,
|
||||
GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
return cvemodel.ImageCVESummary{
|
||||
Count: 1,
|
||||
@@ -179,7 +179,7 @@ func TestCVEConvert(t *testing.T) {
|
||||
Vulnerabilities: false,
|
||||
},
|
||||
mocks.CveInfoMock{
|
||||
GetCVESummaryForImageMediaFn: func(repo string, digest, mediaType string,
|
||||
GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
return cvemodel.ImageCVESummary{
|
||||
Count: 1,
|
||||
@@ -207,7 +207,7 @@ func TestCVEConvert(t *testing.T) {
|
||||
Vulnerabilities: false,
|
||||
},
|
||||
mocks.CveInfoMock{
|
||||
GetCVESummaryForImageMediaFn: func(repo string, digest, mediaType string,
|
||||
GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
return cvemodel.ImageCVESummary{
|
||||
Count: 1,
|
||||
@@ -248,7 +248,7 @@ func TestCVEConvert(t *testing.T) {
|
||||
Vulnerabilities: false,
|
||||
},
|
||||
mocks.CveInfoMock{
|
||||
GetCVESummaryForImageMediaFn: func(repo string, digest, mediaType string,
|
||||
GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
return cvemodel.ImageCVESummary{
|
||||
Count: 1,
|
||||
@@ -271,7 +271,7 @@ func TestCVEConvert(t *testing.T) {
|
||||
Vulnerabilities: false,
|
||||
},
|
||||
mocks.CveInfoMock{
|
||||
GetCVESummaryForImageMediaFn: func(repo string, digest, mediaType string,
|
||||
GetCVESummaryForImageMediaFn: func(ctx context.Context, repo string, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
return cvemodel.ImageCVESummary{}, ErrTestError
|
||||
},
|
||||
|
||||
@@ -47,7 +47,7 @@ func updateImageSummaryVulnerabilities(
|
||||
return
|
||||
}
|
||||
|
||||
imageCveSummary, err := cveInfo.GetCVESummaryForImageMedia(*imageSummary.RepoName, *imageSummary.Digest,
|
||||
imageCveSummary, err := cveInfo.GetCVESummaryForImageMedia(ctx, *imageSummary.RepoName, *imageSummary.Digest,
|
||||
*imageSummary.MediaType)
|
||||
if err != nil {
|
||||
// Log the error, but we should still include the image in results
|
||||
@@ -91,7 +91,7 @@ func updateManifestSummaryVulnerabilities(
|
||||
return
|
||||
}
|
||||
|
||||
imageCveSummary, err := cveInfo.GetCVESummaryForImageMedia(repoName, *manifestSummary.Digest,
|
||||
imageCveSummary, err := cveInfo.GetCVESummaryForImageMedia(ctx, repoName, *manifestSummary.Digest,
|
||||
ispec.MediaTypeImageManifest)
|
||||
if err != nil {
|
||||
// Log the error, but we should still include the manifest in results
|
||||
|
||||
@@ -19,20 +19,20 @@ import (
|
||||
)
|
||||
|
||||
type CveInfo interface {
|
||||
GetImageListForCVE(repo, cveID string) ([]cvemodel.TagInfo, error)
|
||||
GetImageListWithCVEFixed(repo, cveID string) ([]cvemodel.TagInfo, error)
|
||||
GetCVEListForImage(repo, tag string, searchedCVE string, pageinput cvemodel.PageInput,
|
||||
GetImageListForCVE(ctx context.Context, repo, cveID string) ([]cvemodel.TagInfo, error)
|
||||
GetImageListWithCVEFixed(ctx context.Context, repo, cveID string) ([]cvemodel.TagInfo, error)
|
||||
GetCVEListForImage(ctx context.Context, repo, tag string, searchedCVE string, pageinput cvemodel.PageInput,
|
||||
) ([]cvemodel.CVE, zcommon.PageInfo, error)
|
||||
GetCVESummaryForImageMedia(repo, digest, mediaType string) (cvemodel.ImageCVESummary, error)
|
||||
GetCVESummaryForImageMedia(ctx context.Context, repo, digest, mediaType string) (cvemodel.ImageCVESummary, error)
|
||||
}
|
||||
|
||||
type Scanner interface {
|
||||
ScanImage(image string) (map[string]cvemodel.CVE, error)
|
||||
ScanImage(ctx context.Context, image string) (map[string]cvemodel.CVE, error)
|
||||
IsImageFormatScannable(repo, ref string) (bool, error)
|
||||
IsImageMediaScannable(repo, digestStr, mediaType string) (bool, error)
|
||||
IsResultCached(digestStr string) bool
|
||||
GetCachedResult(digestStr string) map[string]cvemodel.CVE
|
||||
UpdateDB() error
|
||||
UpdateDB(ctx context.Context) error
|
||||
}
|
||||
|
||||
type BaseCveInfo struct {
|
||||
@@ -55,10 +55,10 @@ func NewCVEInfo(scanner Scanner, metaDB mTypes.MetaDB, log log.Logger) *BaseCveI
|
||||
}
|
||||
}
|
||||
|
||||
func (cveinfo BaseCveInfo) GetImageListForCVE(repo, cveID string) ([]cvemodel.TagInfo, error) {
|
||||
func (cveinfo BaseCveInfo) GetImageListForCVE(ctx context.Context, repo, cveID string) ([]cvemodel.TagInfo, error) {
|
||||
imgList := make([]cvemodel.TagInfo, 0)
|
||||
|
||||
repoMeta, err := cveinfo.MetaDB.GetRepoMeta(context.Background(), repo)
|
||||
repoMeta, err := cveinfo.MetaDB.GetRepoMeta(ctx, repo)
|
||||
if err != nil {
|
||||
cveinfo.Log.Error().Err(err).Str("repository", repo).Str("cve-id", cveID).
|
||||
Msg("unable to get list of tags from repo")
|
||||
@@ -80,8 +80,12 @@ func (cveinfo BaseCveInfo) GetImageListForCVE(repo, cveID string) ([]cvemodel.Ta
|
||||
continue
|
||||
}
|
||||
|
||||
cveMap, err := cveinfo.Scanner.ScanImage(zcommon.GetFullImageName(repo, tag))
|
||||
cveMap, err := cveinfo.Scanner.ScanImage(ctx, zcommon.GetFullImageName(repo, tag))
|
||||
if err != nil {
|
||||
if zcommon.IsContextDone(ctx) {
|
||||
return imgList, err
|
||||
}
|
||||
|
||||
cveinfo.Log.Info().Str("image", repo+":"+tag).Err(err).Msg("image scan failed")
|
||||
|
||||
continue
|
||||
@@ -105,8 +109,9 @@ func (cveinfo BaseCveInfo) GetImageListForCVE(repo, cveID string) ([]cvemodel.Ta
|
||||
return imgList, nil
|
||||
}
|
||||
|
||||
func (cveinfo BaseCveInfo) GetImageListWithCVEFixed(repo, cveID string) ([]cvemodel.TagInfo, error) {
|
||||
repoMeta, err := cveinfo.MetaDB.GetRepoMeta(context.Background(), repo)
|
||||
func (cveinfo BaseCveInfo) GetImageListWithCVEFixed(ctx context.Context, repo, cveID string,
|
||||
) ([]cvemodel.TagInfo, error) {
|
||||
repoMeta, err := cveinfo.MetaDB.GetRepoMeta(ctx, repo)
|
||||
if err != nil {
|
||||
cveinfo.Log.Error().Err(err).Str("repository", repo).Str("cve-id", cveID).
|
||||
Msg("unable to get list of tags from repo")
|
||||
@@ -118,6 +123,10 @@ func (cveinfo BaseCveInfo) GetImageListWithCVEFixed(repo, cveID string) ([]cvemo
|
||||
allTags := make([]cvemodel.TagInfo, 0)
|
||||
|
||||
for tag, descriptor := range repoMeta.Tags {
|
||||
if zcommon.IsContextDone(ctx) {
|
||||
return []cvemodel.TagInfo{}, ctx.Err()
|
||||
}
|
||||
|
||||
switch descriptor.MediaType {
|
||||
case ispec.MediaTypeImageManifest:
|
||||
manifestDigestStr := descriptor.Digest
|
||||
@@ -132,7 +141,7 @@ func (cveinfo BaseCveInfo) GetImageListWithCVEFixed(repo, cveID string) ([]cvemo
|
||||
|
||||
allTags = append(allTags, tagInfo)
|
||||
|
||||
if cveinfo.isManifestVulnerable(repo, tag, manifestDigestStr, cveID) {
|
||||
if cveinfo.isManifestVulnerable(ctx, repo, tag, manifestDigestStr, cveID) {
|
||||
vulnerableTags = append(vulnerableTags, tagInfo)
|
||||
}
|
||||
case ispec.MediaTypeImageIndex:
|
||||
@@ -162,7 +171,7 @@ func (cveinfo BaseCveInfo) GetImageListWithCVEFixed(repo, cveID string) ([]cvemo
|
||||
|
||||
allManifests = append(allManifests, manifestDescriptorInfo)
|
||||
|
||||
if cveinfo.isManifestVulnerable(repo, tag, manifest.Digest.String(), cveID) {
|
||||
if cveinfo.isManifestVulnerable(ctx, repo, tag, manifest.Digest.String(), cveID) {
|
||||
vulnerableManifests = append(vulnerableManifests, manifestDescriptorInfo)
|
||||
}
|
||||
}
|
||||
@@ -250,7 +259,8 @@ func getTagInfoForManifest(tag, manifestDigestStr string, metaDB mTypes.MetaDB)
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cveinfo *BaseCveInfo) isManifestVulnerable(repo, tag, manifestDigestStr, cveID string) bool {
|
||||
func (cveinfo *BaseCveInfo) isManifestVulnerable(ctx context.Context, repo, tag, manifestDigestStr, cveID string,
|
||||
) bool {
|
||||
image := zcommon.GetFullImageName(repo, tag)
|
||||
|
||||
isValidImage, err := cveinfo.Scanner.IsImageMediaScannable(repo, manifestDigestStr, ispec.MediaTypeImageManifest)
|
||||
@@ -261,7 +271,7 @@ func (cveinfo *BaseCveInfo) isManifestVulnerable(repo, tag, manifestDigestStr, c
|
||||
return true
|
||||
}
|
||||
|
||||
cveMap, err := cveinfo.Scanner.ScanImage(zcommon.GetFullImageName(repo, manifestDigestStr))
|
||||
cveMap, err := cveinfo.Scanner.ScanImage(ctx, zcommon.GetFullImageName(repo, manifestDigestStr))
|
||||
if err != nil {
|
||||
cveinfo.Log.Debug().Str("image", image).Str("cve-id", cveID).
|
||||
Msg("scanning failed, adding as a vulnerable image")
|
||||
@@ -330,10 +340,10 @@ func filterCVEList(cveMap map[string]cvemodel.CVE, searchedCVE string, pageFinde
|
||||
}
|
||||
}
|
||||
|
||||
func (cveinfo BaseCveInfo) GetCVEListForImage(repo, ref string, searchedCVE string, pageInput cvemodel.PageInput) (
|
||||
[]cvemodel.CVE,
|
||||
zcommon.PageInfo,
|
||||
error,
|
||||
func (cveinfo BaseCveInfo) GetCVEListForImage(ctx context.Context, repo, ref string, searchedCVE string,
|
||||
pageInput cvemodel.PageInput,
|
||||
) (
|
||||
[]cvemodel.CVE, zcommon.PageInfo, error,
|
||||
) {
|
||||
isValidImage, err := cveinfo.Scanner.IsImageFormatScannable(repo, ref)
|
||||
if !isValidImage {
|
||||
@@ -344,7 +354,7 @@ func (cveinfo BaseCveInfo) GetCVEListForImage(repo, ref string, searchedCVE stri
|
||||
|
||||
image := zcommon.GetFullImageName(repo, ref)
|
||||
|
||||
cveMap, err := cveinfo.Scanner.ScanImage(image)
|
||||
cveMap, err := cveinfo.Scanner.ScanImage(ctx, image)
|
||||
if err != nil {
|
||||
return []cvemodel.CVE{}, zcommon.PageInfo{}, err
|
||||
}
|
||||
@@ -361,7 +371,7 @@ func (cveinfo BaseCveInfo) GetCVEListForImage(repo, ref string, searchedCVE stri
|
||||
return cveList, pageInfo, nil
|
||||
}
|
||||
|
||||
func (cveinfo BaseCveInfo) GetCVESummaryForImageMedia(repo, digest, mediaType string,
|
||||
func (cveinfo BaseCveInfo) GetCVESummaryForImageMedia(ctx context.Context, repo, digest, mediaType string,
|
||||
) (cvemodel.ImageCVESummary, error) {
|
||||
// There are several cases, expected returned values below:
|
||||
// not scanned yet - max severity "" - cve count 0 - no Errors
|
||||
|
||||
@@ -913,7 +913,7 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
// MetaDB loaded with initial data, now mock the scanner
|
||||
// Setup test CVE data in mock scanner
|
||||
scanner := mocks.CveScannerMock{
|
||||
ScanImageFn: func(image string) (map[string]cvemodel.CVE, error) {
|
||||
ScanImageFn: func(ctx context.Context, image string) (map[string]cvemodel.CVE, error) {
|
||||
result := cache.Get(image)
|
||||
// Will not match sending the repo:tag as a parameter, but we don't care
|
||||
if result != nil {
|
||||
@@ -1127,15 +1127,17 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
SortBy: cveinfo.SeverityDsc,
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Image is found
|
||||
cveList, pageInfo, err := cveInfo.GetCVEListForImage(repo1, "0.1.0", "", pageInput)
|
||||
cveList, pageInfo, err := cveInfo.GetCVEListForImage(ctx, repo1, "0.1.0", "", pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveList), ShouldEqual, 1)
|
||||
So(cveList[0].ID, ShouldEqual, "CVE1")
|
||||
So(pageInfo.ItemCount, ShouldEqual, 1)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 1)
|
||||
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(repo1, "1.0.0", "", pageInput)
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo1, "1.0.0", "", pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveList), ShouldEqual, 3)
|
||||
So(cveList[0].ID, ShouldEqual, "CVE2")
|
||||
@@ -1144,7 +1146,7 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
So(pageInfo.ItemCount, ShouldEqual, 3)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 3)
|
||||
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(repo1, "1.0.1", "", pageInput)
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo1, "1.0.1", "", pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveList), ShouldEqual, 2)
|
||||
So(cveList[0].ID, ShouldEqual, "CVE1")
|
||||
@@ -1152,21 +1154,21 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
So(pageInfo.ItemCount, ShouldEqual, 2)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 2)
|
||||
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(repo1, "1.1.0", "", pageInput)
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo1, "1.1.0", "", pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveList), ShouldEqual, 1)
|
||||
So(cveList[0].ID, ShouldEqual, "CVE3")
|
||||
So(pageInfo.ItemCount, ShouldEqual, 1)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 1)
|
||||
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(repo6, "1.0.0", "", pageInput)
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo6, "1.0.0", "", pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveList), ShouldEqual, 0)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 0)
|
||||
|
||||
// Image is multiarch
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(repoMultiarch, "tagIndex", "", pageInput)
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repoMultiarch, "tagIndex", "", pageInput)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveList), ShouldEqual, 1)
|
||||
So(cveList[0].ID, ShouldEqual, "CVE1")
|
||||
@@ -1174,35 +1176,35 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
So(pageInfo.TotalCount, ShouldEqual, 1)
|
||||
|
||||
// Image is not scannable
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(repo2, "1.0.0", "", pageInput)
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo2, "1.0.0", "", pageInput)
|
||||
So(err, ShouldEqual, zerr.ErrScanNotSupported)
|
||||
So(len(cveList), ShouldEqual, 0)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 0)
|
||||
|
||||
// Tag is not found
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(repo3, "1.0.0", "", pageInput)
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo3, "1.0.0", "", pageInput)
|
||||
So(err, ShouldEqual, zerr.ErrTagMetaNotFound)
|
||||
So(len(cveList), ShouldEqual, 0)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 0)
|
||||
|
||||
// Scan failed
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(repo7, "1.0.0", "", pageInput)
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo7, "1.0.0", "", pageInput)
|
||||
So(err, ShouldEqual, ErrFailedScan)
|
||||
So(len(cveList), ShouldEqual, 0)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 0)
|
||||
|
||||
// Tag is not found
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage("repo-with-bad-tag-digest", "tag", "", pageInput)
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo-with-bad-tag-digest", "tag", "", pageInput)
|
||||
So(err, ShouldEqual, zerr.ErrImageMetaNotFound)
|
||||
So(len(cveList), ShouldEqual, 0)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 0)
|
||||
|
||||
// Repo is not found
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(repo100, "1.0.0", "", pageInput)
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo100, "1.0.0", "", pageInput)
|
||||
So(err, ShouldEqual, zerr.ErrRepoMetaNotFound)
|
||||
So(len(cveList), ShouldEqual, 0)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
@@ -1212,51 +1214,51 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
t.Log("\nTest GetCVESummaryForImage\n")
|
||||
|
||||
// Image is found
|
||||
cveSummary, err := cveInfo.GetCVESummaryForImageMedia(repo1, image11Digest, image11Media)
|
||||
cveSummary, err := cveInfo.GetCVESummaryForImageMedia(ctx, repo1, image11Digest, image11Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 1)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "MEDIUM")
|
||||
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(repo1, image12Digest, image12Media)
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo1, image12Digest, image12Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 3)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "HIGH")
|
||||
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(repo1, image14Digest, image14Media)
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo1, image14Digest, image14Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 2)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "MEDIUM")
|
||||
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(repo1, image13Digest, image13Media)
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo1, image13Digest, image13Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 1)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "LOW")
|
||||
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(repo6, image61Digest, image61Media)
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo6, image61Digest, image61Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "NONE")
|
||||
|
||||
// Image is multiarch
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(repoMultiarch, indexDigest, indexMedia)
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repoMultiarch, indexDigest, indexMedia)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 1)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "MEDIUM")
|
||||
|
||||
// Image is not scannable
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(repo2, image21Digest, image21Media)
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo2, image21Digest, image21Media)
|
||||
So(err, ShouldEqual, zerr.ErrScanNotSupported)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
// Scan failed
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(repo5, image71Digest, image71Media)
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo5, image71Digest, image71Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
// Repo is not found
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(repo100,
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo100,
|
||||
godigest.FromString("missing_digest").String(), ispec.MediaTypeImageManifest)
|
||||
So(err, ShouldEqual, zerr.ErrRepoMetaNotFound)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
@@ -1265,19 +1267,19 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
t.Log("\nTest GetImageListWithCVEFixed\n")
|
||||
|
||||
// Image is found
|
||||
tagList, err := cveInfo.GetImageListWithCVEFixed(repo1, "CVE1")
|
||||
tagList, err := cveInfo.GetImageListWithCVEFixed(ctx, repo1, "CVE1")
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tagList), ShouldEqual, 1)
|
||||
So(tagList[0].Tag, ShouldEqual, "1.1.0")
|
||||
|
||||
tagList, err = cveInfo.GetImageListWithCVEFixed(repo1, "CVE2")
|
||||
tagList, err = cveInfo.GetImageListWithCVEFixed(ctx, repo1, "CVE2")
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tagList), ShouldEqual, 2)
|
||||
expectedTags := []string{"1.0.1", "1.1.0"}
|
||||
So(expectedTags, ShouldContain, tagList[0].Tag)
|
||||
So(expectedTags, ShouldContain, tagList[1].Tag)
|
||||
|
||||
tagList, err = cveInfo.GetImageListWithCVEFixed(repo1, "CVE3")
|
||||
tagList, err = cveInfo.GetImageListWithCVEFixed(ctx, repo1, "CVE3")
|
||||
So(err, ShouldBeNil)
|
||||
// CVE3 is not present in 0.1.0, but that is older than all other
|
||||
// images where it is present. The rest of the images explicitly have it.
|
||||
@@ -1285,13 +1287,13 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
So(len(tagList), ShouldEqual, 0)
|
||||
|
||||
// Image doesn't have any CVEs in the first place
|
||||
tagList, err = cveInfo.GetImageListWithCVEFixed(repo6, "CVE1")
|
||||
tagList, err = cveInfo.GetImageListWithCVEFixed(ctx, repo6, "CVE1")
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tagList), ShouldEqual, 1)
|
||||
So(tagList[0].Tag, ShouldEqual, "1.0.0")
|
||||
|
||||
// Image is not scannable
|
||||
tagList, err = cveInfo.GetImageListWithCVEFixed(repo2, "CVE100")
|
||||
tagList, err = cveInfo.GetImageListWithCVEFixed(ctx, repo2, "CVE100")
|
||||
// CVE is not considered fixed as scan is not possible
|
||||
// but do not return an error
|
||||
So(err, ShouldBeNil)
|
||||
@@ -1299,14 +1301,14 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
|
||||
// Repo is not found, there could potentially be unaffected tags in the repo
|
||||
// but we can't access their data
|
||||
tagList, err = cveInfo.GetImageListWithCVEFixed(repo100, "CVE100")
|
||||
tagList, err = cveInfo.GetImageListWithCVEFixed(ctx, repo100, "CVE100")
|
||||
So(err, ShouldEqual, zerr.ErrRepoMetaNotFound)
|
||||
So(len(tagList), ShouldEqual, 0)
|
||||
|
||||
t.Log("\nTest GetImageListForCVE\n")
|
||||
|
||||
// Image is found
|
||||
tagList, err = cveInfo.GetImageListForCVE(repo1, "CVE1")
|
||||
tagList, err = cveInfo.GetImageListForCVE(ctx, repo1, "CVE1")
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tagList), ShouldEqual, 3)
|
||||
expectedTags = []string{"0.1.0", "1.0.0", "1.0.1"}
|
||||
@@ -1314,12 +1316,12 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
So(expectedTags, ShouldContain, tagList[1].Tag)
|
||||
So(expectedTags, ShouldContain, tagList[2].Tag)
|
||||
|
||||
tagList, err = cveInfo.GetImageListForCVE(repo1, "CVE2")
|
||||
tagList, err = cveInfo.GetImageListForCVE(ctx, repo1, "CVE2")
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tagList), ShouldEqual, 1)
|
||||
So(tagList[0].Tag, ShouldEqual, "1.0.0")
|
||||
|
||||
tagList, err = cveInfo.GetImageListForCVE(repo1, "CVE3")
|
||||
tagList, err = cveInfo.GetImageListForCVE(ctx, repo1, "CVE3")
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tagList), ShouldEqual, 3)
|
||||
expectedTags = []string{"1.0.0", "1.0.1", "1.1.0"}
|
||||
@@ -1328,32 +1330,32 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
So(expectedTags, ShouldContain, tagList[2].Tag)
|
||||
|
||||
// Image/repo doesn't have the CVE at all
|
||||
tagList, err = cveInfo.GetImageListForCVE(repo6, "CVE1")
|
||||
tagList, err = cveInfo.GetImageListForCVE(ctx, repo6, "CVE1")
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tagList), ShouldEqual, 0)
|
||||
|
||||
// Image is not scannable
|
||||
tagList, err = cveInfo.GetImageListForCVE(repo2, "CVE100")
|
||||
tagList, err = cveInfo.GetImageListForCVE(ctx, repo2, "CVE100")
|
||||
// Image is not considered affected with CVE as scan is not possible
|
||||
// but do not return an error
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tagList), ShouldEqual, 0)
|
||||
|
||||
// Tag is not found, but we should not error
|
||||
tagList, err = cveInfo.GetImageListForCVE(repo3, "CVE101")
|
||||
tagList, err = cveInfo.GetImageListForCVE(ctx, repo3, "CVE101")
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tagList), ShouldEqual, 0)
|
||||
|
||||
// Repo is not found, assume it is affected by the CVE
|
||||
// But we don't have enough of its data to actually return it
|
||||
tagList, err = cveInfo.GetImageListForCVE(repo100, "CVE100")
|
||||
tagList, err = cveInfo.GetImageListForCVE(ctx, repo100, "CVE100")
|
||||
So(err, ShouldEqual, zerr.ErrRepoMetaNotFound)
|
||||
So(len(tagList), ShouldEqual, 0)
|
||||
|
||||
t.Log("\nTest errors while scanning\n")
|
||||
|
||||
faultyScanner := mocks.CveScannerMock{
|
||||
ScanImageFn: func(image string) (map[string]cvemodel.CVE, error) {
|
||||
ScanImageFn: func(ctx context.Context, image string) (map[string]cvemodel.CVE, error) {
|
||||
// Could be any type of error, let's reuse this one
|
||||
return nil, zerr.ErrScanNotSupported
|
||||
},
|
||||
@@ -1361,24 +1363,24 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
|
||||
cveInfo = cveinfo.BaseCveInfo{Log: log, Scanner: faultyScanner, MetaDB: metaDB}
|
||||
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(repo1, image11Digest, image11Media)
|
||||
cveSummary, err = cveInfo.GetCVESummaryForImageMedia(ctx, repo1, image11Digest, image11Media)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldEqual, 0)
|
||||
So(cveSummary.MaxSeverity, ShouldEqual, "")
|
||||
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(repo1, "0.1.0", "", pageInput)
|
||||
cveList, pageInfo, err = cveInfo.GetCVEListForImage(ctx, repo1, "0.1.0", "", pageInput)
|
||||
So(err, ShouldNotBeNil)
|
||||
So(cveList, ShouldBeEmpty)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 0)
|
||||
So(pageInfo.TotalCount, ShouldEqual, 0)
|
||||
|
||||
tagList, err = cveInfo.GetImageListWithCVEFixed(repo1, "CVE1")
|
||||
tagList, err = cveInfo.GetImageListWithCVEFixed(ctx, repo1, "CVE1")
|
||||
// CVE is not considered fixed as scan is not possible
|
||||
// but do not return an error
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tagList), ShouldEqual, 0)
|
||||
|
||||
tagList, err = cveInfo.GetImageListForCVE(repo1, "CVE1")
|
||||
tagList, err = cveInfo.GetImageListForCVE(ctx, repo1, "CVE1")
|
||||
// Image is not considered affected with CVE as scan is not possible
|
||||
// but do not return an error
|
||||
So(err, ShouldBeNil)
|
||||
@@ -1390,19 +1392,19 @@ func TestCVEStruct(t *testing.T) { //nolint:gocyclo
|
||||
},
|
||||
}, MetaDB: metaDB}
|
||||
|
||||
_, err = cveInfo.GetImageListForCVE(repoMultiarch, "CVE1")
|
||||
_, err = cveInfo.GetImageListForCVE(ctx, repoMultiarch, "CVE1")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
cveInfo = cveinfo.BaseCveInfo{Log: log, Scanner: mocks.CveScannerMock{
|
||||
IsImageFormatScannableFn: func(repo, reference string) (bool, error) {
|
||||
return true, nil
|
||||
},
|
||||
ScanImageFn: func(image string) (map[string]cvemodel.CVE, error) {
|
||||
ScanImageFn: func(ctx context.Context, image string) (map[string]cvemodel.CVE, error) {
|
||||
return nil, zerr.ErrTypeAssertionFailed
|
||||
},
|
||||
}, MetaDB: metaDB}
|
||||
|
||||
_, err = cveInfo.GetImageListForCVE(repoMultiarch, "CVE1")
|
||||
_, err = cveInfo.GetImageListForCVE(ctx, repoMultiarch, "CVE1")
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
@@ -1545,7 +1547,7 @@ func TestFixedTagsWithIndex(t *testing.T) {
|
||||
|
||||
cveInfo := cveinfo.NewCVEInfo(ctlr.CveScanner, ctlr.MetaDB, ctlr.Log)
|
||||
|
||||
tagsInfo, err := cveInfo.GetImageListWithCVEFixed("repo", Vulnerability1ID)
|
||||
tagsInfo, err := cveInfo.GetImageListWithCVEFixed(context.Background(), "repo", Vulnerability1ID)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(tagsInfo), ShouldEqual, 1)
|
||||
So(len(tagsInfo[0].Manifests), ShouldEqual, 1)
|
||||
@@ -1593,7 +1595,7 @@ func TestGetCVESummaryForImageMediaErrors(t *testing.T) {
|
||||
|
||||
cveInfo := cveinfo.NewCVEInfo(scanner, metaDB, log)
|
||||
|
||||
_, err := cveInfo.GetCVESummaryForImageMedia("repo", "digest", ispec.MediaTypeImageManifest)
|
||||
_, err := cveInfo.GetCVESummaryForImageMedia(context.Background(), "repo", "digest", ispec.MediaTypeImageManifest)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -73,7 +73,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
|
||||
// Setup test CVE data in mock scanner
|
||||
scanner := mocks.CveScannerMock{
|
||||
ScanImageFn: func(image string) (map[string]cvemodel.CVE, error) {
|
||||
ScanImageFn: func(ctx context.Context, image string) (map[string]cvemodel.CVE, error) {
|
||||
cveMap := map[string]cvemodel.CVE{}
|
||||
|
||||
if image == "repo1:0.1.0" {
|
||||
@@ -106,6 +106,8 @@ func TestCVEPagination(t *testing.T) {
|
||||
log := log.NewLogger("debug", "")
|
||||
cveInfo := cveinfo.BaseCveInfo{Log: log, Scanner: scanner, MetaDB: metaDB}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
Convey("create new paginator errors", func() {
|
||||
paginator, err := cveinfo.NewCvePageFinder(-1, 10, cveinfo.AlphabeticAsc)
|
||||
So(paginator, ShouldBeNil)
|
||||
@@ -138,7 +140,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
Convey("Page", func() {
|
||||
Convey("defaults", func() {
|
||||
// By default expect unlimitted results sorted by severity
|
||||
cves, pageInfo, err := cveInfo.GetCVEListForImage("repo1", "0.1.0", "", cvemodel.PageInput{})
|
||||
cves, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{})
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cves), ShouldEqual, 5)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 5)
|
||||
@@ -149,7 +151,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
previousSeverity = severityToInt[cve.Severity]
|
||||
}
|
||||
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage("repo1", "1.0.0", "", cvemodel.PageInput{})
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "", cvemodel.PageInput{})
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cves), ShouldEqual, 30)
|
||||
So(pageInfo.ItemCount, ShouldEqual, 30)
|
||||
@@ -167,7 +169,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
cveIds = append(cveIds, fmt.Sprintf("CVE%d", i))
|
||||
}
|
||||
|
||||
cves, pageInfo, err := cveInfo.GetCVEListForImage("repo1", "0.1.0", "",
|
||||
cves, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "",
|
||||
cvemodel.PageInput{SortBy: cveinfo.AlphabeticAsc})
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cves), ShouldEqual, 5)
|
||||
@@ -178,7 +180,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
}
|
||||
|
||||
sort.Strings(cveIds)
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage("repo1", "1.0.0", "",
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "",
|
||||
cvemodel.PageInput{SortBy: cveinfo.AlphabeticAsc})
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cves), ShouldEqual, 30)
|
||||
@@ -189,7 +191,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
}
|
||||
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(cveIds)))
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage("repo1", "1.0.0", "",
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "",
|
||||
cvemodel.PageInput{SortBy: cveinfo.AlphabeticDsc})
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cves), ShouldEqual, 30)
|
||||
@@ -199,7 +201,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
So(cve.ID, ShouldEqual, cveIds[i])
|
||||
}
|
||||
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage("repo1", "1.0.0", "",
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "",
|
||||
cvemodel.PageInput{SortBy: cveinfo.SeverityDsc})
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cves), ShouldEqual, 30)
|
||||
@@ -218,7 +220,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
cveIds = append(cveIds, fmt.Sprintf("CVE%d", i))
|
||||
}
|
||||
|
||||
cves, pageInfo, err := cveInfo.GetCVEListForImage("repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
cves, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
Limit: 3,
|
||||
Offset: 1,
|
||||
SortBy: cveinfo.AlphabeticAsc,
|
||||
@@ -232,7 +234,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
So(cves[1].ID, ShouldEqual, "CVE2")
|
||||
So(cves[2].ID, ShouldEqual, "CVE3")
|
||||
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage("repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
Limit: 2,
|
||||
Offset: 1,
|
||||
SortBy: cveinfo.AlphabeticDsc,
|
||||
@@ -245,7 +247,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
So(cves[0].ID, ShouldEqual, "CVE3")
|
||||
So(cves[1].ID, ShouldEqual, "CVE2")
|
||||
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage("repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
Limit: 3,
|
||||
Offset: 1,
|
||||
SortBy: cveinfo.SeverityDsc,
|
||||
@@ -262,7 +264,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
}
|
||||
|
||||
sort.Strings(cveIds)
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage("repo1", "1.0.0", "", cvemodel.PageInput{
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "1.0.0", "", cvemodel.PageInput{
|
||||
Limit: 5,
|
||||
Offset: 20,
|
||||
SortBy: cveinfo.AlphabeticAsc,
|
||||
@@ -278,7 +280,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("limit > len(cves)", func() {
|
||||
cves, pageInfo, err := cveInfo.GetCVEListForImage("repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
cves, pageInfo, err := cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
Limit: 6,
|
||||
Offset: 3,
|
||||
SortBy: cveinfo.AlphabeticAsc,
|
||||
@@ -291,7 +293,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
So(cves[0].ID, ShouldEqual, "CVE3")
|
||||
So(cves[1].ID, ShouldEqual, "CVE4")
|
||||
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage("repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
Limit: 6,
|
||||
Offset: 3,
|
||||
SortBy: cveinfo.AlphabeticDsc,
|
||||
@@ -304,7 +306,7 @@ func TestCVEPagination(t *testing.T) {
|
||||
So(cves[0].ID, ShouldEqual, "CVE1")
|
||||
So(cves[1].ID, ShouldEqual, "CVE0")
|
||||
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage("repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
cves, pageInfo, err = cveInfo.GetCVEListForImage(ctx, "repo1", "0.1.0", "", cvemodel.PageInput{
|
||||
Limit: 6,
|
||||
Offset: 3,
|
||||
SortBy: cveinfo.SeverityDsc,
|
||||
|
||||
@@ -183,7 +183,7 @@ func (st *scanTask) DoWork(ctx context.Context) error {
|
||||
|
||||
// We cache the results internally in the scanner
|
||||
// so we can discard the actual results for now
|
||||
if _, err := st.generator.scanner.ScanImage(image); err != nil {
|
||||
if _, err := st.generator.scanner.ScanImage(ctx, image); err != nil {
|
||||
st.generator.log.Error().Err(err).Str("image", image).Msg("Scheduled CVE scan errored for image")
|
||||
st.generator.addError(st.digest, err)
|
||||
|
||||
|
||||
@@ -216,7 +216,7 @@ func TestScanGeneratorWithMockedData(t *testing.T) { //nolint: gocyclo
|
||||
// MetaDB loaded with initial data, now mock the scanner
|
||||
// Setup test CVE data in mock scanner
|
||||
scanner := mocks.CveScannerMock{
|
||||
ScanImageFn: func(image string) (map[string]cvemodel.CVE, error) {
|
||||
ScanImageFn: func(ctx context.Context, image string) (map[string]cvemodel.CVE, error) {
|
||||
result := cache.Get(image)
|
||||
// Will not match sending the repo:tag as a parameter, but we don't care
|
||||
if result != nil {
|
||||
@@ -408,7 +408,7 @@ func TestScanGeneratorWithMockedData(t *testing.T) { //nolint: gocyclo
|
||||
IsResultCachedFn: func(digest string) bool {
|
||||
return cache.Contains(digest)
|
||||
},
|
||||
UpdateDBFn: func() error {
|
||||
UpdateDBFn: func(ctx context.Context) error {
|
||||
cache.Purge()
|
||||
|
||||
return nil
|
||||
@@ -416,7 +416,7 @@ func TestScanGeneratorWithMockedData(t *testing.T) { //nolint: gocyclo
|
||||
}
|
||||
|
||||
// Purge scan, it should not be needed
|
||||
So(scanner.UpdateDB(), ShouldBeNil)
|
||||
So(scanner.UpdateDB(context.Background()), ShouldBeNil)
|
||||
|
||||
// Verify none of the entries are cached to begin with
|
||||
t.Log("verify cache is initially empty")
|
||||
@@ -515,7 +515,7 @@ func TestScanGeneratorWithRealData(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
scanner := cveinfo.NewScanner(storeController, metaDB, "ghcr.io/project-zot/trivy-db", "", logger)
|
||||
err = scanner.UpdateDB()
|
||||
err = scanner.UpdateDB(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
So(scanner.IsResultCached(image.DigestStr()), ShouldBeFalse)
|
||||
@@ -551,7 +551,7 @@ func TestScanGeneratorWithRealData(t *testing.T) {
|
||||
|
||||
So(scanner.IsResultCached(image.DigestStr()), ShouldBeTrue)
|
||||
|
||||
cveMap, err := scanner.ScanImage("zot-test:0.0.1")
|
||||
cveMap, err := scanner.ScanImage(context.Background(), "zot-test:0.0.1")
|
||||
So(err, ShouldBeNil)
|
||||
t.Logf("cveMap: %v", cveMap)
|
||||
// As of September 22 2023 there are 5 CVEs:
|
||||
@@ -567,7 +567,7 @@ func TestScanGeneratorWithRealData(t *testing.T) {
|
||||
cveInfo := cveinfo.NewCVEInfo(scanner, metaDB, logger)
|
||||
|
||||
// Based on cache population only, no extra scanning
|
||||
cveSummary, err := cveInfo.GetCVESummaryForImageMedia("zot-test", image.DigestStr(),
|
||||
cveSummary, err := cveInfo.GetCVESummaryForImageMedia(context.Background(), "zot-test", image.DigestStr(),
|
||||
image.ManifestDescriptor.MediaType)
|
||||
So(err, ShouldBeNil)
|
||||
So(cveSummary.Count, ShouldBeGreaterThanOrEqualTo, 5)
|
||||
|
||||
@@ -157,9 +157,7 @@ func (scanner Scanner) getTrivyOptions(image string) flag.Options {
|
||||
return opts
|
||||
}
|
||||
|
||||
func (scanner Scanner) runTrivy(opts flag.Options) (types.Report, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
func (scanner Scanner) runTrivy(ctx context.Context, opts flag.Options) (types.Report, error) {
|
||||
err := scanner.checkDBPresence()
|
||||
if err != nil {
|
||||
return types.Report{}, err
|
||||
@@ -191,7 +189,7 @@ func (scanner Scanner) IsImageFormatScannable(repo, ref string) (bool, error) {
|
||||
)
|
||||
|
||||
if zcommon.IsTag(ref) {
|
||||
imgDescriptor, err := getImageDescriptor(scanner.metaDB, repo, ref)
|
||||
imgDescriptor, err := getImageDescriptor(context.Background(), scanner.metaDB, repo, ref)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -316,7 +314,7 @@ func (scanner Scanner) GetCachedResult(digest string) map[string]cvemodel.CVE {
|
||||
return scanner.cache.Get(digest)
|
||||
}
|
||||
|
||||
func (scanner Scanner) ScanImage(image string) (map[string]cvemodel.CVE, error) {
|
||||
func (scanner Scanner) ScanImage(ctx context.Context, image string) (map[string]cvemodel.CVE, error) {
|
||||
var (
|
||||
originalImageInput = image
|
||||
digest string
|
||||
@@ -328,7 +326,7 @@ func (scanner Scanner) ScanImage(image string) (map[string]cvemodel.CVE, error)
|
||||
digest = ref
|
||||
|
||||
if isTag {
|
||||
imgDescriptor, err := getImageDescriptor(scanner.metaDB, repo, ref)
|
||||
imgDescriptor, err := getImageDescriptor(ctx, scanner.metaDB, repo, ref)
|
||||
if err != nil {
|
||||
return map[string]cvemodel.CVE{}, err
|
||||
}
|
||||
@@ -351,9 +349,9 @@ func (scanner Scanner) ScanImage(image string) (map[string]cvemodel.CVE, error)
|
||||
|
||||
switch mediaType {
|
||||
case ispec.MediaTypeImageIndex:
|
||||
cveIDMap, err = scanner.scanIndex(repo, digest)
|
||||
cveIDMap, err = scanner.scanIndex(ctx, repo, digest)
|
||||
default:
|
||||
cveIDMap, err = scanner.scanManifest(repo, digest)
|
||||
cveIDMap, err = scanner.scanManifest(ctx, repo, digest)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -365,7 +363,7 @@ func (scanner Scanner) ScanImage(image string) (map[string]cvemodel.CVE, error)
|
||||
return cveIDMap, nil
|
||||
}
|
||||
|
||||
func (scanner Scanner) scanManifest(repo, digest string) (map[string]cvemodel.CVE, error) {
|
||||
func (scanner Scanner) scanManifest(ctx context.Context, repo, digest string) (map[string]cvemodel.CVE, error) {
|
||||
if cachedMap := scanner.cache.Get(digest); cachedMap != nil {
|
||||
return cachedMap, nil
|
||||
}
|
||||
@@ -375,7 +373,7 @@ func (scanner Scanner) scanManifest(repo, digest string) (map[string]cvemodel.CV
|
||||
|
||||
scanner.dbLock.Lock()
|
||||
opts := scanner.getTrivyOptions(image)
|
||||
report, err := scanner.runTrivy(opts)
|
||||
report, err := scanner.runTrivy(ctx, opts)
|
||||
scanner.dbLock.Unlock()
|
||||
|
||||
if err != nil { //nolint: wsl
|
||||
@@ -441,7 +439,7 @@ func (scanner Scanner) scanManifest(repo, digest string) (map[string]cvemodel.CV
|
||||
return cveidMap, nil
|
||||
}
|
||||
|
||||
func (scanner Scanner) scanIndex(repo, digest string) (map[string]cvemodel.CVE, error) {
|
||||
func (scanner Scanner) scanIndex(ctx context.Context, repo, digest string) (map[string]cvemodel.CVE, error) {
|
||||
if cachedMap := scanner.cache.Get(digest); cachedMap != nil {
|
||||
return cachedMap, nil
|
||||
}
|
||||
@@ -459,7 +457,7 @@ func (scanner Scanner) scanIndex(repo, digest string) (map[string]cvemodel.CVE,
|
||||
|
||||
for _, manifest := range indexData.Index.Manifests {
|
||||
if isScannable, err := scanner.isManifestScanable(manifest.Digest.String()); isScannable && err == nil {
|
||||
manifestCveIDMap, err := scanner.scanManifest(repo, manifest.Digest.String())
|
||||
manifestCveIDMap, err := scanner.scanManifest(ctx, repo, manifest.Digest.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -476,7 +474,7 @@ func (scanner Scanner) scanIndex(repo, digest string) (map[string]cvemodel.CVE,
|
||||
}
|
||||
|
||||
// UpdateDB downloads the Trivy DB / Cache under the store root directory.
|
||||
func (scanner Scanner) UpdateDB() error {
|
||||
func (scanner Scanner) UpdateDB(ctx context.Context) error {
|
||||
// We need a lock as using multiple substores each with its own DB
|
||||
// can result in a DATARACE because some varibles in trivy-db are global
|
||||
// https://github.com/project-zot/trivy-db/blob/main/pkg/db/db.go#L23
|
||||
@@ -486,7 +484,7 @@ func (scanner Scanner) UpdateDB() error {
|
||||
if scanner.storeController.DefaultStore != nil {
|
||||
dbDir := path.Join(scanner.storeController.DefaultStore.RootDir(), "_trivy")
|
||||
|
||||
err := scanner.updateDB(dbDir)
|
||||
err := scanner.updateDB(ctx, dbDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -496,7 +494,7 @@ func (scanner Scanner) UpdateDB() error {
|
||||
for _, storage := range scanner.storeController.SubStore {
|
||||
dbDir := path.Join(storage.RootDir(), "_trivy")
|
||||
|
||||
err := scanner.updateDB(dbDir)
|
||||
err := scanner.updateDB(ctx, dbDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -508,11 +506,9 @@ func (scanner Scanner) UpdateDB() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (scanner Scanner) updateDB(dbDir string) error {
|
||||
func (scanner Scanner) updateDB(ctx context.Context, dbDir string) error {
|
||||
scanner.log.Debug().Str("dbDir", dbDir).Msg("Download Trivy DB to destination dir")
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
registryOpts := fanalTypes.RegistryOptions{Insecure: false}
|
||||
|
||||
scanner.log.Debug().Str("dbDir", dbDir).Msg("Started downloading Trivy DB to destination dir")
|
||||
@@ -569,8 +565,8 @@ func (scanner Scanner) checkDBPresence() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getImageDescriptor(metaDB mTypes.MetaDB, repo, tag string) (mTypes.Descriptor, error) {
|
||||
repoMeta, err := metaDB.GetRepoMeta(context.Background(), repo)
|
||||
func getImageDescriptor(ctx context.Context, metaDB mTypes.MetaDB, repo, tag string) (mTypes.Descriptor, error) {
|
||||
repoMeta, err := metaDB.GetRepoMeta(ctx, repo)
|
||||
if err != nil {
|
||||
return mTypes.Descriptor{}, err
|
||||
}
|
||||
|
||||
@@ -128,46 +128,56 @@ func TestMultipleStoragePath(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Try to scan without the DB being downloaded
|
||||
_, err = scanner.ScanImage(img0)
|
||||
_, err = scanner.ScanImage(context.Background(), img0)
|
||||
So(err, ShouldNotBeNil)
|
||||
So(err, ShouldWrap, zerr.ErrCVEDBNotFound)
|
||||
|
||||
// Try to scan with a context done
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
|
||||
_, err = scanner.ScanImage(ctx, img0)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
ctx = context.Background()
|
||||
|
||||
// Download DB since DB download on scan is disabled
|
||||
err = scanner.UpdateDB()
|
||||
err = scanner.UpdateDB(ctx)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Scanning image in default store
|
||||
cveMap, err := scanner.ScanImage(img0)
|
||||
cveMap, err := scanner.ScanImage(ctx, img0)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveMap), ShouldEqual, 0)
|
||||
|
||||
// Scanning image in substore
|
||||
cveMap, err = scanner.ScanImage(img1)
|
||||
cveMap, err = scanner.ScanImage(ctx, img1)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(cveMap), ShouldEqual, 0)
|
||||
|
||||
// Scanning image which does not exist
|
||||
cveMap, err = scanner.ScanImage("a/test/image2:tag100")
|
||||
cveMap, err = scanner.ScanImage(ctx, "a/test/image2:tag100")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(len(cveMap), ShouldEqual, 0)
|
||||
|
||||
// Download the DB to a default store location without permissions
|
||||
err = os.Chmod(firstRootDir, 0o000)
|
||||
So(err, ShouldBeNil)
|
||||
err = scanner.UpdateDB()
|
||||
err = scanner.UpdateDB(ctx)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
// Check the download works correctly when permissions allow
|
||||
err = os.Chmod(firstRootDir, 0o777)
|
||||
So(err, ShouldBeNil)
|
||||
err = scanner.UpdateDB()
|
||||
err = scanner.UpdateDB(ctx)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Download the DB to a substore location without permissions
|
||||
err = os.Chmod(secondRootDir, 0o000)
|
||||
So(err, ShouldBeNil)
|
||||
err = scanner.UpdateDB()
|
||||
err = scanner.UpdateDB(ctx)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
err = os.Chmod(secondRootDir, 0o777)
|
||||
@@ -210,12 +220,14 @@ func TestTrivyLibraryErrors(t *testing.T) {
|
||||
// Download DB fails for missing DB url
|
||||
scanner := NewScanner(storeController, metaDB, "", "", log)
|
||||
|
||||
err = scanner.UpdateDB()
|
||||
ctx := context.Background()
|
||||
|
||||
err = scanner.UpdateDB(ctx)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
// Try to scan without the DB being downloaded
|
||||
opts := scanner.getTrivyOptions(img)
|
||||
_, err = scanner.runTrivy(opts)
|
||||
_, err = scanner.runTrivy(ctx, opts)
|
||||
So(err, ShouldNotBeNil)
|
||||
So(err, ShouldWrap, zerr.ErrCVEDBNotFound)
|
||||
|
||||
@@ -223,37 +235,38 @@ func TestTrivyLibraryErrors(t *testing.T) {
|
||||
scanner = NewScanner(storeController, metaDB, "ghcr.io/project-zot/trivy-db",
|
||||
"ghcr.io/project-zot/trivy-not-db", log)
|
||||
|
||||
err = scanner.UpdateDB()
|
||||
err = scanner.UpdateDB(ctx)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
// Download DB passes for valid Trivy DB url, and missing Trivy Java DB url
|
||||
// Download DB is necessary since DB download on scan is disabled
|
||||
scanner = NewScanner(storeController, metaDB, "ghcr.io/project-zot/trivy-db", "", log)
|
||||
|
||||
err = scanner.UpdateDB()
|
||||
// UpdateDB with good ctx
|
||||
err = scanner.UpdateDB(ctx)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Scanning image with correct options
|
||||
opts = scanner.getTrivyOptions(img)
|
||||
_, err = scanner.runTrivy(opts)
|
||||
_, err = scanner.runTrivy(ctx, opts)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Scanning image with incorrect cache options
|
||||
// to trigger runner initialization errors
|
||||
opts.CacheOptions.CacheBackend = "redis://asdf!$%&!*)("
|
||||
_, err = scanner.runTrivy(opts)
|
||||
_, err = scanner.runTrivy(ctx, opts)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
// Scanning image with invalid input to trigger a scanner error
|
||||
opts = scanner.getTrivyOptions("nilnonexisting_image:0.0.1")
|
||||
_, err = scanner.runTrivy(opts)
|
||||
_, err = scanner.runTrivy(ctx, opts)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
// Scanning image with incorrect report options
|
||||
// to trigger report filtering errors
|
||||
opts = scanner.getTrivyOptions(img)
|
||||
opts.ReportOptions.IgnorePolicy = "invalid file path"
|
||||
_, err = scanner.runTrivy(opts)
|
||||
_, err = scanner.runTrivy(ctx, opts)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
@@ -397,22 +410,31 @@ func TestDefaultTrivyDBUrl(t *testing.T) {
|
||||
scanner := NewScanner(storeController, metaDB, "ghcr.io/aquasecurity/trivy-db",
|
||||
"ghcr.io/aquasecurity/trivy-java-db", log)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
cancelCtx, cancel := context.WithCancel(ctx)
|
||||
cancel()
|
||||
|
||||
// Download DB with context done should return ctx error.
|
||||
err = scanner.UpdateDB(cancelCtx)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
// Download DB since DB download on scan is disabled
|
||||
err = scanner.UpdateDB()
|
||||
err = scanner.UpdateDB(ctx)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Scanning image
|
||||
img := "zot-test:0.0.1" //nolint:goconst
|
||||
|
||||
opts := scanner.getTrivyOptions(img)
|
||||
_, err = scanner.runTrivy(opts)
|
||||
_, err = scanner.runTrivy(ctx, opts)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Scanning image containing a jar file
|
||||
img = "zot-cve-java-test:0.0.1"
|
||||
|
||||
opts = scanner.getTrivyOptions(img)
|
||||
_, err = scanner.runTrivy(opts)
|
||||
_, err = scanner.runTrivy(ctx, opts)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
package trivy_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
@@ -61,10 +62,10 @@ func TestScanBigTestFile(t *testing.T) {
|
||||
// scan
|
||||
scanner := trivy.NewScanner(ctlr.StoreController, ctlr.MetaDB, "ghcr.io/project-zot/trivy-db", "", ctlr.Log)
|
||||
|
||||
err = scanner.UpdateDB()
|
||||
err = scanner.UpdateDB(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
cveMap, err := scanner.ScanImage("zot-test:0.0.1")
|
||||
cveMap, err := scanner.ScanImage(context.Background(), "zot-test:0.0.1")
|
||||
So(err, ShouldBeNil)
|
||||
So(cveMap, ShouldNotBeNil)
|
||||
})
|
||||
@@ -105,26 +106,28 @@ func TestScanningByDigest(t *testing.T) {
|
||||
// scan
|
||||
scanner := trivy.NewScanner(ctlr.StoreController, ctlr.MetaDB, "ghcr.io/project-zot/trivy-db", "", ctlr.Log)
|
||||
|
||||
err = scanner.UpdateDB()
|
||||
ctx := context.Background()
|
||||
|
||||
err = scanner.UpdateDB(ctx)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
cveMap, err := scanner.ScanImage("multi-arch@" + vulnImage.DigestStr())
|
||||
cveMap, err := scanner.ScanImage(ctx, "multi-arch@"+vulnImage.DigestStr())
|
||||
So(err, ShouldBeNil)
|
||||
So(cveMap, ShouldContainKey, Vulnerability1ID)
|
||||
So(cveMap, ShouldContainKey, Vulnerability2ID)
|
||||
So(cveMap, ShouldContainKey, Vulnerability3ID)
|
||||
|
||||
cveMap, err = scanner.ScanImage("multi-arch@" + simpleImage.DigestStr())
|
||||
cveMap, err = scanner.ScanImage(ctx, "multi-arch@"+simpleImage.DigestStr())
|
||||
So(err, ShouldBeNil)
|
||||
So(cveMap, ShouldBeEmpty)
|
||||
|
||||
cveMap, err = scanner.ScanImage("multi-arch@" + multiArch.DigestStr())
|
||||
cveMap, err = scanner.ScanImage(ctx, "multi-arch@"+multiArch.DigestStr())
|
||||
So(err, ShouldBeNil)
|
||||
So(cveMap, ShouldContainKey, Vulnerability1ID)
|
||||
So(cveMap, ShouldContainKey, Vulnerability2ID)
|
||||
So(cveMap, ShouldContainKey, Vulnerability3ID)
|
||||
|
||||
cveMap, err = scanner.ScanImage("multi-arch:multi-arch-tag")
|
||||
cveMap, err = scanner.ScanImage(ctx, "multi-arch:multi-arch-tag")
|
||||
So(err, ShouldBeNil)
|
||||
So(cveMap, ShouldContainKey, Vulnerability1ID)
|
||||
So(cveMap, ShouldContainKey, Vulnerability2ID)
|
||||
@@ -188,10 +191,10 @@ func TestVulnerableLayer(t *testing.T) {
|
||||
|
||||
scanner := trivy.NewScanner(storeController, metaDB, "ghcr.io/project-zot/trivy-db", "", log)
|
||||
|
||||
err = scanner.UpdateDB()
|
||||
err = scanner.UpdateDB(context.Background())
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
cveMap, err := scanner.ScanImage("repo@" + img.DigestStr())
|
||||
cveMap, err := scanner.ScanImage(context.Background(), "repo@"+img.DigestStr())
|
||||
So(err, ShouldBeNil)
|
||||
t.Logf("cveMap: %v", cveMap)
|
||||
// As of September 17 2023 there are 5 CVEs:
|
||||
@@ -271,7 +274,7 @@ func TestScannerErrors(t *testing.T) {
|
||||
|
||||
scanner := trivy.NewScanner(storeController, metaDB, "ghcr.io/project-zot/trivy-db", "", log)
|
||||
|
||||
_, err := scanner.ScanImage("image@" + godigest.FromString("digest").String())
|
||||
_, err := scanner.ScanImage(context.Background(), "image@"+godigest.FromString("digest").String())
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -94,7 +94,7 @@ func newDBUpdadeTask(interval time.Duration, scanner Scanner,
|
||||
func (dbt *dbUpdateTask) DoWork(ctx context.Context) error {
|
||||
dbt.log.Info().Msg("updating the CVE database")
|
||||
|
||||
err := dbt.scanner.UpdateDB()
|
||||
err := dbt.scanner.UpdateDB(ctx)
|
||||
if err != nil {
|
||||
dbt.generator.lock.Lock()
|
||||
dbt.generator.status = pending
|
||||
|
||||
@@ -211,7 +211,7 @@ func getCVEListForImage(
|
||||
return &gql_generated.CVEResultForImage{}, gqlerror.Errorf("no reference provided")
|
||||
}
|
||||
|
||||
cveList, pageInfo, err := cveInfo.GetCVEListForImage(repo, ref, searchedCVE, pageInput)
|
||||
cveList, pageInfo, err := cveInfo.GetCVEListForImage(ctx, repo, ref, searchedCVE, pageInput)
|
||||
if err != nil {
|
||||
return &gql_generated.CVEResultForImage{}, err
|
||||
}
|
||||
@@ -334,7 +334,7 @@ func getImageListForCVE(
|
||||
|
||||
log.Info().Str("repository", repo).Str("CVE", cveID).Msg("extracting list of tags affected by CVE")
|
||||
|
||||
tagsInfo, err := cveInfo.GetImageListForCVE(repo, cveID)
|
||||
tagsInfo, err := cveInfo.GetImageListForCVE(ctx, repo, cveID)
|
||||
if err != nil {
|
||||
log.Error().Str("repository", repo).Str("CVE", cveID).Err(err).
|
||||
Msg("error getting image list for CVE from repo")
|
||||
@@ -407,7 +407,7 @@ func getImageListWithCVEFixed(
|
||||
|
||||
log.Info().Str("repository", repo).Str("CVE", cveID).Msg("extracting list of tags where CVE is fixed")
|
||||
|
||||
tagsInfo, err := cveInfo.GetImageListWithCVEFixed(repo, cveID)
|
||||
tagsInfo, err := cveInfo.GetImageListWithCVEFixed(ctx, repo, cveID)
|
||||
if err != nil {
|
||||
log.Error().Str("repository", repo).Str("CVE", cveID).Err(err).
|
||||
Msg("error getting image list with CVE fixed from repo")
|
||||
|
||||
@@ -1046,14 +1046,14 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
// MetaDB loaded with initial data, now mock the scanner
|
||||
// Setup test CVE data in mock scanner
|
||||
scanner := mocks.CveScannerMock{
|
||||
ScanImageFn: func(image string) (map[string]cvemodel.CVE, error) {
|
||||
ScanImageFn: func(ctx context.Context, image string) (map[string]cvemodel.CVE, error) {
|
||||
repo, ref, _, _ := common.GetRepoReference(image)
|
||||
|
||||
if common.IsDigest(ref) {
|
||||
return getCveResults(ref), nil
|
||||
}
|
||||
|
||||
repoMeta, _ := metaDB.GetRepoMeta(context.Background(), repo)
|
||||
repoMeta, _ := metaDB.GetRepoMeta(ctx, repo)
|
||||
|
||||
if _, ok := repoMeta.Tags[ref]; !ok {
|
||||
panic("unexpected tag '" + ref + "', test might be wrong")
|
||||
@@ -1239,6 +1239,32 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
Convey("context done", func() {
|
||||
pageInput := getPageInput(1, 0)
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
cancel()
|
||||
|
||||
responseContext := graphql.WithResponseContext(ctx, graphql.DefaultErrorPresenter,
|
||||
graphql.DefaultRecover)
|
||||
|
||||
canceledScanner := scanner
|
||||
|
||||
canceledScanner.ScanImageFn = func(ctx context.Context, image string) (map[string]cvemodel.CVE, error) {
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
|
||||
cveInfo.Scanner = canceledScanner
|
||||
|
||||
defer func() {
|
||||
cveInfo.Scanner = scanner
|
||||
}()
|
||||
|
||||
_, err = getImageListForCVE(responseContext, "repo1:1.1.0", cveInfo, &gql_generated.Filter{},
|
||||
pageInput, metaDB, log)
|
||||
So(err, ShouldEqual, ctx.Err())
|
||||
})
|
||||
|
||||
Convey("Paginated requests", func() {
|
||||
responseContext := graphql.WithResponseContext(ctx, graphql.DefaultErrorPresenter,
|
||||
graphql.DefaultRecover,
|
||||
@@ -1506,6 +1532,17 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
Convey("context done", func() {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
cancel()
|
||||
|
||||
responseContext := graphql.WithResponseContext(ctx, graphql.DefaultErrorPresenter,
|
||||
graphql.DefaultRecover)
|
||||
|
||||
_, err := getImageListWithCVEFixed(responseContext, "CVE1", "repo1", cveInfo, nil, nil, metaDB, log)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
Convey("Paginated requests", func() {
|
||||
responseContext := graphql.WithResponseContext(ctx, graphql.DefaultErrorPresenter,
|
||||
graphql.DefaultRecover,
|
||||
@@ -1685,7 +1722,7 @@ func TestCVEResolvers(t *testing.T) { //nolint:gocyclo
|
||||
ctx,
|
||||
"id",
|
||||
mocks.CveInfoMock{
|
||||
GetImageListForCVEFn: func(repo, cveID string) ([]cvemodel.TagInfo, error) {
|
||||
GetImageListForCVEFn: func(ctx context.Context, repo, cveID string) ([]cvemodel.TagInfo, error) {
|
||||
return []cvemodel.TagInfo{}, ErrTestError
|
||||
},
|
||||
},
|
||||
|
||||
@@ -292,7 +292,7 @@ func getMockCveScanner(metaDB mTypes.MetaDB) cveinfo.Scanner {
|
||||
}
|
||||
|
||||
scanner := mocks.CveScannerMock{
|
||||
ScanImageFn: func(image string) (map[string]cvemodel.CVE, error) {
|
||||
ScanImageFn: func(ctx context.Context, image string) (map[string]cvemodel.CVE, error) {
|
||||
return getCveResults(image), nil
|
||||
},
|
||||
GetCachedResultFn: func(digestStr string) map[string]cvemodel.CVE {
|
||||
|
||||
@@ -292,10 +292,8 @@ func (service *BaseService) SyncRepo(ctx context.Context, repo string) error {
|
||||
localRepo := service.contentManager.GetRepoDestination(repo)
|
||||
|
||||
for _, tag := range tags {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
if common.IsContextDone(ctx) {
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if references.IsCosignTag(tag) || common.IsReferrersTag(tag) {
|
||||
|
||||
@@ -1883,9 +1883,6 @@ func TestConfigReloader(t *testing.T) {
|
||||
destConfig.Log.Output = logFile.Name()
|
||||
|
||||
dctlr := api.NewController(destConfig)
|
||||
dcm := test.NewControllerManager(dctlr)
|
||||
|
||||
defer dcm.StopServer()
|
||||
|
||||
//nolint: dupl
|
||||
Convey("Reload config without sync", func() {
|
||||
@@ -1927,6 +1924,8 @@ func TestConfigReloader(t *testing.T) {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
defer dctlr.Shutdown()
|
||||
|
||||
// let it sync
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
@@ -2075,6 +2074,8 @@ func TestConfigReloader(t *testing.T) {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
defer dctlr.Shutdown()
|
||||
|
||||
// let it sync
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user