Add --with-details flag to show details about each tag

parent 84663485
Pipeline #39494906 passed with stage
in 47 seconds
......@@ -3,12 +3,14 @@ package cmd
import (
"context"
"fmt"
"strings"
"github.com/spf13/cobra"
"gitlab.com/zerok/container-inventory/pkg/registryclient"
)
var withDigest bool
var withDetails bool
var tagsCmd = &cobra.Command{
Use: "tags",
......@@ -17,6 +19,23 @@ var tagsCmd = &cobra.Command{
},
}
type tagDetails struct {
name string
blobsum string
digest string
aliases []string
}
func removeCurrentTag(tags []string, curr string) []string {
res := make([]string, 0, len(tags)-1)
for _, t := range tags {
if t != curr {
res = append(res, t)
}
}
return res
}
var listTagsCmd = &cobra.Command{
Use: "list",
Aliases: []string{"ls"},
......@@ -33,25 +52,63 @@ var listTagsCmd = &cobra.Command{
if err != nil {
logger.Fatal().Err(err).Msgf("Failed to retrieve tags for %s", repository)
}
mapping := make(map[string][]string)
listing := make([]tagDetails, 0, len(tags))
for _, tag := range tags {
if longNames {
tag = fmt.Sprintf("%s/%s:%s", registry, repository, tag)
}
if withDigest {
t := tagDetails{name: tag}
if withDigest || withDetails {
m, err := c.GetManifest(ctx, repository, tag)
if err != nil {
logger.Fatal().Err(err).Msgf("Failed to retrieve manifest for %s", tag)
}
fmt.Printf("%s (%s)\n", tag, m.Digest)
bs := m.BlobSum()
aliases, ok := mapping[bs]
if !ok {
aliases = make([]string, 0, 2)
}
aliases = append(aliases, tag)
mapping[bs] = aliases
t.digest = m.Digest
t.blobsum = bs
}
listing = append(listing, t)
}
for _, tag := range listing {
tagName := tag.name
if longNames {
tagName = fmt.Sprintf("%s/%s:%s", registry, repository, tag.name)
}
if withDetails || withDigest {
aliases := removeCurrentTag(mapping[tag.blobsum], tag.name)
aliasesText := strings.Builder{}
if withDetails && len(aliases) > 0 {
aliasesText.WriteString(" (aliases: ")
for idx, a := range aliases {
if idx > 0 {
aliasesText.WriteString(", ")
}
aliasesText.WriteString(a)
}
aliasesText.WriteString(")")
}
digestText := strings.Builder{}
if tag.digest != "" {
digestText.WriteString(" (digest: ")
digestText.WriteString(tag.digest)
digestText.WriteString(")")
}
fmt.Printf("%s%s%s\n", tagName, digestText.String(), aliasesText.String())
} else {
fmt.Println(tag)
fmt.Println(tagName)
}
}
},
}
func init() {
listTagsCmd.Flags().BoolVar(&withDigest, "with-digest", false, "Include the content digest")
listTagsCmd.Flags().BoolVar(&withDigest, "with-digest", false, "Include the content digest (deprecated)")
listTagsCmd.Flags().BoolVar(&withDetails, "with-details", false, "Include details about each tag")
tagsCmd.AddCommand(listTagsCmd)
rootCmd.AddCommand(tagsCmd)
}
......@@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
"net/url"
"strings"
"github.com/pkg/errors"
"gitlab.com/zerok/container-inventory/pkg/sessionfile"
......@@ -36,9 +37,25 @@ type listTagsResponse struct {
}
type Manifest struct {
Name string `json:"name"`
Tag string `json:"tag"`
Digest string
Name string `json:"name"`
Tag string `json:"tag"`
FSLayers []ManifestFSLayer `json:"fsLayers"`
Digest string
}
func (m *Manifest) BlobSum() string {
result := strings.Builder{}
for idx, l := range m.FSLayers {
if idx > 0 {
result.WriteString(" ")
}
result.WriteString(l.BlobSum)
}
return result.String()
}
type ManifestFSLayer struct {
BlobSum string `json:"blobSum"`
}
func NewClient(options ...ClientOption) *Client {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment