Browse code

Refactor cli inspector to support new inspects.

Signed-off-by: Daniel Nephin <dnephin@docker.com>

Daniel Nephin authored on 2016/05/10 23:58:07
Showing 3 changed files
... ...
@@ -8,7 +8,6 @@ import (
8 8
 	"github.com/docker/docker/api/client/inspect"
9 9
 	Cli "github.com/docker/docker/cli"
10 10
 	flag "github.com/docker/docker/pkg/mflag"
11
-	"github.com/docker/docker/utils/templates"
12 11
 	"github.com/docker/engine-api/client"
13 12
 )
14 13
 
... ...
@@ -30,7 +29,7 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
30 30
 
31 31
 	ctx := context.Background()
32 32
 
33
-	var elementSearcher inspectSearcher
33
+	var elementSearcher inspect.GetRefFunc
34 34
 	switch *inspectType {
35 35
 	case "container":
36 36
 		elementSearcher = cli.inspectContainers(ctx, *size)
... ...
@@ -40,22 +39,22 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
40 40
 		elementSearcher = cli.inspectAll(ctx, *size)
41 41
 	}
42 42
 
43
-	return cli.inspectElements(*tmplStr, cmd.Args(), elementSearcher)
43
+	return inspect.Inspect(cli.out, cmd.Args(), *tmplStr, elementSearcher)
44 44
 }
45 45
 
