Browse code

Merge pull request #35744 from ndeloof/35702

closes #35702 introduce « exec_die » event

Vincent Demeester authored on 2018/01/20 08:03:50
Showing 6 changed files
... ...
@@ -6944,7 +6944,7 @@ paths:
6944 6944
 
6945 6945
         Various objects within Docker report events when something happens to them.
6946 6946
 
6947
-        Containers report these events: `attach`, `commit`, `copy`, `create`, `destroy`, `detach`, `die`, `exec_create`, `exec_detach`, `exec_start`, `export`, `health_status`, `kill`, `oom`, `pause`, `rename`, `resize`, `restart`, `start`, `stop`, `top`, `unpause`, and `update`
6947
+        Containers report these events: `attach`, `commit`, `copy`, `create`, `destroy`, `detach`, `die`, `exec_create`, `exec_detach`, `exec_start`, `exec_die`, `export`, `health_status`, `kill`, `oom`, `pause`, `rename`, `resize`, `restart`, `start`, `stop`, `top`, `unpause`, and `update`
6948 6948
 
6949 6949
         Images report these events: `delete`, `import`, `load`, `pull`, `push`, `save`, `tag`, and `untag`
6950 6950
 
... ...
@@ -139,7 +139,10 @@ func (d *Daemon) ContainerExecCreate(name string, config *types.ExecConfig) (str
139 139
 
140 140
 	d.registerExecCommand(cntr, execConfig)
141 141
 
142
-	d.LogContainerEvent(cntr, "exec_create: "+execConfig.Entrypoint+" "+strings.Join(execConfig.Args, " "))
142
+	attributes := map[string]string{
143
+		"execID": execConfig.ID,
144
+	}
145
+	d.LogContainerEventWithAttributes(cntr, "exec_create: "+execConfig.Entrypoint+" "+strings.Join(execConfig.Args, " "), attributes)
143 146
 
144 147
 	return execConfig.ID, nil
145 148
 }
