Merge pull request #23284 from yongtang/23211-spf13-cobra-logs

Use spf13/cobra for docker logs
This commit is contained in:
Vincent Demeester 2016-06-06 09:06:51 +02:00
commit 731bae6749
5 changed files with 89 additions and 70 deletions

View file

@ -18,7 +18,6 @@ func (cli *DockerCli) Command(name string) func(...string) error {
"load": cli.CmdLoad,
"login": cli.CmdLogin,
"logout": cli.CmdLogout,
"logs": cli.CmdLogs,
"network": cli.CmdNetwork,
"network create": cli.CmdNetworkCreate,
"network connect": cli.CmdNetworkConnect,

View file

@ -0,0 +1,88 @@
package container
import (
"fmt"
"io"
"golang.org/x/net/context"
"github.com/docker/docker/api/client"
"github.com/docker/docker/cli"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/engine-api/types"
"github.com/spf13/cobra"
)
var validDrivers = map[string]bool{
"json-file": true,
"journald": true,
}
type logsOptions struct {
follow bool
since string
timestamps bool
details bool
tail string
container string
}
// NewLogsCommand creats a new cobra.Command for `docker logs`
func NewLogsCommand(dockerCli *client.DockerCli) *cobra.Command {
var opts logsOptions
cmd := &cobra.Command{
Use: "logs [OPTIONS] CONTAINER",
Short: "Fetch the logs of a container",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.container = args[0]
return runLogs(dockerCli, &opts)
},
}
cmd.SetFlagErrorFunc(flagErrorFunc)
flags := cmd.Flags()
flags.BoolVarP(&opts.follow, "follow", "f", false, "Follow log output")
flags.StringVar(&opts.since, "since", "", "Show logs since timestamp")
flags.BoolVarP(&opts.timestamps, "timestamps", "t", false, "Show timestamps")
flags.BoolVar(&opts.details, "details", false, "Show extra details provided to logs")
flags.StringVar(&opts.tail, "tail", "all", "Number of lines to show from the end of the logs")
return cmd
}
func runLogs(dockerCli *client.DockerCli, opts *logsOptions) error {
ctx := context.Background()
c, err := dockerCli.Client().ContainerInspect(ctx, opts.container)
if err != nil {
return err
}
if !validDrivers[c.HostConfig.LogConfig.Type] {
return fmt.Errorf("\"logs\" command is supported only for \"json-file\" and \"journald\" logging drivers (got: %s)", c.HostConfig.LogConfig.Type)
}
options := types.ContainerLogsOptions{
ShowStdout: true,
ShowStderr: true,
Since: opts.since,
Timestamps: opts.timestamps,
Follow: opts.follow,
Tail: opts.tail,
Details: opts.details,
}
responseBody, err := dockerCli.Client().ContainerLogs(ctx, opts.container, options)
if err != nil {
return err
}
defer responseBody.Close()
if c.Config.Tty {
_, err = io.Copy(dockerCli.Out(), responseBody)
} else {
_, err = stdcopy.StdCopy(dockerCli.Out(), dockerCli.Err(), responseBody)
}
return err
}

View file

@ -1,68 +0,0 @@
package client
import (
"fmt"
"io"
"golang.org/x/net/context"
Cli "github.com/docker/docker/cli"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/engine-api/types"
)
var validDrivers = map[string]bool{
"json-file": true,
"journald": true,
}
// CmdLogs fetches the logs of a given container.
//
// docker logs [OPTIONS] CONTAINER
func (cli *DockerCli) CmdLogs(args ...string) error {
cmd := Cli.Subcmd("logs", []string{"CONTAINER"}, Cli.DockerCommands["logs"].Description, true)
follow := cmd.Bool([]string{"f", "-follow"}, false, "Follow log output")
since := cmd.String([]string{"-since"}, "", "Show logs since timestamp")
times := cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps")
details := cmd.Bool([]string{"-details"}, false, "Show extra details provided to logs")
tail := cmd.String([]string{"-tail"}, "all", "Number of lines to show from the end of the logs")
cmd.Require(flag.Exact, 1)
cmd.ParseFlags(args, true)
name := cmd.Arg(0)
ctx := context.Background()
c, err := cli.client.ContainerInspect(ctx, name)
if err != nil {
return err
}
if !validDrivers[c.HostConfig.LogConfig.Type] {
return fmt.Errorf("\"logs\" command is supported only for \"json-file\" and \"journald\" logging drivers (got: %s)", c.HostConfig.LogConfig.Type)
}
options := types.ContainerLogsOptions{
ShowStdout: true,
ShowStderr: true,
Since: *since,
Timestamps: *times,
Follow: *follow,
Tail: *tail,
Details: *details,
}
responseBody, err := cli.client.ContainerLogs(ctx, name, options)
if err != nil {
return err
}
defer responseBody.Close()
if c.Config.Tty {
_, err = io.Copy(cli.out, responseBody)
} else {
_, err = stdcopy.StdCopy(cli.out, cli.err, responseBody)
}
return err
}

View file

@ -36,6 +36,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor {
container.NewCreateCommand(dockerCli),
container.NewDiffCommand(dockerCli),
container.NewExportCommand(dockerCli),
container.NewLogsCommand(dockerCli),
container.NewRunCommand(dockerCli),
container.NewStartCommand(dockerCli),
container.NewStopCommand(dockerCli),

View file

@ -23,7 +23,6 @@ var DockerCommandUsage = []Command{
{"load", "Load an image from a tar archive or STDIN"},
{"login", "Log in to a Docker registry"},
{"logout", "Log out from a Docker registry"},
{"logs", "Fetch the logs of a container"},
{"network", "Manage Docker networks"},
{"pause", "Pause all processes within a container"},
{"port", "List port mappings or a specific mapping for the CONTAINER"},