Browse code

Use spf13/cobra for docker logs

This fix is part of the effort to convert commands to spf13/cobra #23211.

Thif fix coverted command `docker logs` to use spf13/cobra

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

Yong Tang authored on 2016/06/06 07:50:48
Showing 5 changed files
... ...
@@ -19,7 +19,6 @@ func (cli *DockerCli) Command(name string) func(...string) error {
19 19
 		"load":               cli.CmdLoad,
20 20
 		"login":              cli.CmdLogin,
21 21
 		"logout":             cli.CmdLogout,
22
-		"logs":               cli.CmdLogs,
23 22
 		"network":            cli.CmdNetwork,
24 23
 		"network create":     cli.CmdNetworkCreate,
25 24
 		"network connect":    cli.CmdNetworkConnect,
26 25
new file mode 100644
... ...
@@ -0,0 +1,88 @@
0
+package container
1
+
2
+import (
3
+	"fmt"
4
+	"io"
5
+
6
+	"golang.org/x/net/context"
7
+
8
+	"github.com/docker/docker/api/client"
9
+	"github.com/docker/docker/cli"
10
+	"github.com/docker/docker/pkg/stdcopy"
11
+	"github.com/docker/engine-api/types"
12
+	"github.com/spf13/cobra"
13
+)
14
+
15
+var validDrivers = map[string]bool{
16
+	"json-file": true,
17
+	"journald":  true,
18
+}
19
+
20
+type logsOptions struct {
21
+	follow     bool
22
+	since      string
23
+	timestamps bool
24
+	details    bool
25
+	tail       string
26
+
27
+	container string
28
+}
29
+
30
+// NewLogsCommand creats a new cobra.Command for `docker logs`
31
+func NewLogsCommand(dockerCli *client.DockerCli) *cobra.Command {
32
+	var opts logsOptions
33
+
34
+	cmd := &cobra.Command{
35
+		Use:   "logs [OPTIONS] CONTAINER",
36
+		Short: "Fetch the logs of a container",
37
+		Args:  cli.ExactArgs(1),
38
+		RunE: func(cmd *cobra.Command, args []string) error {
39
+			opts.container = args[0]
40
+			return runLogs(dockerCli, &opts)
41
+		},
42
+	}
43
+	cmd.SetFlagErrorFunc(flagErrorFunc)
44
+
45
+	flags := cmd.Flags()
46
+	flags.BoolVarP(&opts.follow, "follow", "f", false, "Follow log output")
47
+	flags.StringVar(&opts.since, "since", "", "Show logs since timestamp")
48
+	flags.BoolVarP(&opts.timestamps, "timestamps", "t", false, "Show timestamps")
49
+	flags.BoolVar(&opts.details, "details", false, "Show extra details provided to logs")
50
+	flags.StringVar(&opts.tail, "tail", "all", "Number of lines to show from the end of the logs")
51
+	return cmd
52
+}
53
+
54
+func runLogs(dockerCli *client.DockerCli, opts *logsOptions) error {
55
+	ctx := context.Background()
56
+
57
+	c, err := dockerCli.Client().ContainerInspect(ctx, opts.container)
58
+	if err != nil {
59
+		return err
60
+	}
61
+
62
+	if !validDrivers[c.HostConfig.LogConfig.Type] {
63
+		return fmt.Errorf("\"logs\" command is supported only for \"json-file\" and \"journald\" logging drivers (got: %s)", c.HostConfig.LogConfig.Type)
64
+	}
65
+
66
+	options := types.ContainerLogsOptions{
67
+		ShowStdout: true,
68
+		ShowStderr: true,
69
+		Since:      opts.since,
70
+		Timestamps: opts.timestamps,
71
+		Follow:     opts.follow,
72
+		Tail:       opts.tail,
73
+		Details:    opts.details,
74
+	}
75
+	responseBody, err := dockerCli.Client().ContainerLogs(ctx, opts.container, options)
76
+	if err != nil {
77
+		return err
78
+	}
79
+	defer responseBody.Close()
80
+
81
+	if c.Config.Tty {
82
+		_, err = io.Copy(dockerCli.Out(), responseBody)
83
+	} else {
84
+		_, err = stdcopy.StdCopy(dockerCli.Out(), dockerCli.Err(), responseBody)
85
+	}
86
+	return err
87
+}
0 88
deleted file mode 100644
... ...
@@ -1,68 +0,0 @@
1
-package client
2
-
3
-import (
4
-	"fmt"
5
-	"io"
6
-
7
-	"golang.org/x/net/context"
8
-
9
-	Cli "github.com/docker/docker/cli"
10
-	flag "github.com/docker/docker/pkg/mflag"
11
-	"github.com/docker/docker/pkg/stdcopy"
12
-	"github.com/docker/engine-api/types"
13
-)
14
-
15
-var validDrivers = map[string]bool{
16
-	"json-file": true,
17
-	"journald":  true,
18
-}
19
-
20
-// CmdLogs fetches the logs of a given container.
21
-//
22
-// docker logs [OPTIONS] CONTAINER
23
-func (cli *DockerCli) CmdLogs(args ...string) error {
24
-	cmd := Cli.Subcmd("logs", []string{"CONTAINER"}, Cli.DockerCommands["logs"].Description, true)
25
-	follow := cmd.Bool([]string{"f", "-follow"}, false, "Follow log output")
26
-	since := cmd.String([]string{"-since"}, "", "Show logs since timestamp")
27
-	times := cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps")
28
-	details := cmd.Bool([]string{"-details"}, false, "Show extra details provided to logs")
29
-	tail := cmd.String([]string{"-tail"}, "all", "Number of lines to show from the end of the logs")
30
-	cmd.Require(flag.Exact, 1)
31
-
32
-	cmd.ParseFlags(args, true)
33
-
34
-	name := cmd.Arg(0)
35
-
36
-	ctx := context.Background()
37
-
38
-	c, err := cli.client.ContainerInspect(ctx, name)
39
-	if err != nil {
40
-		return err
41
-	}
42
-
43
-	if !validDrivers[c.HostConfig.LogConfig.Type] {
44
-		return fmt.Errorf("\"logs\" command is supported only for \"json-file\" and \"journald\" logging drivers (got: %s)", c.HostConfig.LogConfig.Type)
45
-	}
46
-
47
-	options := types.ContainerLogsOptions{
48
-		ShowStdout: true,
49
-		ShowStderr: true,
50
-		Since:      *since,
51
-		Timestamps: *times,
52
-		Follow:     *follow,
53
-		Tail:       *tail,
54
-		Details:    *details,
55
-	}
56
-	responseBody, err := cli.client.ContainerLogs(ctx, name, options)
57
-	if err != nil {
58
-		return err
59
-	}
60
-	defer responseBody.Close()
61
-
62
-	if c.Config.Tty {
63
-		_, err = io.Copy(cli.out, responseBody)
64
-	} else {
65
-		_, err = stdcopy.StdCopy(cli.out, cli.err, responseBody)
66
-	}
67
-	return err
68
-}
... ...
@@ -35,6 +35,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor {
35 35
 	rootCmd.AddCommand(
36 36
 		container.NewCreateCommand(dockerCli),
37 37
 		container.NewExportCommand(dockerCli),
38
+		container.NewLogsCommand(dockerCli),
38 39
 		container.NewRunCommand(dockerCli),
39 40
 		container.NewStopCommand(dockerCli),
40 41
 		image.NewRemoveCommand(dockerCli),
... ...
@@ -24,7 +24,6 @@ var DockerCommandUsage = []Command{
24 24
 	{"load", "Load an image from a tar archive or STDIN"},
25 25
 	{"login", "Log in to a Docker registry"},
26 26
 	{"logout", "Log out from a Docker registry"},
27
-	{"logs", "Fetch the logs of a container"},
28 27
 	{"network", "Manage Docker networks"},
29 28
 	{"pause", "Pause all processes within a container"},
30 29
 	{"port", "List port mappings or a specific mapping for the CONTAINER"},