... ...
@@ -174,7 +177,10 @@ func (d *Daemon) ContainerExecStart(ctx context.Context, name string, stdin io.R
174 174
 
175 175
 	c := d.containers.Get(ec.ContainerID)
176 176
 	logrus.Debugf("starting exec command %s in container %s", ec.ID, c.ID)
177
-	d.LogContainerEvent(c, "exec_start: "+ec.Entrypoint+" "+strings.Join(ec.Args, " "))
177
+	attributes := map[string]string{
178
+		"execID": ec.ID,
179
+	}
180
+	d.LogContainerEventWithAttributes(c, "exec_start: "+ec.Entrypoint+" "+strings.Join(ec.Args, " "), attributes)
178 181
 
179 182
 	defer func() {
180 183
 		if err != nil {
... ...
@@ -270,7 +276,10 @@ func (d *Daemon) ContainerExecStart(ctx context.Context, name string, stdin io.R
270 270
 			if _, ok := err.(term.EscapeError); !ok {
271 271
 				return errdefs.System(errors.Wrap(err, "exec attach failed"))
272 272
 			}
273
-			d.LogContainerEvent(c, "exec_detach")
273
+			attributes := map[string]string{
274
+				"execID": ec.ID,
275
+			}
276
+			d.LogContainerEventWithAttributes(c, "exec_detach", attributes)
274 277
 		}
275 278
 	}
276 279
 	return nil
... ...
@@ -89,7 +89,10 @@ func (p *cmdProbe) run(ctx context.Context, d *Daemon, cntr *container.Container
89 89
 	execConfig.Env = container.ReplaceOrAppendEnvValues(cntr.CreateDaemonEnvironment(execConfig.Tty, linkedEnv), execConfig.Env)
90 90
 
91 91
 	d.registerExecCommand(cntr, execConfig)
92
-	d.LogContainerEvent(cntr, "exec_create: "+execConfig.Entrypoint+" "+strings.Join(execConfig.Args, " "))
92
+	attributes := map[string]string{
93
+		"execID": execConfig.ID,
94
+	}
95
+	d.LogContainerEventWithAttributes(cntr, "exec_create: "+execConfig.Entrypoint+" "+strings.Join(execConfig.Args, " "), attributes)
93 96
 
94 97
 	output := &limitedBuffer{}
95 98
 	err = d.ContainerExecStart(ctx, execConfig.ID, nil, output, output)
... ...
@@ -128,6 +128,11 @@ func (daemon *Daemon) ProcessEvent(id string, e libcontainerd.EventType, ei libc
128 128
 			// remove the exec command from the container's store only and not the
129 129
 			// daemon's store so that the exec command can be inspected.
130 130
 			c.ExecCommands.Delete(execConfig.ID, execConfig.Pid)
131
+			attributes := map[string]string{
132
+				"execID":   execConfig.ID,
133
+				"exitCode": strconv.Itoa(ec),
134
+			}
135
+			daemon.LogContainerEventWithAttributes(c, "exec_die", attributes)
131 136
 		} else {
132 137
 			logrus.WithFields(logrus.Fields{
133 138
 				"container": c.ID,
... ...
@@ -17,6 +17,8 @@ keywords: "API, Docker, rcli, REST, documentation"
17 17
 
18 18
 [Docker Engine API v1.36](https://docs.docker.com/engine/api/v1.36/) documentation
19 19
 
20
+* `Get /events` now return `exec_die` event when an exec process terminates.  
21
+
20 22
 
21 23
 ## v1.35 API changes
22 24
 
23 25
new file mode 100644
... ...
@@ -0,0 +1,74 @@
0
+package system
1
+
2
+import (
3
+	"context"
4
+	"testing"
5
+
6
+	"time"
7
+
8
+	"github.com/docker/docker/api/types"
9
+	"github.com/docker/docker/api/types/container"
10
+	"github.com/docker/docker/api/types/filters"
11
+	"github.com/docker/docker/api/types/network"
12
+	"github.com/docker/docker/api/types/strslice"
13
+	"github.com/docker/docker/integration/util/request"
14
+	"github.com/stretchr/testify/require"
15
+)
16
+
17
+func TestEvents(t *testing.T) {
18
+	defer setupTest(t)()
19
+	ctx := context.Background()
20
+	client := request.NewAPIClient(t)
21
+
22
+	container, err := client.ContainerCreate(ctx,
23
+		&container.Config{
24
+			Image:      "busybox",
25
+			Tty:        true,
26
+			WorkingDir: "/root",
27
+			Cmd:        strslice.StrSlice([]string{"top"}),
28
+		},
29
+		&container.HostConfig{},
30
+		&network.NetworkingConfig{},
31
+		"foo",
32
+	)
33
+	require.NoError(t, err)
34
+	err = client.ContainerStart(ctx, container.ID, types.ContainerStartOptions{})
35
+	require.NoError(t, err)
36
+
37
+	id, err := client.ContainerExecCreate(ctx, container.ID,
38
+		types.ExecConfig{
39
+			Cmd: strslice.StrSlice([]string{"echo", "hello"}),
40
+		},
41
+	)
42
+	require.NoError(t, err)
43
+
44
+	filters := filters.NewArgs(
45
+		filters.Arg("container", container.ID),
46
+		filters.Arg("event", "exec_die"),
47
+	)
48
+	msg, errors := client.Events(ctx, types.EventsOptions{
49
+		Filters: filters,
50
+	})
51
+
52
+	err = client.ContainerExecStart(ctx, id.ID,
53
+		types.ExecStartCheck{
54
+			Detach: true,
55
+			Tty:    false,
56
+		},
57
+	)
58
+	require.NoError(t, err)
59
+
60
+	select {
61
+	case m := <-msg:
62
+		require.Equal(t, m.Type, "container")
63
+		require.Equal(t, m.Actor.ID, container.ID)
64
+		require.Equal(t, m.Action, "exec_die")
65
+		require.Equal(t, m.Actor.Attributes["execID"], id.ID)
66
+		require.Equal(t, m.Actor.Attributes["exitCode"], "0")
67
+	case err = <-errors:
68
+		t.Fatal(err)
69
+	case <-time.After(time.Second * 3):
70
+		t.Fatal("timeout hit")
71
+	}
72
+
73
+}