github.com/squaremo/docker@v1.3.2-0.20150516120342-42cfc9554972/api/client/images.go (about)

     1  package client
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/url"
     7  	"text/tabwriter"
     8  	"time"
     9  
    10  	"github.com/docker/docker/api/types"
    11  	"github.com/docker/docker/opts"
    12  	flag "github.com/docker/docker/pkg/mflag"
    13  	"github.com/docker/docker/pkg/parsers"
    14  	"github.com/docker/docker/pkg/parsers/filters"
    15  	"github.com/docker/docker/pkg/stringid"
    16  	"github.com/docker/docker/pkg/units"
    17  	"github.com/docker/docker/utils"
    18  )
    19  
    20  // CmdImages lists the images in a specified repository, or all top-level images if no repository is specified.
    21  //
    22  // Usage: docker images [OPTIONS] [REPOSITORY]
    23  func (cli *DockerCli) CmdImages(args ...string) error {
    24  	cmd := cli.Subcmd("images", "[REPOSITORY]", "List images", true)
    25  	quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs")
    26  	all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (default hides intermediate images)")
    27  	noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Don't truncate output")
    28  	showDigests := cmd.Bool([]string{"-digests"}, false, "Show digests")
    29  
    30  	flFilter := opts.NewListOpts(nil)
    31  	cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided")
    32  	cmd.Require(flag.Max, 1)
    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.Args{}
    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  	matchName := cmd.Arg(0)
    47  	v := url.Values{}
    48  	if len(imageFilterArgs) > 0 {
    49  		filterJSON, err := filters.ToParam(imageFilterArgs)
    50  		if err != nil {
    51  			return err
    52  		}
    53  		v.Set("filters", filterJSON)
    54  	}
    55  
    56  	if cmd.NArg() == 1 {
    57  		// FIXME rename this parameter, to not be confused with the filters flag
    58  		v.Set("filter", matchName)
    59  	}
    60  	if *all {
    61  		v.Set("all", "1")
    62  	}
    63  
    64  	rdr, _, err := cli.call("GET", "/images/json?"+v.Encode(), nil, nil)
    65  	if err != nil {
    66  		return err
    67  	}
    68  
    69  	images := []types.Image{}
    70  	if err := json.NewDecoder(rdr).Decode(&images); err != nil {
    71  		return err
    72  	}
    73  
    74  	w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0)
    75  	if !*quiet {
    76  		if *showDigests {
    77  			fmt.Fprintln(w, "REPOSITORY\tTAG\tDIGEST\tIMAGE ID\tCREATED\tVIRTUAL SIZE")
    78  		} else {
    79  			fmt.Fprintln(w, "REPOSITORY\tTAG\tIMAGE ID\tCREATED\tVIRTUAL SIZE")
    80  		}
    81  	}
    82  
    83  	for _, image := range images {
    84  		ID := image.ID
    85  		if !*noTrunc {
    86  			ID = stringid.TruncateID(ID)
    87  		}
    88  
    89  		repoTags := image.RepoTags
    90  		repoDigests := image.RepoDigests
    91  
    92  		if len(repoTags) == 1 && repoTags[0] == "<none>:<none>" && len(repoDigests) == 1 && repoDigests[0] == "<none>@<none>" {
    93  			// dangling image - clear out either repoTags or repoDigsts so we only show it once below
    94  			repoDigests = []string{}
    95  		}
    96  
    97  		// combine the tags and digests lists
    98  		tagsAndDigests := append(repoTags, repoDigests...)
    99  		for _, repoAndRef := range tagsAndDigests {
   100  			repo, ref := parsers.ParseRepositoryTag(repoAndRef)
   101  			// default tag and digest to none - if there's a value, it'll be set below
   102  			tag := "<none>"
   103  			digest := "<none>"
   104  			if utils.DigestReference(ref) {
   105  				digest = ref
   106  			} else {
   107  				tag = ref
   108  			}
   109  
   110  			if !*quiet {
   111  				if *showDigests {
   112  					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.VirtualSize)))
   113  				} else {
   114  					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.VirtualSize)))
   115  				}
   116  			} else {
   117  				fmt.Fprintln(w, ID)
   118  			}
   119  		}
   120  	}
   121  
   122  	if !*quiet {
   123  		w.Flush()
   124  	}
   125  	return nil
   126  }