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