@@ -76,7 +76,12 @@ func FilterByDigest(digest string) mTypes.FilterFunc {
7676 // imageMeta will always contain 1 manifest
7777 return func (repoMeta mTypes.RepoMeta , imageMeta mTypes.ImageMeta ) bool {
7878 lookupDigest := digest
79- contains := false
79+
80+ // Check in case of an index if the index digest matches the search digest
81+ // For Manifests, this is equivalent to imageMeta.Manifests[0]
82+ if imageMeta .Digest .String () == lookupDigest {
83+ return true
84+ }
8085
8186 manifest := imageMeta .Manifests [0 ]
8287
@@ -85,24 +90,24 @@ func FilterByDigest(digest string) mTypes.FilterFunc {
8590 // Check the image manifest in index.json matches the search digest
8691 // This is a blob with mediaType application/vnd.oci.image.manifest.v1+json
8792 if strings .Contains (manifestDigest , lookupDigest ) {
88- contains = true
93+ return true
8994 }
9095
9196 // Check the image config matches the search digest
9297 // This is a blob with mediaType application/vnd.oci.image.config.v1+json
9398 if strings .Contains (manifest .Manifest .Config .Digest .String (), lookupDigest ) {
94- contains = true
99+ return true
95100 }
96101
97102 // Check to see if the individual layers in the oci image manifest match the digest
98103 // These are blobs with mediaType application/vnd.oci.image.layer.v1.tar+gzip
99104 for _ , layer := range manifest .Manifest .Layers {
100105 if strings .Contains (layer .Digest .String (), lookupDigest ) {
101- contains = true
106+ return true
102107 }
103108 }
104109
105- return contains
110+ return false
106111 }
107112}
108113
@@ -628,18 +633,10 @@ func globalSearch(ctx context.Context, query string, metaDB mTypes.MetaDB, filte
628633 }
629634 }
630635
631- if searchingForRepos (query ) {
632- skip := convert.SkipQGLField {
633- Vulnerabilities : canSkipField (preloads , "Repos.NewestImage.Vulnerabilities" ),
634- }
635-
636- pageInput := pagination.PageInput {
637- Limit : deref (requestedPage .Limit , 0 ),
638- Offset : deref (requestedPage .Offset , 0 ),
639- SortBy : pagination .SortCriteria (
640- deref (requestedPage .SortBy , gql_generated .SortCriteriaRelevance ),
641- ),
642- }
636+ switch getSearchTarget (query ) {
637+ case RepoTarget :
638+ skip := convert.SkipQGLField {Vulnerabilities : canSkipField (preloads , "Repos.NewestImage.Vulnerabilities" )}
639+ pageInput := getPageInput (requestedPage )
643640
644641 repoMetaList , err := metaDB .SearchRepos (ctx , query )
645642 if err != nil {
@@ -667,20 +664,34 @@ func globalSearch(ctx context.Context, query string, metaDB mTypes.MetaDB, filte
667664 }
668665
669666 paginatedRepos .Results = repos
670- } else { // search for images
671- skip := convert.SkipQGLField {
672- Vulnerabilities : canSkipField (preloads , "Images.Vulnerabilities" ),
667+ case ImageTarget :
668+ skip := convert.SkipQGLField {Vulnerabilities : canSkipField (preloads , "Images.Vulnerabilities" )}
669+ pageInput := getPageInput (requestedPage )
670+
671+ fullImageMetaList , err := metaDB .SearchTags (ctx , query )
672+ if err != nil {
673+ return & gql_generated.PaginatedReposResult {}, []* gql_generated.ImageSummary {}, []* gql_generated.LayerSummary {}, err
673674 }
674675
675- pageInput := pagination.PageInput {
676- Limit : deref (requestedPage .Limit , 0 ),
677- Offset : deref (requestedPage .Offset , 0 ),
678- SortBy : pagination .SortCriteria (
679- deref (requestedPage .SortBy , gql_generated .SortCriteriaRelevance ),
680- ),
676+ imageSummaries , pageInfo , err := convert .PaginatedFullImageMeta2ImageSummaries (ctx , fullImageMetaList , skip , cveInfo ,
677+ localFilter , pageInput )
678+ if err != nil {
679+ return & gql_generated.PaginatedReposResult {}, []* gql_generated.ImageSummary {}, []* gql_generated.LayerSummary {}, err
681680 }
682681
683- fullImageMetaList , err := metaDB .SearchTags (ctx , query )
682+ images = imageSummaries
683+
684+ paginatedRepos .Page = & gql_generated.PageInfo {
685+ TotalCount : pageInfo .TotalCount ,
686+ ItemCount : pageInfo .ItemCount ,
687+ }
688+ case DigestTarget :
689+ skip := convert.SkipQGLField {Vulnerabilities : canSkipField (preloads , "Images.Vulnerabilities" )}
690+ pageInput := getPageInput (requestedPage )
691+
692+ searchedDigest := query
693+
694+ fullImageMetaList , err := metaDB .FilterTags (ctx , mTypes .AcceptAllRepoTag , FilterByDigest (searchedDigest ))
684695 if err != nil {
685696 return & gql_generated.PaginatedReposResult {}, []* gql_generated.ImageSummary {}, []* gql_generated.LayerSummary {}, err
686697 }
@@ -697,11 +708,48 @@ func globalSearch(ctx context.Context, query string, metaDB mTypes.MetaDB, filte
697708 TotalCount : pageInfo .TotalCount ,
698709 ItemCount : pageInfo .ItemCount ,
699710 }
711+ default :
712+ return & paginatedRepos , images , layers , zerr .ErrInvalidSearchQuery
700713 }
701714
702715 return & paginatedRepos , images , layers , nil
703716}
704717
718+ func getPageInput (requestedPage * gql_generated.PageInput ) pagination.PageInput {
719+ return pagination.PageInput {
720+ Limit : deref (requestedPage .Limit , 0 ),
721+ Offset : deref (requestedPage .Offset , 0 ),
722+ SortBy : pagination .SortCriteria (
723+ deref (requestedPage .SortBy , gql_generated .SortCriteriaRelevance ),
724+ ),
725+ }
726+ }
727+
728+ type SearchTarget int
729+
730+ const (
731+ RepoTarget = iota
732+ ImageTarget
733+ DigestTarget
734+ InvalidTarget
735+ )
736+
737+ func getSearchTarget (query string ) SearchTarget {
738+ if ! strings .ContainsAny (query , ":@" ) {
739+ return RepoTarget
740+ }
741+
742+ if strings .HasPrefix (query , string (godigest .SHA256 )+ ":" ) {
743+ return DigestTarget
744+ }
745+
746+ if before , _ , found := strings .Cut (query , ":" ); found && before != "" {
747+ return ImageTarget
748+ }
749+
750+ return InvalidTarget
751+ }
752+
705753func canSkipField (preloads map [string ]bool , s string ) bool {
706754 fieldIsPresent := preloads [s ]
707755
@@ -1100,10 +1148,6 @@ func deref[T any](pointer *T, defaultVal T) T {
11001148 return defaultVal
11011149}
11021150
1103- func searchingForRepos (query string ) bool {
1104- return ! strings .Contains (query , ":" )
1105- }
1106-
11071151func getImageList (ctx context.Context , repo string , metaDB mTypes.MetaDB , cveInfo cveinfo.CveInfo ,
11081152 requestedPage * gql_generated.PageInput , log log.Logger , //nolint:unparam
11091153) (* gql_generated.PaginatedImagesResult , error ) {
0 commit comments