@@ -4,9 +4,11 @@ import (
44 "context"
55 "fmt"
66
7+ "github.com/alibaba/pouch/apis/types"
78 "github.com/alibaba/pouch/pkg/reference"
89 "github.com/alibaba/pouch/pkg/utils"
910
11+ digest "github.com/opencontainers/go-digest"
1012 "github.com/spf13/cobra"
1113)
1214
@@ -21,6 +23,13 @@ func (i imageSize) String() string {
2123 return utils .FormatSize (int64 (i ))
2224}
2325
26+ type displayImage struct {
27+ id string
28+ name string
29+ size imageSize
30+ digest string
31+ }
32+
2433// ImagesCommand use to implement 'images' command.
2534type ImagesCommand struct {
2635 baseCommand
@@ -73,56 +82,100 @@ func (i *ImagesCommand) runImages(args []string) error {
7382 }
7483
7584 display := i .cli .NewTableDisplay ()
76-
7785 if i .flagDigest {
7886 display .AddRow ([]string {"IMAGE ID" , "IMAGE NAME" , "DIGEST" , "SIZE" })
7987 } else {
8088 display .AddRow ([]string {"IMAGE ID" , "IMAGE NAME" , "SIZE" })
8189 }
8290
83- for _ , image := range imageList {
84- var name reference.Named
85- var digest string
86- if len (image .RepoTags ) > 0 {
87- name , err = reference .ParseNamedReference (image .RepoTags [0 ])
88- if err != nil {
89- return err
90- }
91- digestName , err := reference .ParseNamedReference (image .RepoDigests [0 ])
92- if err != nil {
93- return err
94- }
95- if digestd , ok := digestName .(reference.Digested ); ok {
96- digest = digestd .Digest ()
97- }
91+ dimgs := make ([]displayImage , 0 , len (imageList ))
92+ for _ , img := range imageList {
93+ dimgs = append (dimgs , imageInfoToDisplayImages (img )... )
94+ }
95+
96+ for _ , dimg := range dimgs {
97+ if i .flagDigest {
98+ display .AddRow ([]string {dimg .id , dimg .name , dimg .digest , fmt .Sprintf ("%s" , dimg .size )})
9899 } else {
99- name , err = reference .ParseNamedReference (image .RepoDigests [0 ])
100- if err != nil {
101- return err
100+ display .AddRow ([]string {dimg .id , dimg .name , fmt .Sprintf ("%s" , dimg .size )})
101+ }
102+ }
103+
104+ display .Flush ()
105+ return nil
106+ }
107+
108+ func imageInfoToDisplayImages (img types.ImageInfo ) []displayImage {
109+ dimgs := make ([]displayImage , 0 )
110+
111+ nameTags := make (map [string ][]string )
112+ digestIndexByName := make (map [string ]digest.Digest )
113+
114+ for _ , repoTag := range img .RepoTags {
115+ namedRef , err := reference .Parse (repoTag )
116+ // ideally, it should be nil
117+ if err != nil {
118+ continue
119+ }
120+
121+ if reference .IsNameTagged (namedRef ) {
122+ taggedRef := namedRef .(reference.Tagged )
123+ nameTags [taggedRef .Name ()] = append (nameTags [taggedRef .Name ()], taggedRef .Tag ())
124+ }
125+ }
126+
127+ for _ , repoDigest := range img .RepoDigests {
128+ namedRef , err := reference .Parse (repoDigest )
129+ // ideally, it should be nil
130+ if err != nil {
131+ continue
132+ }
133+
134+ namedRef = reference .TrimTagForDigest (namedRef )
135+ if cdRef , ok := namedRef .(reference.CanonicalDigested ); ok {
136+ digestIndexByName [cdRef .Name ()] = cdRef .Digest ()
137+ }
138+ }
139+
140+ for name , tags := range nameTags {
141+ for _ , tag := range tags {
142+ dimg := displayImage {
143+ id : utils .TruncateID (img .ID ),
144+ name : name + ":" + tag ,
145+ size : imageSize (img .Size ),
102146 }
103- if digestd , ok := name .(reference.Digested ); ok {
104- digest = digestd .Digest ()
147+
148+ if dig , ok := digestIndexByName [name ]; ok {
149+ dimg .digest = dig .String ()
150+ } else {
151+ dimg .digest = "<none>"
105152 }
153+ dimgs = append (dimgs , dimg )
106154 }
155+ }
107156
108- if i .flagDigest {
109- display .AddRow ([]string {
110- utils .TruncateID (image .ID ),
111- name .String (),
112- digest ,
113- fmt .Sprintf ("%s" , imageSize (image .Size )),
157+ // if there is no repo tags
158+ if len (dimgs ) == 0 {
159+ for name , dig := range digestIndexByName {
160+ dimgs = append (dimgs , displayImage {
161+ id : utils .TruncateID (img .ID ),
162+ name : name + "@" + dig .String (),
163+ digest : dig .String (),
164+ size : imageSize (img .Size ),
114165 })
115- } else {
116- display .AddRow ([]string {
117- utils .TruncateID (image .ID ),
118- name .String (),
119- fmt .Sprintf ("%s" , imageSize (image .Size )),
166+ }
167+
168+ // if there is no repo digests
169+ if len (dimgs ) == 0 {
170+ dimgs = append (dimgs , displayImage {
171+ id : utils .TruncateID (img .ID ),
172+ name : "<none>" ,
173+ digest : "<none>" ,
174+ size : imageSize (img .Size ),
120175 })
121176 }
122177 }
123-
124- display .Flush ()
125- return nil
178+ return dimgs
126179}
127180
128181// imagesExample shows examples in images command, and is used in auto-generated cli docs.
0 commit comments