github.com/docker/app@v0.9.1-beta3.0.20210611140623-a48f773ab002/internal/commands/image/list.go (about) 1 package image 2 3 import ( 4 "github.com/docker/app/internal/image" 5 "github.com/docker/app/internal/store" 6 "github.com/docker/cli/cli/command" 7 "github.com/docker/cli/cli/command/formatter" 8 "github.com/docker/cli/cli/config" 9 "github.com/docker/distribution/reference" 10 "github.com/docker/docker/pkg/stringid" 11 "github.com/spf13/cobra" 12 ) 13 14 type imageListOption struct { 15 quiet bool 16 digests bool 17 format string 18 } 19 20 func listCmd(dockerCli command.Cli) *cobra.Command { 21 options := imageListOption{} 22 cmd := &cobra.Command{ 23 Short: "List App images", 24 Use: "ls", 25 Aliases: []string{"list"}, 26 RunE: func(cmd *cobra.Command, args []string) error { 27 appstore, err := store.NewApplicationStore(config.Dir()) 28 if err != nil { 29 return err 30 } 31 32 imageStore, err := appstore.ImageStore() 33 if err != nil { 34 return err 35 } 36 37 return runList(dockerCli, options, imageStore) 38 }, 39 } 40 flags := cmd.Flags() 41 flags.BoolVarP(&options.quiet, "quiet", "q", false, "Only show numeric IDs") 42 flags.BoolVarP(&options.digests, "digests", "", false, "Show image digests") 43 cmd.Flags().StringVarP(&options.format, "format", "f", "table", "Format the output using the given syntax or Go template") 44 cmd.Flags().SetAnnotation("format", "experimentalCLI", []string{"true"}) //nolint:errcheck 45 46 return cmd 47 } 48 49 func runList(dockerCli command.Cli, options imageListOption, imageStore store.ImageStore) error { 50 images, err := getImageDescriptors(imageStore) 51 if err != nil { 52 return err 53 } 54 55 ctx := formatter.Context{ 56 Output: dockerCli.Out(), 57 Format: NewImageFormat(options.format, options.quiet, options.digests), 58 } 59 60 return Write(ctx, images) 61 } 62 63 func getImageDescriptors(imageStore store.ImageStore) ([]imageDesc, error) { 64 references, err := imageStore.List() 65 if err != nil { 66 return nil, err 67 } 68 images := make([]imageDesc, len(references)) 69 for i, ref := range references { 70 b, err := imageStore.Read(ref) 71 if err != nil { 72 return nil, err 73 } 74 75 images[i] = getImageDesc(b, ref) 76 } 77 return images, nil 78 } 79 80 func getImageID(bundle *image.AppImage, ref reference.Reference) (string, error) { 81 id, ok := ref.(store.ID) 82 if !ok { 83 var err error 84 id, err = store.FromAppImage(bundle) 85 if err != nil { 86 return "", err 87 } 88 } 89 return stringid.TruncateID(id.String()), nil 90 } 91 92 type imageDesc struct { 93 ID string `json:"id,omitempty"` 94 Name string `json:"name,omitempty"` 95 Repository string `json:"repository,omitempty"` 96 Tag string `json:"tag,omitempty"` 97 Digest string `json:"digest,omitempty"` 98 } 99 100 func getImageDesc(bundle *image.AppImage, ref reference.Reference) imageDesc { 101 var id string 102 id, _ = getImageID(bundle, ref) 103 var repository string 104 if n, ok := ref.(reference.Named); ok { 105 repository = reference.FamiliarName(n) 106 } 107 var tag string 108 if t, ok := ref.(reference.Tagged); ok { 109 tag = t.Tag() 110 } 111 var digest string 112 if t, ok := ref.(reference.Digested); ok { 113 digest = t.Digest().String() 114 } 115 return imageDesc{ 116 ID: id, 117 Name: bundle.Name, 118 Repository: repository, 119 Tag: tag, 120 Digest: digest, 121 } 122 }