浏览代码

Refactor cli inspector to support new inspects.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Daniel Nephin 9 年之前
父节点
当前提交
6bc3e23f65
共有 3 个文件被更改,包括 61 次插入59 次删除
  1. 5 58
      api/client/inspect.go
  2. 54 0
      api/client/inspect/inspector.go
  3. 2 1
      api/client/network.go

+ 5 - 58
api/client/inspect.go

@@ -8,7 +8,6 @@ import (
 	"github.com/docker/docker/api/client/inspect"
 	Cli "github.com/docker/docker/cli"
 	flag "github.com/docker/docker/pkg/mflag"
-	"github.com/docker/docker/utils/templates"
 	"github.com/docker/engine-api/client"
 )
 
@@ -30,7 +29,7 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
 
 	ctx := context.Background()
 
-	var elementSearcher inspectSearcher
+	var elementSearcher inspect.GetRefFunc
 	switch *inspectType {
 	case "container":
 		elementSearcher = cli.inspectContainers(ctx, *size)
@@ -40,22 +39,22 @@ func (cli *DockerCli) CmdInspect(args ...string) error {
 		elementSearcher = cli.inspectAll(ctx, *size)
 	}
 
-	return cli.inspectElements(*tmplStr, cmd.Args(), elementSearcher)
+	return inspect.Inspect(cli.out, cmd.Args(), *tmplStr, elementSearcher)
 }
 
-func (cli *DockerCli) inspectContainers(ctx context.Context, getSize bool) inspectSearcher {
+func (cli *DockerCli) inspectContainers(ctx context.Context, getSize bool) inspect.GetRefFunc {
 	return func(ref string) (interface{}, []byte, error) {
 		return cli.client.ContainerInspectWithRaw(ctx, ref, getSize)
 	}
 }
 
-func (cli *DockerCli) inspectImages(ctx context.Context, getSize bool) inspectSearcher {
+func (cli *DockerCli) inspectImages(ctx context.Context, getSize bool) inspect.GetRefFunc {
 	return func(ref string) (interface{}, []byte, error) {
 		return cli.client.ImageInspectWithRaw(ctx, ref, getSize)
 	}
 }
 
-func (cli *DockerCli) inspectAll(ctx context.Context, getSize bool) inspectSearcher {
+func (cli *DockerCli) inspectAll(ctx context.Context, getSize bool) inspect.GetRefFunc {
 	return func(ref string) (interface{}, []byte, error) {
 		c, rawContainer, err := cli.client.ContainerInspectWithRaw(ctx, ref, getSize)
 		if err != nil {
@@ -75,55 +74,3 @@ func (cli *DockerCli) inspectAll(ctx context.Context, getSize bool) inspectSearc
 		return c, rawContainer, err
 	}
 }
-
-type inspectSearcher func(ref string) (interface{}, []byte, error)
-
-func (cli *DockerCli) inspectElements(tmplStr string, references []string, searchByReference inspectSearcher) error {
-	elementInspector, err := cli.newInspectorWithTemplate(tmplStr)
-	if err != nil {
-		return Cli.StatusError{StatusCode: 64, Status: err.Error()}
-	}
-
-	var inspectErr error
-	for _, ref := range references {
-		element, raw, err := searchByReference(ref)
-		if err != nil {
-			inspectErr = err
-			break
-		}
-
-		if err := elementInspector.Inspect(element, raw); err != nil {
-			inspectErr = err
-			break
-		}
-	}
-
-	if err := elementInspector.Flush(); err != nil {
-		cli.inspectErrorStatus(err)
-	}
-
-	if status := cli.inspectErrorStatus(inspectErr); status != 0 {
-		return Cli.StatusError{StatusCode: status}
-	}
-	return nil
-}
-
-func (cli *DockerCli) inspectErrorStatus(err error) (status int) {
-	if err != nil {
-		fmt.Fprintf(cli.err, "%s\n", err)
-		status = 1
-	}
-	return
-}
-
-func (cli *DockerCli) newInspectorWithTemplate(tmplStr string) (inspect.Inspector, error) {
-	elementInspector := inspect.NewIndentedInspector(cli.out)
-	if tmplStr != "" {
-		tmpl, err := templates.Parse(tmplStr)
-		if err != nil {
-			return nil, fmt.Errorf("Template parsing error: %s", err)
-		}
-		elementInspector = inspect.NewTemplateInspector(cli.out, tmpl)
-	}
-	return elementInspector, nil
-}

+ 54 - 0
api/client/inspect/inspector.go

@@ -6,6 +6,10 @@ import (
 	"fmt"
 	"io"
 	"text/template"
+
+	"github.com/Sirupsen/logrus"
+	"github.com/docker/docker/cli"
+	"github.com/docker/docker/utils/templates"
 )
 
 // Inspector defines an interface to implement to process elements
@@ -30,6 +34,56 @@ func NewTemplateInspector(outputStream io.Writer, tmpl *template.Template) Inspe
 	}
 }
 
+// NewTemplateInspectorFromString creates a new TemplateInspector from a string
+// which is compiled into a template.
+func NewTemplateInspectorFromString(out io.Writer, tmplStr string) (Inspector, error) {
+	if tmplStr == "" {
+		return NewIndentedInspector(out), nil
+	}
+
+	tmpl, err := templates.Parse(tmplStr)
+	if err != nil {
+		return nil, fmt.Errorf("Template parsing error: %s", err)
+	}
+	return NewTemplateInspector(out, tmpl), nil
+}
+
+// GetRefFunc is a function which used by Inspect to fetch an object from a
+// reference
+type GetRefFunc func(ref string) (interface{}, []byte, error)
+
+// Inspect fetches objects by reference using GetRefFunc and writes the json
+// representation to the output writer.
+func Inspect(out io.Writer, references []string, tmplStr string, getRef GetRefFunc) error {
+	inspector, err := NewTemplateInspectorFromString(out, tmplStr)
+	if err != nil {
+		return cli.StatusError{StatusCode: 64, Status: err.Error()}
+	}
+
+	var inspectErr error
+	for _, ref := range references {
+		element, raw, err := getRef(ref)
+		if err != nil {
+			inspectErr = err
+			break
+		}
+
+		if err := inspector.Inspect(element, raw); err != nil {
+			inspectErr = err
+			break
+		}
+	}
+
+	if err := inspector.Flush(); err != nil {
+		logrus.Errorf("%s\n", err)
+	}
+
+	if inspectErr != nil {
+		return cli.StatusError{StatusCode: 1, Status: inspectErr.Error()}
+	}
+	return nil
+}
+
 // Inspect executes the inspect template.
 // It decodes the raw element into a map if the initial execution fails.
 // This allows docker cli to parse inspect structs injected with Swarm fields.

+ 2 - 1
api/client/network.go

@@ -9,6 +9,7 @@ import (
 
 	"golang.org/x/net/context"
 
+	"github.com/docker/docker/api/client/inspect"
 	Cli "github.com/docker/docker/cli"
 	"github.com/docker/docker/opts"
 	flag "github.com/docker/docker/pkg/mflag"
@@ -249,7 +250,7 @@ func (cli *DockerCli) CmdNetworkInspect(args ...string) error {
 		return i, nil, err
 	}
 
-	return cli.inspectElements(*tmplStr, cmd.Args(), inspectSearcher)
+	return inspect.Inspect(cli.out, cmd.Args(), *tmplStr, inspectSearcher)
 }
 
 // Consolidates the ipam configuration as a group from different related configurations