mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 04:17:55 +08:00
refactor(digests): standardise representation of digests to digest.Digest (#898)
- Digests were represented by different ways
- We needed a uniform way to represent the digests and enforce a format
- also replace usage of github.com/google/go-containerregistry/pkg/v1
with github.com/opencontainers/image-spec/specs-go/v1
Signed-off-by: Laurentiu Niculae <niculae.laurentiu1@gmail.com>
(cherry picked from commit 96b2f29d6d57070a913ce419149cd481c0723815)
(cherry picked from commit 3d41b583daea654c98378ce3dcb78937d71538e8)
Co-authored-by: Laurentiu Niculae <niculae.laurentiu1@gmail.com>
This commit is contained in:
+3
-7
@@ -17,7 +17,6 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -272,11 +271,8 @@ func (p *requestsPool) doJob(ctx context.Context, job *manifestJob) {
|
||||
p.outputCh <- stringResult{"", err}
|
||||
}
|
||||
|
||||
digest := header.Get("docker-content-digest")
|
||||
digest = strings.TrimPrefix(digest, "sha256:")
|
||||
|
||||
digestStr := header.Get("docker-content-digest")
|
||||
configDigest := job.manifestResp.Config.Digest
|
||||
configDigest = strings.TrimPrefix(configDigest, "sha256:")
|
||||
|
||||
var size uint64
|
||||
|
||||
@@ -289,7 +285,7 @@ func (p *requestsPool) doJob(ctx context.Context, job *manifestJob) {
|
||||
layers,
|
||||
layer{
|
||||
Size: entry.Size,
|
||||
Digest: strings.TrimPrefix(entry.Digest, "sha256:"),
|
||||
Digest: entry.Digest,
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -298,7 +294,7 @@ func (p *requestsPool) doJob(ctx context.Context, job *manifestJob) {
|
||||
image.verbose = *job.config.verbose
|
||||
image.RepoName = job.imageName
|
||||
image.Tag = job.tagName
|
||||
image.Digest = digest
|
||||
image.Digest = digestStr
|
||||
image.Size = strconv.Itoa(int(size))
|
||||
image.ConfigDigest = configDigest
|
||||
image.Layers = layers
|
||||
|
||||
@@ -183,7 +183,7 @@ func TestSearchCVECmd(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE dummyImageName tag DigestsA false 123kB")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE dummyImageName tag 6e2f80bf false 123kB")
|
||||
Convey("using shorthand", func() {
|
||||
args := []string{"cvetest", "-I", "dummyImageName", "--cve-id", "aCVEID", "--url", "someURL"}
|
||||
buff := bytes.NewBufferString("")
|
||||
@@ -197,7 +197,7 @@ func TestSearchCVECmd(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE dummyImageName tag DigestsA false 123kB")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE dummyImageName tag 6e2f80bf false 123kB")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -281,7 +281,7 @@ func TestSearchCVECmd(t *testing.T) {
|
||||
err := cveCmd.Execute()
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE anImage tag DigestsA false 123kB")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE anImage tag 6e2f80bf false 123kB")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("invalid CVE ID", func() {
|
||||
@@ -326,7 +326,7 @@ func TestSearchCVECmd(t *testing.T) {
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
So(err, ShouldBeNil)
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE fixedImage tag DigestsA false 123kB")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE fixedImage tag 6e2f80bf false 123kB")
|
||||
|
||||
Convey("invalid image name", func() {
|
||||
args := []string{"cvetest", "--cve-id", "aCVEID", "--image", "invalidImageName"}
|
||||
|
||||
+174
-136
@@ -187,7 +187,7 @@ func TestSearchImageCmd(t *testing.T) {
|
||||
err := cmd.Execute()
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE dummyImageName tag DigestsA false 123kB")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE dummyImageName tag 6e2f80bf false 123kB")
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
@@ -203,7 +203,7 @@ func TestSearchImageCmd(t *testing.T) {
|
||||
err := imageCmd.Execute()
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE dummyImageName tag DigestsA false 123kB")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE dummyImageName tag 6e2f80bf false 123kB")
|
||||
So(err, ShouldBeNil)
|
||||
Convey("using shorthand", func() {
|
||||
args := []string{"imagetest", "-n", "dummyImageName", "--url", "someUrlImage"}
|
||||
@@ -218,13 +218,13 @@ func TestSearchImageCmd(t *testing.T) {
|
||||
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE dummyImageName tag DigestsA false 123kB")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE dummyImageName tag 6e2f80bf false 123kB")
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
})
|
||||
|
||||
Convey("Test image by digest", t, func() {
|
||||
args := []string{"imagetest", "--digest", "DigestsA", "--url", "someUrlImage"}
|
||||
args := []string{"imagetest", "--digest", "6e2f80bf", "--url", "someUrlImage"}
|
||||
configPath := makeConfigFile(`{"configs":[{"_name":"imagetest","showspinner":false}]}`)
|
||||
defer os.Remove(configPath)
|
||||
imageCmd := NewImageCommand(new(mockService))
|
||||
@@ -235,7 +235,7 @@ func TestSearchImageCmd(t *testing.T) {
|
||||
err := imageCmd.Execute()
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE anImage tag DigestsA false 123kB")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE anImage tag 6e2f80bf false 123kB")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("invalid URL format", func() {
|
||||
@@ -385,42 +385,47 @@ func TestSignature(t *testing.T) {
|
||||
|
||||
//nolint:dupl
|
||||
func TestDerivedImageList(t *testing.T) {
|
||||
port := test.GetFreePort()
|
||||
url := test.GetBaseURL(port)
|
||||
conf := config.New()
|
||||
conf.HTTP.Port = port
|
||||
defaultVal := true
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: &extconf.SearchConfig{BaseConfig: extconf.BaseConfig{Enable: &defaultVal}},
|
||||
}
|
||||
ctlr := api.NewController(conf)
|
||||
ctlr.Config.Storage.RootDirectory = t.TempDir()
|
||||
|
||||
go func(controller *api.Controller) {
|
||||
// this blocks
|
||||
if err := controller.Run(context.Background()); err != nil {
|
||||
return
|
||||
}
|
||||
}(ctlr)
|
||||
|
||||
// wait till ready
|
||||
for {
|
||||
_, err := resty.R().Get(url)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
defer func(controller *api.Controller) {
|
||||
ctx := context.Background()
|
||||
_ = controller.Server.Shutdown(ctx)
|
||||
}(ctlr)
|
||||
|
||||
err := uploadManifest(url)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
t.Logf("rootDir: %s", ctlr.Config.Storage.RootDirectory)
|
||||
|
||||
Convey("Test from real server", t, func() {
|
||||
port := test.GetFreePort()
|
||||
url := test.GetBaseURL(port)
|
||||
conf := config.New()
|
||||
conf.HTTP.Port = port
|
||||
defaultVal := true
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: &extconf.SearchConfig{BaseConfig: extconf.BaseConfig{Enable: &defaultVal}},
|
||||
}
|
||||
ctlr := api.NewController(conf)
|
||||
ctlr.Config.Storage.RootDirectory = t.TempDir()
|
||||
|
||||
go func(controller *api.Controller) {
|
||||
// this blocks
|
||||
if err := controller.Run(context.Background()); err != nil {
|
||||
return
|
||||
}
|
||||
}(ctlr)
|
||||
// wait till ready
|
||||
for {
|
||||
_, err := resty.R().Get(url)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
defer func(controller *api.Controller) {
|
||||
ctx := context.Background()
|
||||
_ = controller.Server.Shutdown(ctx)
|
||||
}(ctlr)
|
||||
|
||||
err := uploadManifest(url)
|
||||
So(err, ShouldBeNil)
|
||||
t.Logf("rootDir: %s", ctlr.Config.Storage.RootDirectory)
|
||||
|
||||
Convey("Test derived images list working", func() {
|
||||
t.Logf("%s", ctlr.Config.Storage.RootDirectory)
|
||||
args := []string{"imagetest", "--derived-images", "repo7:test:1.0"}
|
||||
@@ -479,42 +484,47 @@ func TestDerivedImageList(t *testing.T) {
|
||||
|
||||
//nolint:dupl
|
||||
func TestBaseImageList(t *testing.T) {
|
||||
port := test.GetFreePort()
|
||||
url := test.GetBaseURL(port)
|
||||
conf := config.New()
|
||||
conf.HTTP.Port = port
|
||||
defaultVal := true
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: &extconf.SearchConfig{BaseConfig: extconf.BaseConfig{Enable: &defaultVal}},
|
||||
}
|
||||
ctlr := api.NewController(conf)
|
||||
ctlr.Config.Storage.RootDirectory = t.TempDir()
|
||||
|
||||
go func(controller *api.Controller) {
|
||||
// this blocks
|
||||
if err := controller.Run(context.Background()); err != nil {
|
||||
return
|
||||
}
|
||||
}(ctlr)
|
||||
|
||||
// wait till ready
|
||||
for {
|
||||
_, err := resty.R().Get(url)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
defer func(controller *api.Controller) {
|
||||
ctx := context.Background()
|
||||
_ = controller.Server.Shutdown(ctx)
|
||||
}(ctlr)
|
||||
|
||||
err := uploadManifest(url)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
t.Logf("rootDir: %s", ctlr.Config.Storage.RootDirectory)
|
||||
|
||||
Convey("Test from real server", t, func() {
|
||||
port := test.GetFreePort()
|
||||
url := test.GetBaseURL(port)
|
||||
conf := config.New()
|
||||
conf.HTTP.Port = port
|
||||
defaultVal := true
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: &extconf.SearchConfig{BaseConfig: extconf.BaseConfig{Enable: &defaultVal}},
|
||||
}
|
||||
ctlr := api.NewController(conf)
|
||||
ctlr.Config.Storage.RootDirectory = t.TempDir()
|
||||
|
||||
go func(controller *api.Controller) {
|
||||
// this blocks
|
||||
if err := controller.Run(context.Background()); err != nil {
|
||||
return
|
||||
}
|
||||
}(ctlr)
|
||||
// wait till ready
|
||||
for {
|
||||
_, err := resty.R().Get(url)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
defer func(controller *api.Controller) {
|
||||
ctx := context.Background()
|
||||
_ = controller.Server.Shutdown(ctx)
|
||||
}(ctlr)
|
||||
|
||||
err := uploadManifest(url)
|
||||
So(err, ShouldBeNil)
|
||||
t.Logf("rootDir: %s", ctlr.Config.Storage.RootDirectory)
|
||||
|
||||
Convey("Test base images list working", func() {
|
||||
t.Logf("%s", ctlr.Config.Storage.RootDirectory)
|
||||
args := []string{"imagetest", "--base-images", "repo7:test:1.0"}
|
||||
@@ -727,7 +737,7 @@ func TestOutputFormat(t *testing.T) {
|
||||
err := cmd.Execute()
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE dummyImageName tag DigestsA false 123kB")
|
||||
So(strings.TrimSpace(str), ShouldEqual, "IMAGE NAME TAG DIGEST SIGNED SIZE dummyImageName tag 6e2f80bf false 123kB")
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
@@ -746,7 +756,11 @@ func TestOutputFormat(t *testing.T) {
|
||||
space := regexp.MustCompile(`\s+`)
|
||||
str := space.ReplaceAllString(buff.String(), " ")
|
||||
So(strings.TrimSpace(str), ShouldEqual, `{ "repoName": "dummyImageName", "tag": "tag", `+
|
||||
`"configDigest": "", "digest": "DigestsAreReallyLong", "layers": null, "size": "123445", "isSigned": false }`)
|
||||
`"configDigest": "sha256:4c10985c40365538426f2ba8cf0c21384a7769be502a550dcc0601b3736625e0", `+
|
||||
`"digest": "sha256:6e2f80bf9cfaabad474fbaf8ad68fdb652f776ea80b63492ecca404e5f6446a6", `+
|
||||
`"layers": [ { "size": "0", `+
|
||||
`"digest": "sha256:c122a146f0d02349be211bb95cc2530f4a5793f96edbdfa00860f741e5d8c0e6" } ], `+
|
||||
`"size": "123445", "isSigned": false }`)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
@@ -765,9 +779,11 @@ func TestOutputFormat(t *testing.T) {
|
||||
So(
|
||||
strings.TrimSpace(str),
|
||||
ShouldEqual,
|
||||
`reponame: dummyImageName tag: tag configdigest: "" `+
|
||||
`digest: DigestsAreReallyLong layers: [] size: "123445" `+
|
||||
`issigned: false`,
|
||||
`reponame: dummyImageName tag: tag `+
|
||||
`configdigest: sha256:4c10985c40365538426f2ba8cf0c21384a7769be502a550dcc0601b3736625e0 `+
|
||||
`digest: sha256:6e2f80bf9cfaabad474fbaf8ad68fdb652f776ea80b63492ecca404e5f6446a6 `+
|
||||
`layers: - size: 0 digest: sha256:c122a146f0d02349be211bb95cc2530f4a5793f96edbdfa00860f741e5d8c0e6 `+
|
||||
`size: "123445" issigned: false`,
|
||||
)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -789,9 +805,11 @@ func TestOutputFormat(t *testing.T) {
|
||||
So(
|
||||
strings.TrimSpace(str),
|
||||
ShouldEqual,
|
||||
`reponame: dummyImageName tag: tag configdigest: "" `+
|
||||
`digest: DigestsAreReallyLong layers: [] size: "123445" `+
|
||||
`issigned: false`,
|
||||
`reponame: dummyImageName tag: tag `+
|
||||
`configdigest: sha256:4c10985c40365538426f2ba8cf0c21384a7769be502a550dcc0601b3736625e0 `+
|
||||
`digest: sha256:6e2f80bf9cfaabad474fbaf8ad68fdb652f776ea80b63492ecca404e5f6446a6 `+
|
||||
`layers: - size: 0 digest: sha256:c122a146f0d02349be211bb95cc2530f4a5793f96edbdfa00860f741e5d8c0e6 `+
|
||||
`size: "123445" issigned: false`,
|
||||
)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
@@ -1086,41 +1104,47 @@ func TestServerResponseGQL(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServerResponse(t *testing.T) {
|
||||
port := test.GetFreePort()
|
||||
url := test.GetBaseURL(port)
|
||||
conf := config.New()
|
||||
conf.HTTP.Port = port
|
||||
defaultVal := true
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: &extconf.SearchConfig{BaseConfig: extconf.BaseConfig{Enable: &defaultVal}},
|
||||
}
|
||||
ctlr := api.NewController(conf)
|
||||
ctlr.Config.Storage.RootDirectory = t.TempDir()
|
||||
|
||||
go func(controller *api.Controller) {
|
||||
// this blocks
|
||||
if err := controller.Run(context.Background()); err != nil {
|
||||
return
|
||||
}
|
||||
}(ctlr)
|
||||
|
||||
// wait till ready
|
||||
for {
|
||||
_, err := resty.R().Get(url)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
defer func(controller *api.Controller) {
|
||||
ctx := context.Background()
|
||||
_ = controller.Server.Shutdown(ctx)
|
||||
}(ctlr)
|
||||
|
||||
err := uploadManifest(url)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
t.Logf("%s", ctlr.Config.Storage.RootDirectory)
|
||||
|
||||
Convey("Test from real server", t, func() {
|
||||
port := test.GetFreePort()
|
||||
url := test.GetBaseURL(port)
|
||||
conf := config.New()
|
||||
conf.HTTP.Port = port
|
||||
defaultVal := true
|
||||
conf.Extensions = &extconf.ExtensionConfig{
|
||||
Search: &extconf.SearchConfig{BaseConfig: extconf.BaseConfig{Enable: &defaultVal}},
|
||||
}
|
||||
ctlr := api.NewController(conf)
|
||||
ctlr.Config.Storage.RootDirectory = t.TempDir()
|
||||
go func(controller *api.Controller) {
|
||||
// this blocks
|
||||
if err := controller.Run(context.Background()); err != nil {
|
||||
return
|
||||
}
|
||||
}(ctlr)
|
||||
// wait till ready
|
||||
for {
|
||||
_, err := resty.R().Get(url)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
defer func(controller *api.Controller) {
|
||||
ctx := context.Background()
|
||||
_ = controller.Server.Shutdown(ctx)
|
||||
}(ctlr)
|
||||
|
||||
err := uploadManifest(url)
|
||||
t.Logf("%s", ctlr.Config.Storage.RootDirectory)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
Convey("Test all images", func() {
|
||||
t.Logf("%s", ctlr.Config.Storage.RootDirectory)
|
||||
args := []string{"imagetest"}
|
||||
@@ -1555,10 +1579,12 @@ func (service mockService) getDerivedImageListGQL(ctx context.Context, config se
|
||||
imageListGQLResponse := &imageListStructForDerivedImagesGQL{}
|
||||
imageListGQLResponse.Data.ImageList = []imageStruct{
|
||||
{
|
||||
RepoName: "dummyImageName",
|
||||
Tag: "tag",
|
||||
Digest: "DigestsAreReallyLong",
|
||||
Size: "123445",
|
||||
RepoName: "dummyImageName",
|
||||
Tag: "tag",
|
||||
Digest: godigest.FromString("Digest").String(),
|
||||
ConfigDigest: godigest.FromString("ConfigDigest").String(),
|
||||
Size: "123445",
|
||||
Layers: []layer{{Digest: godigest.FromString("LayerDigest").String()}},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1571,10 +1597,12 @@ func (service mockService) getBaseImageListGQL(ctx context.Context, config searc
|
||||
imageListGQLResponse := &imageListStructForBaseImagesGQL{}
|
||||
imageListGQLResponse.Data.ImageList = []imageStruct{
|
||||
{
|
||||
RepoName: "dummyImageName",
|
||||
Tag: "tag",
|
||||
Digest: "DigestsAreReallyLong",
|
||||
Size: "123445",
|
||||
RepoName: "dummyImageName",
|
||||
Tag: "tag",
|
||||
Digest: godigest.FromString("Digest").String(),
|
||||
ConfigDigest: godigest.FromString("ConfigDigest").String(),
|
||||
Size: "123445",
|
||||
Layers: []layer{{Digest: godigest.FromString("LayerDigest").String()}},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1587,10 +1615,12 @@ func (service mockService) getImagesGQL(ctx context.Context, config searchConfig
|
||||
imageListGQLResponse := &imageListStructGQL{}
|
||||
imageListGQLResponse.Data.ImageList = []imageStruct{
|
||||
{
|
||||
RepoName: "dummyImageName",
|
||||
Tag: "tag",
|
||||
Digest: "DigestsAreReallyLong",
|
||||
Size: "123445",
|
||||
RepoName: "dummyImageName",
|
||||
Tag: "tag",
|
||||
Digest: godigest.FromString("Digest").String(),
|
||||
ConfigDigest: godigest.FromString("ConfigDigest").String(),
|
||||
Size: "123445",
|
||||
Layers: []layer{{Digest: godigest.FromString("LayerDigest").String()}},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1603,10 +1633,12 @@ func (service mockService) getImagesByDigestGQL(ctx context.Context, config sear
|
||||
imageListGQLResponse := &imageListStructForDigestGQL{}
|
||||
imageListGQLResponse.Data.ImageList = []imageStruct{
|
||||
{
|
||||
RepoName: "randomimageName",
|
||||
Tag: "tag",
|
||||
Digest: "DigestsAreReallyLong",
|
||||
Size: "123445",
|
||||
RepoName: "randomimageName",
|
||||
Tag: "tag",
|
||||
Digest: godigest.FromString("Digest").String(),
|
||||
ConfigDigest: godigest.FromString("ConfigDigest").String(),
|
||||
Size: "123445",
|
||||
Layers: []layer{{Digest: godigest.FromString("LayerDigest").String()}},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1700,8 +1732,10 @@ func (service mockService) getMockedImageByName(imageName string) imageStruct {
|
||||
image := imageStruct{}
|
||||
image.RepoName = imageName
|
||||
image.Tag = "tag"
|
||||
image.Digest = "DigestsAreReallyLong"
|
||||
image.Digest = godigest.FromString("Digest").String()
|
||||
image.ConfigDigest = godigest.FromString("ConfigDigest").String()
|
||||
image.Size = "123445"
|
||||
image.Layers = []layer{{Digest: godigest.FromString("LayerDigest").String()}}
|
||||
|
||||
return image
|
||||
}
|
||||
@@ -1715,8 +1749,10 @@ func (service mockService) getAllImages(ctx context.Context, config searchConfig
|
||||
image := &imageStruct{}
|
||||
image.RepoName = "randomimageName"
|
||||
image.Tag = "tag"
|
||||
image.Digest = "DigestsAreReallyLong"
|
||||
image.Digest = godigest.FromString("Digest").String()
|
||||
image.ConfigDigest = godigest.FromString("ConfigDigest").String()
|
||||
image.Size = "123445"
|
||||
image.Layers = []layer{{Digest: godigest.FromString("LayerDigest").String()}}
|
||||
|
||||
str, err := image.string(*config.outputFormat, len(image.RepoName), len(image.Tag))
|
||||
if err != nil {
|
||||
@@ -1737,8 +1773,10 @@ func (service mockService) getImageByName(ctx context.Context, config searchConf
|
||||
image := &imageStruct{}
|
||||
image.RepoName = imageName
|
||||
image.Tag = "tag"
|
||||
image.Digest = "DigestsAreReallyLong"
|
||||
image.Digest = godigest.FromString("Digest").String()
|
||||
image.ConfigDigest = godigest.FromString("ConfigDigest").String()
|
||||
image.Size = "123445"
|
||||
image.Layers = []layer{{Digest: godigest.FromString("LayerDigest").String()}}
|
||||
|
||||
str, err := image.string(*config.outputFormat, len(image.RepoName), len(image.Tag))
|
||||
if err != nil {
|
||||
|
||||
+31
-11
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/dustin/go-humanize"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/olekukonko/tablewriter"
|
||||
godigest "github.com/opencontainers/go-digest"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
zotErrors "zotregistry.io/zot/errors"
|
||||
@@ -74,6 +75,7 @@ func (service searchService) getDerivedImageListGQL(ctx context.Context, config
|
||||
Tag,
|
||||
Digest,
|
||||
ConfigDigest,
|
||||
Layers {Size Digest},
|
||||
LastUpdated,
|
||||
IsSigned,
|
||||
Size
|
||||
@@ -100,6 +102,7 @@ func (service searchService) getBaseImageListGQL(ctx context.Context, config sea
|
||||
Tag,
|
||||
Digest,
|
||||
ConfigDigest,
|
||||
Layers {Size Digest},
|
||||
LastUpdated,
|
||||
IsSigned,
|
||||
Size
|
||||
@@ -156,7 +159,7 @@ func (service searchService) getImagesByCveIDGQL(ctx context.Context, config sea
|
||||
password, cveID string,
|
||||
) (*imagesForCve, error) {
|
||||
query := fmt.Sprintf(`{ImageListForCVE(id: "%s") {`+`
|
||||
RepoName Tag Digest Size}
|
||||
RepoName Tag Digest ConfigDigest Layers {Size Digest} Size}
|
||||
}`,
|
||||
cveID)
|
||||
result := &imagesForCve{}
|
||||
@@ -193,7 +196,7 @@ func (service searchService) getTagsForCVEGQL(ctx context.Context, config search
|
||||
username, password, imageName, cveID string,
|
||||
) (*imagesForCve, error) {
|
||||
query := fmt.Sprintf(`{ImageListForCVE(id: "%s") {`+`
|
||||
RepoName Tag Digest Size}
|
||||
RepoName Tag Digest ConfigDigest Layers {Size Digest} Size}
|
||||
}`,
|
||||
cveID)
|
||||
result := &imagesForCve{}
|
||||
@@ -211,7 +214,7 @@ func (service searchService) getFixedTagsForCVEGQL(ctx context.Context, config s
|
||||
username, password, imageName, cveID string,
|
||||
) (*fixedTags, error) {
|
||||
query := fmt.Sprintf(`{ImageListWithCVEFixed(id: "%s", image: "%s") {`+`
|
||||
RepoName Tag Digest Size}
|
||||
RepoName Tag Digest ConfigDigest Layers {Size Digest} Size}
|
||||
}`,
|
||||
cveID, imageName)
|
||||
|
||||
@@ -334,7 +337,7 @@ func (service searchService) getImagesByCveID(ctx context.Context, config search
|
||||
defer close(rch)
|
||||
|
||||
query := fmt.Sprintf(`{ImageListForCVE(id: "%s") {`+`
|
||||
RepoName Tag Digest Size}
|
||||
RepoName Tag Digest ConfigDigest Layers {Size Digest} Size}
|
||||
}`,
|
||||
cvid)
|
||||
result := &imagesForCve{}
|
||||
@@ -551,7 +554,7 @@ func (service searchService) getFixedTagsForCVE(ctx context.Context, config sear
|
||||
defer close(rch)
|
||||
|
||||
query := fmt.Sprintf(`{ImageListWithCVEFixed (id: "%s", image: "%s") {`+`
|
||||
RepoName Tag Digest Size}
|
||||
RepoName Tag Digest ConfigDigest Layers {Size Digest} Size}
|
||||
}`,
|
||||
cvid, imageName)
|
||||
result := &fixedTags{}
|
||||
@@ -924,21 +927,32 @@ func (img imageStruct) stringPlainText(maxImgNameLen, maxTagLen int) (string, er
|
||||
|
||||
imageName = img.RepoName
|
||||
tagName = img.Tag
|
||||
digest := ellipsize(img.Digest, digestWidth, "")
|
||||
|
||||
manifestDigest, err := godigest.Parse(img.Digest)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error parsing manifest digest %s: %w", img.Digest, err)
|
||||
}
|
||||
|
||||
configDigest, err := godigest.Parse(img.ConfigDigest)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error parsing config digest %s: %w", img.ConfigDigest, err)
|
||||
}
|
||||
|
||||
minifestDigestStr := ellipsize(manifestDigest.Encoded(), digestWidth, "")
|
||||
configDigestStr := ellipsize(configDigest.Encoded(), configWidth, "")
|
||||
imgSize, _ := strconv.ParseUint(img.Size, 10, 64)
|
||||
size := ellipsize(strings.ReplaceAll(humanize.Bytes(imgSize), " ", ""), sizeWidth, ellipsis)
|
||||
config := ellipsize(img.ConfigDigest, configWidth, "")
|
||||
isSigned := img.IsSigned
|
||||
row := make([]string, 7) //nolint:gomnd
|
||||
|
||||
row[colImageNameIndex] = imageName
|
||||
row[colTagIndex] = tagName
|
||||
row[colDigestIndex] = digest
|
||||
row[colDigestIndex] = minifestDigestStr
|
||||
row[colSizeIndex] = size
|
||||
row[colIsSignedIndex] = strconv.FormatBool(isSigned)
|
||||
|
||||
if img.verbose {
|
||||
row[colConfigIndex] = config
|
||||
row[colConfigIndex] = configDigestStr
|
||||
row[colLayersIndex] = ""
|
||||
}
|
||||
|
||||
@@ -948,7 +962,13 @@ func (img imageStruct) stringPlainText(maxImgNameLen, maxTagLen int) (string, er
|
||||
for _, entry := range img.Layers {
|
||||
layerSize := entry.Size
|
||||
size := ellipsize(strings.ReplaceAll(humanize.Bytes(layerSize), " ", ""), sizeWidth, ellipsis)
|
||||
layerDigest := ellipsize(entry.Digest, digestWidth, "")
|
||||
|
||||
layerDigest, err := godigest.Parse(entry.Digest)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error parsing layer digest %s: %w", entry.Digest, err)
|
||||
}
|
||||
|
||||
layerDigestStr := ellipsize(layerDigest.Encoded(), digestWidth, "")
|
||||
|
||||
layerRow := make([]string, 7) //nolint:gomnd
|
||||
layerRow[colImageNameIndex] = ""
|
||||
@@ -956,7 +976,7 @@ func (img imageStruct) stringPlainText(maxImgNameLen, maxTagLen int) (string, er
|
||||
layerRow[colDigestIndex] = ""
|
||||
layerRow[colSizeIndex] = size
|
||||
layerRow[colConfigIndex] = ""
|
||||
layerRow[colLayersIndex] = layerDigest
|
||||
layerRow[colLayersIndex] = layerDigestStr
|
||||
|
||||
table.Append(layerRow)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user