diff --git a/main.go b/main.go index 75a1085..ea5ab5a 100644 --- a/main.go +++ b/main.go @@ -210,9 +210,15 @@ func (a *apiClient) viewTagInfo(c echo.Context) error { } sha256, infoV1, infoV2 := a.client.TagInfo(repoPath, tag, false) - if infoV1 == "" || infoV2 == "" { + manifests := a.client.Manifests(repoPath, tag) + if (infoV1 == "" || infoV2 == "") && len(manifests) == 0 { return c.Redirect(http.StatusSeeOther, fmt.Sprintf("%s/%s/%s", a.config.BasePath, namespace, repo)) } + isListOnly := (infoV1 == "" && infoV2 == "") + newRepoPath := gjson.Get(infoV1, "name").String() + if newRepoPath != "" { + repoPath = newRepoPath + } var imageSize int64 if gjson.Get(infoV2, "layers").Exists() { @@ -244,18 +250,20 @@ func (a *apiClient) viewTagInfo(c echo.Context) error { } isDigest := strings.HasPrefix(tag, "sha256:") - var digests []map[string]gjson.Result - var digestSizes []int64 - for _, s := range a.client.Manifests(repoPath, tag) { - var r map[string]gjson.Result = s.Map() - r["architecture"] = s.Get("platform.architecture") - r["os"] = s.Get("platform.os") - _, _, dInfo := a.client.TagInfo(repoPath, s.Get("digest").String(), false) - var dSize int64 - for _, d := range gjson.Get(dInfo, "layers.#.size").Array() { - dSize = dSize + d.Int() + var digests []map[string]interface{} + for _, s := range manifests { + r, _ := gjson.Parse(s.String()).Value().(map[string]interface{}) + if s.Get("mediaType").String() == "application/vnd.docker.distribution.manifest.v2+json" { + _, _, dInfo := a.client.TagInfo(repoPath, s.Get("digest").String(), false) + var dSize int64 + for _, d := range gjson.Get(dInfo, "layers.#.size").Array() { + dSize = dSize + d.Int() + } + r["size"] = dSize + } else { + r["size"] = s.Get("size").Int() } - digestSizes = append(digestSizes, dSize) + r["ordered_keys"] = registry.SortedMapKeys(r) digests = append(digests, r) } @@ -265,14 +273,14 @@ func (a *apiClient) viewTagInfo(c echo.Context) error { data.Set("sha256", sha256) data.Set("imageSize", imageSize) data.Set("tag", tag) - data.Set("repoPath", gjson.Get(infoV1, "name").String()) + data.Set("repoPath", repoPath) data.Set("created", gjson.Get(gjson.Get(infoV1, "history.0.v1Compatibility").String(), "created").String()) data.Set("layersCount", layersCount) data.Set("layersV2", layersV2) data.Set("layersV1", layersV1) data.Set("isDigest", isDigest) + data.Set("isListOnly", isListOnly) data.Set("digests", digests) - data.Set("digestSizes", digestSizes) return c.Render(http.StatusOK, "tag_info.html", data) } diff --git a/templates/tag_info.html b/templates/tag_info.html index ad8efc4..716f427 100644 --- a/templates/tag_info.html +++ b/templates/tag_info.html @@ -17,11 +17,10 @@ Image Details - {{if not isDigest}} Image{{ registryHost }}/{{ repoPath }}:{{ tag }} - {{end}} + {{if not isListOnly}} sha256{{ sha256 }} @@ -36,32 +35,44 @@ Layer Count{{ layersCount }} + {{end}} -{{if len(digests) != 0}} +{{if digests}}

Manifest List v2

+{{range index, manifest := digests}} - - - - - + -{{range index, manifest := digests}} + {{range key := manifest["ordered_keys"]}} - + + {{if key == "platform" || key == "annotations"}} + + {{else if key == "size"}} + + {{else if key == "digest"}} + {{if not isListOnly}} - - - + {{else}} + + {{end}} + {{else}} + + {{end}} -{{end}} + {{end}}
Manifest #DigestSizeArchitectureOSManifest #{{ index+1 }}
{{ index+1 }}{{ key }} + + + {{ manifest[key]|parse_map|raw }} +
+
{{ manifest[key]|pretty_size }}{{ manifest["digest"] }}{{ digestSizes[index]|pretty_size }}{{ manifest["architecture"] }}{{ manifest["os"] }}{{ manifest["digest"] }}{{ manifest[key] }}
-{{else}} -{{if layersV2}} +{{end}} +{{else if layersV2}}

Manifest v2

@@ -80,9 +91,8 @@ {{end}}
{{end}} -{{end}} -{{if not isDigest}} +{{if not isListOnly && not isDigest}}

Manifest v1

{{range index, layer := layersV1}}