Beispiel #1
0
func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, error) {
	options := &types.ContainerListOptions{
		All:     opts.all,
		Limit:   opts.last,
		Size:    opts.size,
		Filters: opts.filter.Value(),
	}

	if opts.nLatest && opts.last == -1 {
		options.Limit = 1
	}

	// 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
}
Beispiel #2
0
func buildContainerListOptions(opts *psOptions) (*types.ContainerListOptions, error) {
	options := &types.ContainerListOptions{
		All:     opts.all,
		Limit:   opts.last,
		Size:    opts.size,
		Filters: opts.filter.Value(),
	}

	if opts.nLatest && opts.last == -1 {
		options.Limit = 1
	}

	tmpl, err := templates.Parse(opts.format)

	if err != nil {
		return nil, err
	}

	optionsProcessor := listOptionsProcessor{}
	// 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, optionsProcessor); err != nil {
		return nil, err
	}
	// At the moment all we need is to capture .Size for preprocessor
	options.Size = opts.size || optionsProcessor["size"]

	return options, nil
}
Beispiel #3
0
func (c *Context) parseFormat() (*template.Template, error) {
	tmpl, err := templates.Parse(c.finalFormat)
	if err != nil {
		return tmpl, fmt.Errorf("Template parsing error: %v\n", err)
	}
	return tmpl, err
}
Beispiel #4
0
func (c *Context) parseFormat() (*template.Template, error) {
	tmpl, err := templates.Parse(c.finalFormat)
	if err != nil {
		c.buffer.WriteString(fmt.Sprintf("Template parsing error: %v\n", err))
		c.buffer.WriteTo(c.Output)
	}
	return tmpl, err
}
Beispiel #5
0
func formatInfo(dockerCli *client.DockerCli, info types.Info, format string) error {
	tmpl, err := templates.Parse(format)
	if err != nil {
		return cli.StatusError{StatusCode: 64,
			Status: "Template parsing error: " + err.Error()}
	}
	err = tmpl.Execute(dockerCli.Out(), info)
	dockerCli.Out().Write([]byte{'\n'})
	return err
}
Beispiel #6
0
func runVersion(dockerCli *command.DockerCli, opts *versionOptions) error {
	ctx := context.Background()

	templateFormat := versionTemplate
	if opts.format != "" {
		templateFormat = opts.format
	}

	tmpl, err := templates.Parse(templateFormat)
	if err != nil {
		return cli.StatusError{StatusCode: 64,
			Status: "Template parsing error: " + err.Error()}
	}

	APIVersion := dockerCli.Client().ClientVersion()
	if defaultAPIVersion := dockerCli.DefaultVersion(); APIVersion != defaultAPIVersion {
		APIVersion = fmt.Sprintf("%s (downgraded from %s)", APIVersion, defaultAPIVersion)
	}

	vd := types.VersionResponse{
		Client: &types.Version{
			Version:    dockerversion.Version,
			APIVersion: APIVersion,
			GoVersion:  runtime.Version(),
			GitCommit:  dockerversion.GitCommit,
			BuildTime:  dockerversion.BuildTime,
			Os:         runtime.GOOS,
			Arch:       runtime.GOARCH,
		},
	}

	serverVersion, err := dockerCli.Client().ServerVersion(ctx)
	if err == nil {
		vd.Server = &serverVersion
	}

	// first we need to make BuildTime more human friendly
	t, errTime := time.Parse(time.RFC3339Nano, vd.Client.BuildTime)
	if errTime == nil {
		vd.Client.BuildTime = t.Format(time.ANSIC)
	}

	if vd.ServerOK() {
		t, errTime = time.Parse(time.RFC3339Nano, vd.Server.BuildTime)
		if errTime == nil {
			vd.Server.BuildTime = t.Format(time.ANSIC)
		}
	}

	if err2 := tmpl.Execute(dockerCli.Out(), vd); err2 != nil && err == nil {
		err = err2
	}
	dockerCli.Out().Write([]byte{'\n'})
	return err
}
Beispiel #7
0
// CmdVersion shows Docker version information.
//
// Available version information is shown for: client Docker version, client API version, client Go version, client Git commit, client OS/Arch, server Docker version, server API version, server Go version, server Git commit, and server OS/Arch.
//
// Usage: docker version
func (cli *DockerCli) CmdVersion(args ...string) (err error) {
	cmd := Cli.Subcmd("version", nil, Cli.DockerCommands["version"].Description, true)
	tmplStr := cmd.String([]string{"f", "#format", "-format"}, "", "Format the output using the given go template")
	cmd.Require(flag.Exact, 0)

	cmd.ParseFlags(args, true)

	templateFormat := versionTemplate
	if *tmplStr != "" {
		templateFormat = *tmplStr
	}

	var tmpl *template.Template
	if tmpl, err = templates.Parse(templateFormat); err != nil {
		return Cli.StatusError{StatusCode: 64,
			Status: "Template parsing error: " + err.Error()}
	}

	vd := types.VersionResponse{
		Client: &types.Version{
			Version:      dockerversion.Version,
			APIVersion:   cli.client.ClientVersion(),
			GoVersion:    runtime.Version(),
			GitCommit:    dockerversion.GitCommit,
			BuildTime:    dockerversion.BuildTime,
			Os:           runtime.GOOS,
			Arch:         runtime.GOARCH,
			Experimental: utils.ExperimentalBuild(),
		},
	}

	serverVersion, err := cli.client.ServerVersion()
	if err == nil {
		vd.Server = &serverVersion
	}

	// first we need to make BuildTime more human friendly
	t, errTime := time.Parse(time.RFC3339Nano, vd.Client.BuildTime)
	if errTime == nil {
		vd.Client.BuildTime = t.Format(time.ANSIC)
	}

	if vd.ServerOK() {
		t, errTime = time.Parse(time.RFC3339Nano, vd.Server.BuildTime)
		if errTime == nil {
			vd.Server.BuildTime = t.Format(time.ANSIC)
		}
	}

	if err2 := tmpl.Execute(cli.out, vd); err2 != nil && err == nil {
		err = err2
	}
	cli.out.Write([]byte{'\n'})
	return err
}
Beispiel #8
0
// 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
}
Beispiel #9
0
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
}
Beispiel #10
0
func makeTemplate(format string) (*template.Template, error) {
	if format == "" {
		return nil, nil
	}
	tmpl, err := templates.Parse(format)
	if err != nil {
		return tmpl, err
	}
	// we execute the template for an empty message, so as to validate
	// a bad template like "{{.badFieldString}}"
	return tmpl, tmpl.Execute(ioutil.Discard, &eventtypes.Message{})
}
Beispiel #11
0
func TestTemplateInspectorEmpty(t *testing.T) {
	b := new(bytes.Buffer)
	tmpl, err := templates.Parse("{{.DNS}}")
	if err != nil {
		t.Fatal(err)
	}
	i := NewTemplateInspector(b, tmpl)

	if err := i.Flush(); err != nil {
		t.Fatal(err)
	}
	if b.String() != "\n" {
		t.Fatalf("Expected `\\n`, got `%s`", b.String())
	}
}
Beispiel #12
0
func TestTemplateInspectorRawFallbackError(t *testing.T) {
	b := new(bytes.Buffer)
	tmpl, err := templates.Parse("{{.Dns}}")
	if err != nil {
		t.Fatal(err)
	}
	i := NewTemplateInspector(b, tmpl)
	err = i.Inspect(testElement{"0.0.0.0"}, []byte(`{"Foo": "0.0.0.0"}`))
	if err == nil {
		t.Fatal("Expected error got nil")
	}

	if !strings.HasPrefix(err.Error(), "Template parsing error") {
		t.Fatalf("Expected template error, got %v", err)
	}
}
Beispiel #13
0
func TestTemplateInspectorRawFallback(t *testing.T) {
	b := new(bytes.Buffer)
	tmpl, err := templates.Parse("{{.Dns}}")
	if err != nil {
		t.Fatal(err)
	}
	i := NewTemplateInspector(b, tmpl)
	if err := i.Inspect(testElement{"0.0.0.0"}, []byte(`{"Dns": "0.0.0.0"}`)); err != nil {
		t.Fatal(err)
	}

	if err := i.Flush(); err != nil {
		t.Fatal(err)
	}
	if b.String() != "0.0.0.0\n" {
		t.Fatalf("Expected `0.0.0.0\\n`, got `%s`", b.String())
	}
}
Beispiel #14
0
func TestTemplateInspectorDefault(t *testing.T) {
	b := new(bytes.Buffer)
	tmpl, err := templates.Parse("{{.DNS}}")
	if err != nil {
		t.Fatal(err)
	}
	i := NewTemplateInspector(b, tmpl)
	if err := i.Inspect(testElement{"0.0.0.0"}, nil); err != nil {
		t.Fatal(err)
	}

	if err := i.Flush(); err != nil {
		t.Fatal(err)
	}
	if b.String() != "0.0.0.0\n" {
		t.Fatalf("Expected `0.0.0.0\\n`, got `%s`", b.String())
	}
}
Beispiel #15
0
func runPs(dockerCli *client.DockerCli, opts *psOptions) error {
	ctx := context.Background()

	if opts.nLatest && opts.last == -1 {
		opts.last = 1
	}

	containerFilterArgs := filters.NewArgs()
	for _, f := range opts.filter {
		var err error
		containerFilterArgs, err = filters.ParseFlag(f, containerFilterArgs)
		if err != nil {
			return err
		}
	}

	options := types.ContainerListOptions{
		All:    opts.all,
		Limit:  opts.last,
		Size:   opts.size,
		Filter: containerFilterArgs,
	}

	pre := &preProcessor{opts: &options}
	tmpl, err := templates.Parse(opts.format)

	if err != nil {
		return err
	}

	_ = tmpl.Execute(ioutil.Discard, pre)

	containers, err := dockerCli.Client().ContainerList(ctx, options)
	if err != nil {
		return err
	}

	f := opts.format
	if len(f) == 0 {
		if len(dockerCli.PsFormat()) > 0 && !opts.quiet {
			f = dockerCli.PsFormat()
		} else {
			f = "table"
		}
	}

	psCtx := formatter.ContainerContext{
		Context: formatter.Context{
			Output: dockerCli.Out(),
			Format: f,
			Quiet:  opts.quiet,
			Trunc:  !opts.noTrunc,
		},
		Size:       opts.size,
		Containers: containers,
	}

	psCtx.Write()

	return nil
}
Beispiel #16
0
// 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)")
		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,
		Size:   *size,
		Filter: psFilterArgs,
	}

	pre := &preProcessor{opts: &options}
	tmpl, err := templates.Parse(*format)
	if err != nil {
		return err
	}

	_ = tmpl.Execute(ioutil.Discard, pre)

	containers, err := cli.client.ContainerList(context.Background(), 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
}