mirror of
https://github.com/project-zot/zot.git
synced 2024-12-16 21:56:37 -05:00
fix: Sort tags returned by ExpendedRepoInfo in the Images property with the newest first (#1137)
Signed-off-by: Nicol Draghici <idraghic@cisco.com> (cherry picked from commit e99ea64bd1b9699bcd6d72183c722d636772bbb1) Signed-off-by: Andrei Aaron <aaaron@luxoft.com> Signed-off-by: Nicol Draghici <idraghic@cisco.com>
This commit is contained in:
parent
58ec62b3e4
commit
799f747429
2 changed files with 137 additions and 1 deletions
|
@ -297,6 +297,58 @@ func verifyImageSummaryFields(t *testing.T,
|
|||
}
|
||||
}
|
||||
|
||||
func uploadNewRepoTag(tag string, repoName string, baseURL string, layers [][]byte) error {
|
||||
created := time.Now()
|
||||
config := ispec.Image{
|
||||
Created: &created,
|
||||
Platform: ispec.Platform{
|
||||
Architecture: "amd64",
|
||||
OS: "linux",
|
||||
},
|
||||
RootFS: ispec.RootFS{
|
||||
Type: "layers",
|
||||
DiffIDs: []godigest.Digest{},
|
||||
},
|
||||
Author: "ZotUser",
|
||||
}
|
||||
|
||||
configBlob, err := json.Marshal(config)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
configDigest := godigest.FromBytes(configBlob)
|
||||
|
||||
manifest := ispec.Manifest{
|
||||
Versioned: specs.Versioned{
|
||||
SchemaVersion: 2,
|
||||
},
|
||||
Config: ispec.Descriptor{
|
||||
MediaType: "application/vnd.oci.image.config.v1+json",
|
||||
Digest: configDigest,
|
||||
Size: int64(len(configBlob)),
|
||||
},
|
||||
Layers: []ispec.Descriptor{
|
||||
{
|
||||
MediaType: "application/vnd.oci.image.layer.v1.tar",
|
||||
Digest: godigest.FromBytes(layers[0]),
|
||||
Size: int64(len(layers[0])),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
err = UploadImage(
|
||||
Image{
|
||||
Manifest: manifest,
|
||||
Config: config,
|
||||
Layers: layers,
|
||||
Tag: tag,
|
||||
},
|
||||
baseURL,
|
||||
repoName,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func TestRepoListWithNewestImage(t *testing.T) {
|
||||
Convey("Test repoListWithNewestImage by tag with HTTP", t, func() {
|
||||
subpath := "/a"
|
||||
|
@ -1081,6 +1133,68 @@ func TestExpandedRepoInfo(t *testing.T) {
|
|||
err = json.Unmarshal(resp.Body(), responseStruct)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("Test image tags order", t, func() {
|
||||
port := GetFreePort()
|
||||
baseURL := GetBaseURL(port)
|
||||
conf := config.New()
|
||||
conf.HTTP.Port = port
|
||||
conf.Storage.RootDirectory = t.TempDir()
|
||||
|
||||
defaultVal := true
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: &extconf.SearchConfig{BaseConfig: extconf.BaseConfig{Enable: &defaultVal}},
|
||||
}
|
||||
|
||||
conf.Extensions.Search.CVE = nil
|
||||
|
||||
ctlr := api.NewController(conf)
|
||||
|
||||
ctlrManager := NewControllerManager(ctlr)
|
||||
ctlrManager.StartAndWait(port)
|
||||
defer ctlrManager.StopServer()
|
||||
|
||||
resp, err := resty.R().Get(baseURL + "/v2/")
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
resp, err = resty.R().Get(baseURL + graphqlQueryPrefix)
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 422)
|
||||
|
||||
// create test images
|
||||
repoName := "test-repo" //nolint:goconst
|
||||
layers := [][]byte{
|
||||
{10, 11, 10, 11},
|
||||
}
|
||||
|
||||
err = uploadNewRepoTag("1.0", repoName, baseURL, layers)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = uploadNewRepoTag("2.0", repoName, baseURL, layers)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = uploadNewRepoTag("3.0", repoName, baseURL, layers)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
responseStruct := &ExpandedRepoInfoResp{}
|
||||
query := "{ExpandedRepoInfo(repo:\"test-repo\"){Images%20{RepoName%20Digest%20Tag%20LastUpdated%20Layers%20{Size%20Digest}}}}" //nolint: lll
|
||||
resp, err = resty.R().Get(baseURL + graphqlQueryPrefix + "?query=" + query)
|
||||
So(resp, ShouldNotBeNil)
|
||||
So(err, ShouldBeNil)
|
||||
So(resp.StatusCode(), ShouldEqual, 200)
|
||||
|
||||
err = json.Unmarshal(resp.Body(), responseStruct)
|
||||
So(err, ShouldBeNil)
|
||||
So(len(responseStruct.ExpandedRepoInfo.RepoInfo.ImageSummaries), ShouldNotEqual, 0)
|
||||
So(len(responseStruct.ExpandedRepoInfo.RepoInfo.ImageSummaries[0].Layers), ShouldNotEqual, 0)
|
||||
|
||||
So(responseStruct.ExpandedRepoInfo.RepoInfo.ImageSummaries[0].Tag, ShouldEqual, "3.0")
|
||||
So(responseStruct.ExpandedRepoInfo.RepoInfo.ImageSummaries[1].Tag, ShouldEqual, "2.0")
|
||||
So(responseStruct.ExpandedRepoInfo.RepoInfo.ImageSummaries[2].Tag, ShouldEqual, "1.0")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUtilsMethod(t *testing.T) {
|
||||
|
|
|
@ -7,6 +7,7 @@ package search
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
|
@ -706,7 +707,28 @@ func expandedRepoInfo(ctx context.Context, repo string, repoDB repodb.RepoDB, cv
|
|||
|
||||
repoSummary, imageSummaries := convert.RepoMeta2ExpandedRepoInfo(ctx, repoMeta, manifestMetaMap, skip, cveInfo)
|
||||
|
||||
return &gql_generated.RepoInfo{Summary: repoSummary, Images: imageSummaries}, nil
|
||||
dateSortedImages := make(timeSlice, 0, len(imageSummaries))
|
||||
for _, imgSummary := range imageSummaries {
|
||||
dateSortedImages = append(dateSortedImages, imgSummary)
|
||||
}
|
||||
|
||||
sort.Sort(dateSortedImages)
|
||||
|
||||
return &gql_generated.RepoInfo{Summary: repoSummary, Images: dateSortedImages}, nil
|
||||
}
|
||||
|
||||
type timeSlice []*gql_generated.ImageSummary
|
||||
|
||||
func (p timeSlice) Len() int {
|
||||
return len(p)
|
||||
}
|
||||
|
||||
func (p timeSlice) Less(i, j int) bool {
|
||||
return p[i].LastUpdated.After(*p[j].LastUpdated)
|
||||
}
|
||||
|
||||
func (p timeSlice) Swap(i, j int) {
|
||||
p[i], p[j] = p[j], p[i]
|
||||
}
|
||||
|
||||
func safeDerefferencing[T any](pointer *T, defaultVal T) T {
|
||||
|
|
Loading…
Reference in a new issue