func runEvents(dockerCli *client.DockerCli, opts *eventsOptions) error { eventFilterArgs := filters.NewArgs() // Consolidate all filter flags, and sanity check them early. // They'll get process in the daemon/server. for _, f := range opts.filter { var err error eventFilterArgs, err = filters.ParseFlag(f, eventFilterArgs) if err != nil { return err } } options := types.EventsOptions{ Since: opts.since, Until: opts.until, Filters: eventFilterArgs, } responseBody, err := dockerCli.Client().Events(context.Background(), options) if err != nil { return err } defer responseBody.Close() return streamEvents(responseBody, dockerCli.Out()) }
// CmdNetworkLs lists all the networks managed by docker daemon // // Usage: docker network ls [OPTIONS] func (cli *DockerCli) CmdNetworkLs(args ...string) error { cmd := Cli.Subcmd("network ls", nil, "Lists networks", true) quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs") noTrunc := cmd.Bool([]string{"-no-trunc"}, false, "Do not truncate the output") flFilter := opts.NewListOpts(nil) cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided") cmd.Require(flag.Exact, 0) err := cmd.ParseFlags(args, true) if err != nil { return err } // Consolidate all filter flags, and sanity check them early. // They'll get process after get response from server. netFilterArgs := filters.NewArgs() for _, f := range flFilter.GetAll() { if netFilterArgs, err = filters.ParseFlag(f, netFilterArgs); err != nil { return err } } options := types.NetworkListOptions{ Filters: netFilterArgs, } networkResources, err := cli.client.NetworkList(options) if err != nil { return err } wr := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) // unless quiet (-q) is specified, print field titles if !*quiet { fmt.Fprintln(wr, "NETWORK ID\tNAME\tDRIVER") } for _, networkResource := range networkResources { ID := networkResource.ID netName := networkResource.Name if !*noTrunc { ID = stringid.TruncateID(ID) } if *quiet { fmt.Fprintln(wr, ID) continue } driver := networkResource.Driver fmt.Fprintf(wr, "%s\t%s\t%s\t", ID, netName, driver) fmt.Fprint(wr, "\n") } wr.Flush() return nil }
func runImages(dockerCli *command.DockerCli, opts imagesOptions) error { ctx := context.Background() // Consolidate all filter flags, and sanity check them early. // They'll get process in the daemon/server. imageFilterArgs := filters.NewArgs() for _, f := range opts.filter { var err error imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs) if err != nil { return err } } matchName := opts.matchName options := types.ImageListOptions{ MatchName: matchName, All: opts.all, Filters: imageFilterArgs, } images, err := dockerCli.Client().ImageList(ctx, options) if err != nil { return err } f := opts.format if len(f) == 0 { if len(dockerCli.ConfigFile().ImagesFormat) > 0 && !opts.quiet { f = dockerCli.ConfigFile().ImagesFormat } else { f = "table" } } imagesCtx := formatter.ImageContext{ Context: formatter.Context{ Output: dockerCli.Out(), Format: f, Quiet: opts.quiet, Trunc: !opts.noTrunc, }, Digest: opts.showDigests, Images: images, } imagesCtx.Write() return nil }
func runList(dockerCli *client.DockerCli, opts listOptions) error { client := dockerCli.Client() netFilterArgs := filters.NewArgs() for _, f := range opts.filter { var err error netFilterArgs, err = filters.ParseFlag(f, netFilterArgs) if err != nil { return err } } options := types.NetworkListOptions{ Filters: netFilterArgs, } networkResources, err := client.NetworkList(context.Background(), options) if err != nil { return err } f := opts.format if len(f) == 0 { if len(dockerCli.ConfigFile().NetworksFormat) > 0 && !opts.quiet { f = dockerCli.ConfigFile().NetworksFormat } else { f = "table" } } sort.Sort(byNetworkName(networkResources)) networksCtx := formatter.NetworkContext{ Context: formatter.Context{ Output: dockerCli.Out(), Format: f, Quiet: opts.quiet, Trunc: !opts.noTrunc, }, Networks: networkResources, } networksCtx.Write() return nil }
// CmdVolumeLs outputs a list of Docker volumes. // // Usage: docker volume ls [OPTIONS] func (cli *DockerCli) CmdVolumeLs(args ...string) error { cmd := Cli.Subcmd("volume ls", nil, "List volumes", true) quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display volume names") flFilter := opts.NewListOpts(nil) cmd.Var(&flFilter, []string{"f", "-filter"}, "Provide filter values (i.e. 'dangling=true')") cmd.Require(flag.Exact, 0) cmd.ParseFlags(args, true) volFilterArgs := filters.NewArgs() for _, f := range flFilter.GetAll() { var err error volFilterArgs, err = filters.ParseFlag(f, volFilterArgs) if err != nil { return err } } volumes, err := cli.client.VolumeList(volFilterArgs) if err != nil { return err } w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) if !*quiet { for _, warn := range volumes.Warnings { fmt.Fprintln(cli.err, warn) } fmt.Fprintf(w, "DRIVER \tVOLUME NAME") fmt.Fprintf(w, "\n") } for _, vol := range volumes.Volumes { if *quiet { fmt.Fprintln(w, vol.Name) continue } fmt.Fprintf(w, "%s\t%s\n", vol.Driver, vol.Name) } w.Flush() return nil }
func (l *LocalCluster) monitor(ctx context.Context) { if log.V(1) { log.Infof(ctx, "events monitor starts") defer log.Infof(ctx, "events monitor exits") } longPoll := func() bool { // If our context was cancelled, it's time to go home. if l.monitorCtx.Err() != nil { return false } args, err := filters.ParseFlag( fmt.Sprintf("label=Acceptance-cluster-id=%s", l.clusterID), filters.NewArgs()) maybePanic(err) eventq, errq := l.client.Events(l.monitorCtx, types.EventsOptions{ Filters: args, }) for { select { case err := <-errq: log.Infof(ctx, "event stream done, resetting...: %s", err) // Sometimes we get a random string-wrapped EOF error back. // Hard to assert on, so we just let this goroutine spin. return true case event := <-eventq: // Currently, the only events generated (and asserted against) are "die" // and "restart", to maximize compatibility across different versions of // Docker. switch event.Status { case eventDie, eventRestart: if !l.processEvent(ctx, event) { return false } } } } } for longPoll() { } }
func runList(dockerCli *client.DockerCli, opts listOptions) error { client := dockerCli.Client() volFilterArgs := filters.NewArgs() for _, f := range opts.filter { var err error volFilterArgs, err = filters.ParseFlag(f, volFilterArgs) if err != nil { return err } } volumes, err := client.VolumeList(context.Background(), volFilterArgs) if err != nil { return err } f := opts.format if len(f) == 0 { if len(dockerCli.ConfigFile().VolumesFormat) > 0 && !opts.quiet { f = dockerCli.ConfigFile().VolumesFormat } else { f = "table" } } sort.Sort(byVolumeName(volumes.Volumes)) volumeCtx := formatter.VolumeContext{ Context: formatter.Context{ Output: dockerCli.Out(), Format: f, Quiet: opts.quiet, }, Volumes: volumes.Volumes, } volumeCtx.Write() return nil }
func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, error) { options := &types.ContainerListOptions{ All: opts.all, Limit: opts.last, Size: opts.size, Filter: filters.NewArgs(), } if opts.nLatest && opts.last == -1 { options.Limit = 1 } for _, f := range opts.filter { var err error options.Filter, err = filters.ParseFlag(f, options.Filter) if err != nil { return nil, err } } // Currently only used with Size, so we can determine if the user // put {{.Size}} in their format. pre := &preProcessor{opts: options} tmpl, err := templates.Parse(opts.format) if err != nil { return nil, err } // This shouldn't error out but swallowing the error makes it harder // to track down if preProcessor issues come up. Ref #24696 if err := tmpl.Execute(ioutil.Discard, pre); err != nil { return nil, err } return options, nil }
// CmdEvents prints a live stream of real time events from the server. // // Usage: docker events [OPTIONS] func (cli *DockerCli) CmdEvents(args ...string) error { cmd := Cli.Subcmd("events", nil, Cli.DockerCommands["events"].Description, true) since := cmd.String([]string{"-since"}, "", "Show all events created since timestamp") until := cmd.String([]string{"-until"}, "", "Stream events until this timestamp") flFilter := opts.NewListOpts(nil) cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided") cmd.Require(flag.Exact, 0) cmd.ParseFlags(args, true) eventFilterArgs := filters.NewArgs() // Consolidate all filter flags, and sanity check them early. // They'll get process in the daemon/server. for _, f := range flFilter.GetAll() { var err error eventFilterArgs, err = filters.ParseFlag(f, eventFilterArgs) if err != nil { return err } } options := types.EventsOptions{ Since: *since, Until: *until, Filters: eventFilterArgs, } responseBody, err := cli.client.Events(options) if err != nil { return err } defer responseBody.Close() return streamEvents(responseBody, cli.out) }
// CmdImages lists the images in a specified repository, or all top-level images if no repository is specified. // // Usage: docker images [OPTIONS] [REPOSITORY] func (cli *DockerCli) CmdImages(args ...string) error { cmd := Cli.Subcmd("images", []string{"[REPOSITORY[:TAG]]"}, Cli.DockerCommands["images"].Description, true) quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs") all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (default hides intermediate images)") noTrunc := cmd.Bool([]string{"-no-trunc"}, false, "Don't truncate output") showDigests := cmd.Bool([]string{"-digests"}, false, "Show digests") flFilter := opts.NewListOpts(nil) cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided") cmd.Require(flag.Max, 1) cmd.ParseFlags(args, true) // Consolidate all filter flags, and sanity check them early. // They'll get process in the daemon/server. imageFilterArgs := filters.NewArgs() for _, f := range flFilter.GetAll() { var err error imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs) if err != nil { return err } } var matchName string if cmd.NArg() == 1 { matchName = cmd.Arg(0) } options := types.ImageListOptions{ MatchName: matchName, All: *all, Filters: imageFilterArgs, } images, err := cli.client.ImageList(options) if err != nil { return err } w := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) if !*quiet { if *showDigests { fmt.Fprintln(w, "REPOSITORY\tTAG\tDIGEST\tIMAGE ID\tCREATED\tSIZE") } else { fmt.Fprintln(w, "REPOSITORY\tTAG\tIMAGE ID\tCREATED\tSIZE") } } for _, image := range images { ID := image.ID if !*noTrunc { ID = stringid.TruncateID(ID) } repoTags := image.RepoTags repoDigests := image.RepoDigests if len(repoTags) == 1 && repoTags[0] == "<none>:<none>" && len(repoDigests) == 1 && repoDigests[0] == "<none>@<none>" { // dangling image - clear out either repoTags or repoDigsts so we only show it once below repoDigests = []string{} } // combine the tags and digests lists tagsAndDigests := append(repoTags, repoDigests...) for _, repoAndRef := range tagsAndDigests { // default repo, tag, and digest to none - if there's a value, it'll be set below repo := "<none>" tag := "<none>" digest := "<none>" if !strings.HasPrefix(repoAndRef, "<none>") { ref, err := reference.ParseNamed(repoAndRef) if err != nil { return err } repo = ref.Name() switch x := ref.(type) { case reference.Digested: digest = x.Digest().String() case reference.Tagged: tag = x.Tag() } } if !*quiet { if *showDigests { 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))) } else { 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))) } } else { fmt.Fprintln(w, ID) } } } if !*quiet { w.Flush() } return nil }
// Set sets the value of the opt by parsing the command line value func (o *FilterOpt) Set(value string) error { var err error o.filter, err = filters.ParseFlag(value, o.filter) return err }
// CmdPs outputs a list of Docker containers. // // Usage: docker ps [OPTIONS] func (cli *DockerCli) CmdPs(args ...string) error { var ( err error psFilterArgs = filters.NewArgs() cmd = Cli.Subcmd("ps", nil, Cli.DockerCommands["ps"].Description, true) quiet = cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs") size = cmd.Bool([]string{"s", "-size"}, false, "Display total file sizes") all = cmd.Bool([]string{"a", "-all"}, false, "Show all containers (default shows just running)") noTrunc = cmd.Bool([]string{"-no-trunc"}, false, "Don't truncate output") nLatest = cmd.Bool([]string{"l", "-latest"}, false, "Show the latest created container (includes all states)") since = cmd.String([]string{"#-since"}, "", "Show containers created since Id or Name (includes all states)") before = cmd.String([]string{"#-before"}, "", "Only show containers created before Id or Name") last = cmd.Int([]string{"n"}, -1, "Show n last created containers (includes all states)") format = cmd.String([]string{"-format"}, "", "Pretty-print containers using a Go template") flFilter = opts.NewListOpts(nil) ) cmd.Require(flag.Exact, 0) cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided") cmd.ParseFlags(args, true) if *last == -1 && *nLatest { *last = 1 } // Consolidate all filter flags, and sanity check them. // They'll get processed in the daemon/server. for _, f := range flFilter.GetAll() { if psFilterArgs, err = filters.ParseFlag(f, psFilterArgs); err != nil { return err } } options := types.ContainerListOptions{ All: *all, Limit: *last, Since: *since, Before: *before, Size: *size, Filter: psFilterArgs, } containers, err := cli.client.ContainerList(options) if err != nil { return err } f := *format if len(f) == 0 { if len(cli.PsFormat()) > 0 && !*quiet { f = cli.PsFormat() } else { f = "table" } } psCtx := formatter.ContainerContext{ Context: formatter.Context{ Output: cli.out, Format: f, Quiet: *quiet, Trunc: !*noTrunc, }, Size: *size, Containers: containers, } psCtx.Write() return nil }
func runSearch(dockerCli *command.DockerCli, opts searchOptions) error { indexInfo, err := registry.ParseSearchIndexInfo(opts.term) if err != nil { return err } ctx := context.Background() authConfig := dockerCli.ResolveAuthConfig(ctx, indexInfo) requestPrivilege := dockerCli.RegistryAuthenticationPrivilegedFunc(indexInfo, "search") encodedAuth, err := command.EncodeAuthToBase64(authConfig) if err != nil { return err } searchFilters := filters.NewArgs() for _, f := range opts.filter { var err error searchFilters, err = filters.ParseFlag(f, searchFilters) if err != nil { return err } } options := types.ImageSearchOptions{ RegistryAuth: encodedAuth, PrivilegeFunc: requestPrivilege, Filters: searchFilters, Limit: opts.limit, } clnt := dockerCli.Client() unorderedResults, err := clnt.ImageSearch(ctx, opts.term, options) if err != nil { return err } results := searchResultsByStars(unorderedResults) sort.Sort(results) w := tabwriter.NewWriter(dockerCli.Out(), 10, 1, 3, ' ', 0) fmt.Fprintf(w, "NAME\tDESCRIPTION\tSTARS\tOFFICIAL\tAUTOMATED\n") for _, res := range results { // --automated and -s, --stars are deprecated since Docker 1.12 if (opts.automated && !res.IsAutomated) || (int(opts.stars) > res.StarCount) { continue } desc := strings.Replace(res.Description, "\n", " ", -1) desc = strings.Replace(desc, "\r", " ", -1) if !opts.noTrunc { desc = stringutils.Ellipsis(desc, 45) } fmt.Fprintf(w, "%s\t%s\t%d\t", res.Name, desc, res.StarCount) if res.IsOfficial { fmt.Fprint(w, "[OK]") } fmt.Fprint(w, "\t") if res.IsAutomated { fmt.Fprint(w, "[OK]") } fmt.Fprint(w, "\n") } w.Flush() return nil }
// CmdImages lists the images in a specified repository, or all top-level images if no repository is specified. // // Usage: docker images [OPTIONS] [REPOSITORY] func (cli *DockerCli) CmdImages(args ...string) error { cmd := Cli.Subcmd("images", []string{"[REPOSITORY[:TAG]]"}, Cli.DockerCommands["images"].Description, true) quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only show numeric IDs") all := cmd.Bool([]string{"a", "-all"}, false, "Show all images (default hides intermediate images)") noTrunc := cmd.Bool([]string{"-no-trunc"}, false, "Don't truncate output") showDigests := cmd.Bool([]string{"-digests"}, false, "Show digests") format := cmd.String([]string{"-format"}, "", "Pretty-print images using a Go template") flFilter := opts.NewListOpts(nil) cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided") cmd.Require(flag.Max, 1) cmd.ParseFlags(args, true) // Consolidate all filter flags, and sanity check them early. // They'll get process in the daemon/server. imageFilterArgs := filters.NewArgs() for _, f := range flFilter.GetAll() { var err error imageFilterArgs, err = filters.ParseFlag(f, imageFilterArgs) if err != nil { return err } } var matchName string if cmd.NArg() == 1 { matchName = cmd.Arg(0) } options := types.ImageListOptions{ MatchName: matchName, All: *all, Filters: imageFilterArgs, } images, err := cli.client.ImageList(options) if err != nil { return err } f := *format if len(f) == 0 { if len(cli.ImagesFormat()) > 0 && !*quiet { f = cli.ImagesFormat() } else { f = "table" } } imagesCtx := formatter.ImageContext{ Context: formatter.Context{ Output: cli.out, Format: f, Quiet: *quiet, Trunc: !*noTrunc, }, Digest: *showDigests, Images: images, } imagesCtx.Write() return nil }