46
-func (cli *DockerCli) inspectContainers(ctx context.Context, getSize bool) inspectSearcher {
46
+func (cli *DockerCli) inspectContainers(ctx context.Context, getSize bool) inspect.GetRefFunc {
47 47
 	return func(ref string) (interface{}, []byte, error) {
48 48
 		return cli.client.ContainerInspectWithRaw(ctx, ref, getSize)
49 49
 	}
50 50
 }
51 51
 
52
-func (cli *DockerCli) inspectImages(ctx context.Context, getSize bool) inspectSearcher {
52
+func (cli *DockerCli) inspectImages(ctx context.Context, getSize bool) inspect.GetRefFunc {
53 53
 	return func(ref string) (interface{}, []byte, error) {
54 54
 		return cli.client.ImageInspectWithRaw(ctx, ref, getSize)
55 55
 	}
56 56
 }
57 57
 
58
-func (cli *DockerCli) inspectAll(ctx context.Context, getSize bool) inspectSearcher {
58
+func (cli *DockerCli) inspectAll(ctx context.Context, getSize bool) inspect.GetRefFunc {
59 59
 	return func(ref string) (interface{}, []byte, error) {
60 60
 		c, rawContainer, err := cli.client.ContainerInspectWithRaw(ctx, ref, getSize)
61 61
 		if err != nil {
... ...
@@ -75,55 +74,3 @@ func (cli *DockerCli) inspectAll(ctx context.Context, getSize bool) inspectSearc
75 75
 		return c, rawContainer, err
76 76
 	}
77 77
 }
78
-
79
-type inspectSearcher func(ref string) (interface{}, []byte, error)
80
-
81
-func (cli *DockerCli) inspectElements(tmplStr string, references []string, searchByReference inspectSearcher) error {
82
-	elementInspector, err := cli.newInspectorWithTemplate(tmplStr)
83
-	if err != nil {
84
-		return Cli.StatusError{StatusCode: 64, Status: err.Error()}
85
-	}
86
-
87
-	var inspectErr error
88
-	for _, ref := range references {
89
-		element, raw, err := searchByReference(ref)
90
-		if err != nil {
91
-			inspectErr = err
92
-			break
93
-		}
94
-
95
-		if err := elementInspector.Inspect(element, raw); err != nil {
96
-			inspectErr = err
97
-			break
98
-		}
99
-	}
100
-
101
-	if err := elementInspector.Flush(); err != nil {
102
-		cli.inspectErrorStatus(err)
103
-	}
104
-
105
-	if status := cli.inspectErrorStatus(inspectErr); status != 0 {
106
-		return Cli.StatusError{StatusCode: status}
107
-	}
108
-	return nil
109
-}
110
-
111
-func (cli *DockerCli) inspectErrorStatus(err error) (status int) {
112
-	if err != nil {
113
-		fmt.Fprintf(cli.err, "%s\n", err)
114
-		status = 1
115
-	}
116
-	return
117
-}
118
-
119
-func (cli *DockerCli) newInspectorWithTemplate(tmplStr string) (inspect.Inspector, error) {
120
-	elementInspector := inspect.NewIndentedInspector(cli.out)
121
-	if tmplStr != "" {
122
-		tmpl, err := templates.Parse(tmplStr)
123
-		if err != nil {
124
-			return nil, fmt.Errorf("Template parsing error: %s", err)
125
-		}
126
-		elementInspector = inspect.NewTemplateInspector(cli.out, tmpl)
127
-	}
128
-	return elementInspector, nil
129
-}
... ...
@@ -6,6 +6,10 @@ import (
6 6
 	"fmt"
7 7
 	"io"
8 8
 	"text/template"
9
+
10
+	"github.com/Sirupsen/logrus"
11
+	"github.com/docker/docker/cli"
12
+	"github.com/docker/docker/utils/templates"
9 13
 )
10 14
 
11 15
 // Inspector defines an interface to implement to process elements
... ...
@@ -30,6 +34,56 @@ func NewTemplateInspector(outputStream io.Writer, tmpl *template.Template) Inspe
30 30
 	}
31 31
 }
32 32
 
33
+// NewTemplateInspectorFromString creates a new TemplateInspector from a string
34
+// which is compiled into a template.
35
+func NewTemplateInspectorFromString(out io.Writer, tmplStr string) (Inspector, error) {
36
+	if tmplStr == "" {
37
+		return NewIndentedInspector(out), nil
38
+	}
39
+
40
+	tmpl, err := templates.Parse(tmplStr)
41
+	if err != nil {
42
+		return nil, fmt.Errorf("Template parsing error: %s", err)
43
+	}
44
+	return NewTemplateInspector(out, tmpl), nil
45
+}
46
+
47
+// GetRefFunc is a function which used by Inspect to fetch an object from a
48
+// reference
49
+type GetRefFunc func(ref string) (interface{}, []byte, error)
50
+
51
+// Inspect fetches objects by reference using GetRefFunc and writes the json
52
+// representation to the output writer.
53
+func Inspect(out io.Writer, references []string, tmplStr string, getRef GetRefFunc) error {
54
+	inspector, err := NewTemplateInspectorFromString(out, tmplStr)
55
+	if err != nil {
56
+		return cli.StatusError{StatusCode: 64, Status: err.Error()}
57
+	}
58
+
59
+	var inspectErr error
60
+	for _, ref := range references {
61
+		element, raw, err := getRef(ref)
62
+		if err != nil {
63
+			inspectErr = err
64
+			break
65
+		}
66
+
67
+		if err := inspector.Inspect(element, raw); err != nil {
68
+			inspectErr = err
69
+			break
70
+		}
71
+	}
72
+
73
+	if err := inspector.Flush(); err != nil {
74
+		logrus.Errorf("%s\n", err)
75
+	}
76
+
77
+	if inspectErr != nil {
78
+		return cli.StatusError{StatusCode: 1, Status: inspectErr.Error()}
79
+	}
80
+	return nil
81
+}
82
+
33 83
 // Inspect executes the inspect template.
34 84
 // It decodes the raw element into a map if the initial execution fails.
35 85
 // This allows docker cli to parse inspect structs injected with Swarm fields.
... ...
@@ -9,6 +9,7 @@ import (
9 9
 
10 10
 	"golang.org/x/net/context"
11 11
 
12
+	"github.com/docker/docker/api/client/inspect"
12 13
 	Cli "github.com/docker/docker/cli"
13 14
 	"github.com/docker/docker/opts"
14 15
 	flag "github.com/docker/docker/pkg/mflag"
... ...
@@ -249,7 +250,7 @@ func (cli *DockerCli) CmdNetworkInspect(args ...string) error {
249 249
 		return i, nil, err
250 250
 	}
251 251
 
252
-	return cli.inspectElements(*tmplStr, cmd.Args(), inspectSearcher)
252
+	return inspect.Inspect(cli.out, cmd.Args(), *tmplStr, inspectSearcher)
253 253
 }
254 254
 
255 255
 // Consolidates the ipam configuration as a group from different related configurations