github.com/walkingsparrow/docker@v1.4.2-0.20151218153551-b708a2249bfa/api/client/images.go (about)

     1  package client
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"text/tabwriter"
     7  	"time"
     8  
     9  	"github.com/docker/docker/api/types"
    10  	"github.com/docker/docker/api/types/filters"
    11  	Cli "github.com/docker/docker/cli"
    12  	"github.com/docker/docker/opts"
    13  	flag "github.com/docker/docker/pkg/mflag"
    14  	"github.com/docker/docker/pkg/stringid"
    15  	"github.com/docker/docker/reference"
    16  	"github.com/docker/go-units"
    17  )
    18  
    19  // CmdImages lists the images in a specified repository, or all top-level images if no repository is specified.
    20  //
    21  // Usage: docker images [OPTIONS] [REPOSITORY]
    22  func (cli *DockerCli) CmdImages(args ...string) error {
    23  	cmd := Cli.Subcmd("images", []string{"[REPOSITORY[:TAG]]"}, Cli.DockerCommands["images"].Description, true)
    24  	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
    25  	all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (default hides intermediate images)")
    26  	noTrunc := cmd.Bool([]string{"-no-trunc"}, false, "Don't truncate output")
    27  	showDigests := cmd.Bool([]string{"-digests"}, false, "Show digests")
    28  
    29  	flFilter := opts.NewListOpts(nil)
    30  	cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
    31  	cmd.Require(flag.Max, 1)
    32  
    33  	cmd.ParseFlags(args, true)
    34  
    35  	// Consolidate all filter flags, and sanity check them early.
    36  	// They'll get process in the daemon/server.
    37  	imageFilterArgs := filters.NewArgs()
    38  	for _, f := range flFilter.GetAll() {
    39  		var err error
    40  		imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs)
    41  		if err != nil {
    42  			return err
    43  		}
    44  	}
    45  
    46  	var matchName string
    47  	if cmd.NArg() == 1 {
    48  		matchName = cmd.Arg(0)
    49  	}
    50  
    51  	options := types.ImageListOptions{
    52  		MatchName: matchName,
    53  		All:       *all,
    54  		Filters:   imageFilterArgs,
    55  	}
    56  
    57  	images, err := cli.client.ImageList(options)
    58  	if err != nil {
    59  		return err
    60  	}
    61  
    62  	w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
    63  	if !*quiet {
    64  		if *showDigests {
    65  			fmt.Fprintln(w, "REPOSITORY\tTAG\tDIGEST\tIMAGE ID\tCREATED\tSIZE")
    66  		} else {
    67  			fmt.Fprintln(w, "REPOSITORY\tTAG\tIMAGE ID\tCREATED\tSIZE")
    68  		}
    69  	}
    70  
    71  	for _, image := range images {
    72  		ID := image.ID
    73  		if !*noTrunc {
    74  			ID = stringid.TruncateID(ID)
    75  		}
    76  
    77  		repoTags := image.RepoTags
    78  		repoDigests := image.RepoDigests
    79  
    80  		if len(repoTags) == 1 && repoTags[0] == "<none>:<none>" && len(repoDigests) == 1 && repoDigests[0] == "<none>@<none>" {
    81  			// dangling image - clear out either repoTags or repoDigsts so we only show it once below
    82  			repoDigests = []string{}
    83  		}
    84  
    85  		// combine the tags and digests lists
    86  		tagsAndDigests := append(repoTags, repoDigests...)
    87  		for _, repoAndRef := range tagsAndDigests {
    88  			// default repo, tag, and digest to none - if there's a value, it'll be set below
    89  			repo := "<none>"
    90  			tag := "<none>"
    91  			digest := "<none>"
    92  
    93  			if !strings.HasPrefix(repoAndRef, "<none>") {
    94  				ref, err := reference.ParseNamed(repoAndRef)
    95  				if err != nil {
    96  					return err
    97  				}
    98  				repo = ref.Name()
    99  
   100  				switch x := ref.(type) {
   101  				case reference.Canonical:
   102  					digest = x.Digest().String()
   103  				case reference.NamedTagged:
   104  					tag = x.Tag()
   105  				}
   106  			}
   107  
   108  			if !*quiet {
   109  				if *showDigests {
   110  					fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s ago\t%s\n", repo, tag, digest, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.Size)))
   111  				} else {
   112  					fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, ID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(int64(image.Created), 0))), units.HumanSize(float64(image.Size)))
   113  				}
   114  			} else {
   115  				fmt.Fprintln(w, ID)
   116  			}
   117  		}
   118  	}
   119  
   120  	if !*quiet {
   121  		w.Flush()
   122  	}
   123  	return nil
   124  }