Browse code

Merge pull request #10663 from brahmaroutu/events_filterbyname_10645

filter events by container name

moxiegirl authored on 2015/03/11 13:16:39
Showing 3 changed files
... ...
@@ -992,6 +992,12 @@ You'll need two shells for this example.
992 992
     $ sudo docker events --filter 'container=7805c1d35632' --filter 'event=stop'
993 993
     2014-09-03T15:49:29.999999999Z07:00 7805c1d35632: (from redis:2.8) stop
994 994
 
995
+    $ sudo docker events --filter 'container=container_1' --filter 'container=container_2'
996
+    2014-09-03T15:49:29.999999999Z07:00 4386fb97867d: (from ubuntu-1:14.04) die
997
+    2014-05-10T17:42:14.999999999Z07:00 4386fb97867d: (from ubuntu-1:14.04) stop
998
+    2014-05-10T17:42:14.999999999Z07:00 7805c1d35632: (from redis:2.8) die
999
+    2014-09-03T15:49:29.999999999Z07:00 7805c1d35632: (from redis:2.8) stop
1000
+
995 1001
 ## exec
996 1002
 
997 1003
     Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
... ...
@@ -1,7 +1,9 @@
1 1
 package events
2 2
 
3 3
 import (
4
+	"bytes"
4 5
 	"encoding/json"
6
+	"io"
5 7
 	"strings"
6 8
 	"sync"
7 9
 	"time"
... ...
@@ -123,7 +125,13 @@ func writeEvent(job *engine.Job, event *utils.JSONMessage, eventFilters filters.
123 123
 		return true
124 124
 	}
125 125
 
126
-	if isFiltered(event.Status, eventFilters["event"]) || isFiltered(event.From, eventFilters["image"]) || isFiltered(event.ID, eventFilters["container"]) {
126
+	//incoming container filter can be name,id or partial id, convert and replace as a full container id
127
+	for i, cn := range eventFilters["container"] {
128
+		eventFilters["container"][i] = GetContainerId(job.Eng, cn)
129
+	}
130
+
131
+	if isFiltered(event.Status, eventFilters["event"]) || isFiltered(event.From, eventFilters["image"]) ||
132
+		isFiltered(event.ID, eventFilters["container"]) {
127 133
 		return nil
128 134
 	}
129 135
 
... ...
@@ -203,3 +211,20 @@ func (e *Events) unsubscribe(l listener) bool {
203 203
 	e.mu.Unlock()
204 204
 	return false
205 205
 }
206
+
207
+func GetContainerId(eng *engine.Engine, name string) string {
208
+	var buf bytes.Buffer
209
+	job := eng.Job("container_inspect", name)
210
+
211
+	var outStream io.Writer
212
+
213
+	outStream = &buf
214
+	job.Stdout.Set(outStream)
215
+
216
+	if err := job.Run(); err != nil {
217
+		return ""
218
+	}
219
+	var out struct{ ID string }
220
+	json.NewDecoder(&buf).Decode(&out)
221
+	return out.ID
222
+}
... ...
@@ -258,6 +258,7 @@ func TestEventsFilterImageName(t *testing.T) {
258 258
 		t.Fatal(out, err)
259 259
 	}
260 260
 	container1 := stripTrailingCharacters(out)
261
+
261 262
 	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_2", "-d", "busybox", "true"))
262 263
 	if err != nil {
263 264
 		t.Fatal(out, err)
... ...
@@ -290,5 +291,98 @@ func TestEventsFilterImageName(t *testing.T) {
290 290
 	}
291 291
 
292 292
 	logDone("events - filters using image")
293
+}
294
+
295
+func TestEventsFilterContainerID(t *testing.T) {
296
+	since := time.Now().Unix()
297
+	defer deleteAllContainers()
298
+
299
+	out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "busybox", "true"))
300
+	if err != nil {
301
+		t.Fatal(out, err)
302
+	}
303
+	container1 := stripTrailingCharacters(out)
304
+
305
+	out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "busybox", "true"))
306
+	if err != nil {
307
+		t.Fatal(out, err)
308
+	}
309
+	container2 := stripTrailingCharacters(out)
310
+
311
+	for _, s := range []string{container1, container2, container1[:12], container2[:12]} {
312
+		eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", time.Now().Unix()), "--filter", fmt.Sprintf("container=%s", s))
313
+		out, _, err := runCommandWithOutput(eventsCmd)
314
+		if err != nil {
315
+			t.Fatalf("Failed to get events, error: %s(%s)", err, out)
316
+		}
317
+		events := strings.Split(out, "\n")
318
+		events = events[:len(events)-1]
319
+		if len(events) == 0 || len(events) > 3 {
320
+			t.Fatalf("Expected 3 events, got %d: %v", len(events), events)
321
+		}
322
+		createEvent := strings.Fields(events[0])
323
+		if createEvent[len(createEvent)-1] != "create" {
324
+			t.Fatalf("first event should be create, not %#v", createEvent)
325
+		}
326
+		if len(events) > 1 {
327
+			startEvent := strings.Fields(events[1])
328
+			if startEvent[len(startEvent)-1] != "start" {
329
+				t.Fatalf("second event should be start, not %#v", startEvent)
330
+			}
331
+		}
332
+		if len(events) == 3 {
333
+			dieEvent := strings.Fields(events[len(events)-1])
334
+			if dieEvent[len(dieEvent)-1] != "die" {
335
+				t.Fatalf("event should be die, not %#v", dieEvent)
336
+			}
337
+		}
338
+	}
339
+
340
+	logDone("events - filters using container id")
341
+}
342
+
343
+func TestEventsFilterContainerName(t *testing.T) {
344
+	since := time.Now().Unix()
345
+	defer deleteAllContainers()
346
+
347
+	_, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_1", "busybox", "true"))
348
+	if err != nil {
349
+		t.Fatal(err)
350
+	}
351
+
352
+	_, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_2", "busybox", "true"))
353
+	if err != nil {
354
+		t.Fatal(err)
355
+	}
356
+
357
+	for _, s := range []string{"container_1", "container_2"} {
358
+		eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", time.Now().Unix()), "--filter", fmt.Sprintf("container=%s", s))
359
+		out, _, err := runCommandWithOutput(eventsCmd)
360
+		if err != nil {
361
+			t.Fatalf("Failed to get events, error : %s(%s)", err, out)
362
+		}
363
+		events := strings.Split(out, "\n")
364
+		events = events[:len(events)-1]
365
+		if len(events) == 0 || len(events) > 3 {
366
+			t.Fatalf("Expected 3 events, got %d: %v", len(events), events)
367
+		}
368
+		createEvent := strings.Fields(events[0])
369
+		if createEvent[len(createEvent)-1] != "create" {
370
+			t.Fatalf("first event should be create, not %#v", createEvent)
371
+		}
372
+		if len(events) > 1 {
373
+			startEvent := strings.Fields(events[1])
374
+			if startEvent[len(startEvent)-1] != "start" {
375
+				t.Fatalf("second event should be start, not %#v", startEvent)
376
+			}
377
+		}
378
+		if len(events) == 3 {
379
+			dieEvent := strings.Fields(events[len(events)-1])
380
+			if dieEvent[len(dieEvent)-1] != "die" {
381
+				t.Fatalf("event should be die, not %#v", dieEvent)
382
+			}
383
+		}
384
+	}
293 385
 
386
+	logDone("events - filters using container name")
294 387
 }