Skip to content

Commit

Permalink
cli/command/system: fix "docker events" not supporting --format=json
Browse files Browse the repository at this point in the history
Before this patch:

    docker events --format=json
    json
    json
    json
    ^C

With this patch:

    docker events --format=json
    {"status":"create","id":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","from":"hello-world","Type":"container","Action":"create","Actor":{"ID":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","Attributes":{"image":"hello-world","name":"dreamy_goldstine"}},"scope":"local","time":1693168508,"timeNano":1693168508190136885}
    {"status":"attach","id":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","from":"hello-world","Type":"container","Action":"attach","Actor":{"ID":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","Attributes":{"image":"hello-world","name":"dreamy_goldstine"}},"scope":"local","time":1693168508,"timeNano":1693168508192851593}
    {"Type":"network","Action":"connect","Actor":{"ID":"c54920dd5074a73e28bea62007e0334d81cc040a90372be311cf16806403d350","Attributes":{"container":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","name":"bridge","type":"bridge"}},"scope":"local","time":1693168508,"timeNano":1693168508212398802}
    {"status":"start","id":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","from":"hello-world","Type":"container","Action":"start","Actor":{"ID":"4ac3bba8abd68961e627540fed81ad16d55b88e45629d7cdb792126d09b6488d","Attributes":{"image":"hello-world","name":"dreamy_goldstine"}},"scope":"local","time":1693168508,"timeNano":1693168508312969843}
    ^C

Signed-off-by: Sebastiaan van Stijn <[email protected]>
  • Loading branch information
thaJeztah committed Aug 27, 2023
1 parent 6f80b0b commit 3a6f3d4
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 9 deletions.
17 changes: 17 additions & 0 deletions cli/command/system/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package system

import (
"context"
"io"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/client"
)

Expand All @@ -12,6 +14,7 @@ type fakeClient struct {

version string
serverVersion func(ctx context.Context) (types.Version, error)
events []events.Message
}

func (cli *fakeClient) ServerVersion(ctx context.Context) (types.Version, error) {
Expand All @@ -21,3 +24,17 @@ func (cli *fakeClient) ServerVersion(ctx context.Context) (types.Version, error)
func (cli *fakeClient) ClientVersion() string {
return cli.version
}

func (cli *fakeClient) Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error) {
messages := make(chan events.Message)
errs := make(chan error, 1)
go func() {
for _, msg := range cli.events {
messages <- msg
}
errs <- io.EOF
close(messages)
close(errs)
}()
return messages, errs
}
20 changes: 11 additions & 9 deletions cli/command/system/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/completion"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/cli/opts"
"github.com/docker/cli/templates"
"github.com/docker/docker/api/types"
Expand All @@ -33,7 +34,7 @@ func NewEventsCommand(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "events [OPTIONS]",
Short: "Get real time events from the server",
Args: cli.NoArgs,
// Args: cli.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return runEvents(dockerCli, &options)
},
Expand All @@ -60,14 +61,12 @@ func runEvents(dockerCli command.Cli, options *eventsOptions) error {
Status: "Error parsing format: " + err.Error(),
}
}
eventOptions := types.EventsOptions{
ctx, cancel := context.WithCancel(context.Background())
events, errs := dockerCli.Client().Events(ctx, types.EventsOptions{
Since: options.since,
Until: options.until,
Filters: options.filter.Value(),
}

ctx, cancel := context.WithCancel(context.Background())
events, errs := dockerCli.Client().Events(ctx, eventOptions)
})
defer cancel()

out := dockerCli.Out()
Expand Down Expand Up @@ -96,15 +95,18 @@ func handleEvent(out io.Writer, event eventtypes.Message, tmpl *template.Templat
}

func makeTemplate(format string) (*template.Template, error) {
if format == "" {
switch format {
case "":
return nil, nil
case formatter.JSONFormatKey:
format = formatter.JSONFormat
}
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}}"
// execute the template on an empty message to validate a bad
// template like "{{.badFieldString}}"
return tmpl, tmpl.Execute(io.Discard, &eventtypes.Message{})
}

Expand Down
67 changes: 67 additions & 0 deletions cli/command/system/events_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package system

import (
"fmt"
"strings"
"testing"
"time"

"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/events"
"gotest.tools/v3/assert"
"gotest.tools/v3/golden"
)

func TestEventsFormat(t *testing.T) {
var evts []events.Message
for i, action := range []string{"create", "start", "attach", "die"} {
evts = append(evts, events.Message{
Status: action,
ID: "abc123",
From: "ubuntu:latest",
Type: events.ContainerEventType,
Action: action,
Actor: events.Actor{
ID: "abc123",
Attributes: map[string]string{"image": "ubuntu:latest"},
},
Scope: "local",
Time: int64(time.Second) * int64(i+1),
TimeNano: int64(time.Second) * int64(i+1),
})
}
tests := []struct {
name, format string
}{
{
name: "default",
},
{
name: "json",
format: "json",
},
{
name: "json template",
format: "{{ json . }}",
},
{
name: "json action",
format: "{{ json .Action }}",
},
}

for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{events: evts})
cmd := NewEventsCommand(cli)
if tc.format != "" {
cmd.Flags().Set("format", tc.format)
}
assert.Check(t, cmd.Execute())
out := cli.OutBuffer().String()
assert.Check(t, golden.String(out, fmt.Sprintf("docker-events-%s.golden", strings.ReplaceAll(tc.name, " ", "-"))))
cli.OutBuffer().Reset()
})
}
}
4 changes: 4 additions & 0 deletions cli/command/system/testdata/docker-events-default.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1970-01-01T01:00:01.000000000+01:00 container create abc123 (image=ubuntu:latest)
1970-01-01T01:00:02.000000000+01:00 container start abc123 (image=ubuntu:latest)
1970-01-01T01:00:03.000000000+01:00 container attach abc123 (image=ubuntu:latest)
1970-01-01T01:00:04.000000000+01:00 container die abc123 (image=ubuntu:latest)
4 changes: 4 additions & 0 deletions cli/command/system/testdata/docker-events-json-action.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"create"
"start"
"attach"
"die"
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{"status":"create","id":"abc123","from":"ubuntu:latest","Type":"container","Action":"create","Actor":{"ID":"abc123","Attributes":{"image":"ubuntu:latest"}},"scope":"local","time":1000000000,"timeNano":1000000000}
{"status":"start","id":"abc123","from":"ubuntu:latest","Type":"container","Action":"start","Actor":{"ID":"abc123","Attributes":{"image":"ubuntu:latest"}},"scope":"local","time":2000000000,"timeNano":2000000000}
{"status":"attach","id":"abc123","from":"ubuntu:latest","Type":"container","Action":"attach","Actor":{"ID":"abc123","Attributes":{"image":"ubuntu:latest"}},"scope":"local","time":3000000000,"timeNano":3000000000}
{"status":"die","id":"abc123","from":"ubuntu:latest","Type":"container","Action":"die","Actor":{"ID":"abc123","Attributes":{"image":"ubuntu:latest"}},"scope":"local","time":4000000000,"timeNano":4000000000}
4 changes: 4 additions & 0 deletions cli/command/system/testdata/docker-events-json.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{"status":"create","id":"abc123","from":"ubuntu:latest","Type":"container","Action":"create","Actor":{"ID":"abc123","Attributes":{"image":"ubuntu:latest"}},"scope":"local","time":1000000000,"timeNano":1000000000}
{"status":"start","id":"abc123","from":"ubuntu:latest","Type":"container","Action":"start","Actor":{"ID":"abc123","Attributes":{"image":"ubuntu:latest"}},"scope":"local","time":2000000000,"timeNano":2000000000}
{"status":"attach","id":"abc123","from":"ubuntu:latest","Type":"container","Action":"attach","Actor":{"ID":"abc123","Attributes":{"image":"ubuntu:latest"}},"scope":"local","time":3000000000,"timeNano":3000000000}
{"status":"die","id":"abc123","from":"ubuntu:latest","Type":"container","Action":"die","Actor":{"ID":"abc123","Attributes":{"image":"ubuntu:latest"}},"scope":"local","time":4000000000,"timeNano":4000000000}

0 comments on commit 3a6f3d4

Please sign in to comment.