filter events by container name,id or partial id

Addresses #10645

Signed-off-by: Srini Brahmaroutu <srbrahma@us.ibm.com>
This commit is contained in:
Srini Brahmaroutu 2015-02-09 06:03:42 +00:00
parent cfe5767045
commit e0fa577378
3 changed files with 127 additions and 2 deletions

View file

@ -988,6 +988,12 @@ You'll need two shells for this example.
$ sudo docker events --filter 'container=7805c1d35632' --filter 'event=stop'
2014-09-03T15:49:29.999999999Z07:00 7805c1d35632: (from redis:2.8) stop
$ sudo docker events --filter 'container=container_1' --filter 'container=container_2'
2014-09-03T15:49:29.999999999Z07:00 4386fb97867d: (from ubuntu-1:14.04) die
2014-05-10T17:42:14.999999999Z07:00 4386fb97867d: (from ubuntu-1:14.04) stop
2014-05-10T17:42:14.999999999Z07:00 7805c1d35632: (from redis:2.8) die
2014-09-03T15:49:29.999999999Z07:00 7805c1d35632: (from redis:2.8) stop
## exec
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

View file

@ -1,7 +1,9 @@
package events
import (
"bytes"
"encoding/json"
"io"
"strings"
"sync"
"time"
@ -123,7 +125,13 @@ func writeEvent(job *engine.Job, event *utils.JSONMessage, eventFilters filters.
return true
}
if isFiltered(event.Status, eventFilters["event"]) || isFiltered(event.From, eventFilters["image"]) || isFiltered(event.ID, eventFilters["container"]) {
//incoming container filter can be name,id or partial id, convert and replace as a full container id
for i, cn := range eventFilters["container"] {
eventFilters["container"][i] = GetContainerId(job.Eng, cn)
}
if isFiltered(event.Status, eventFilters["event"]) || isFiltered(event.From, eventFilters["image"]) ||
isFiltered(event.ID, eventFilters["container"]) {
return nil
}
@ -203,3 +211,20 @@ func (e *Events) unsubscribe(l listener) bool {
e.mu.Unlock()
return false
}
func GetContainerId(eng *engine.Engine, name string) string {
var buf bytes.Buffer
job := eng.Job("container_inspect", name)
var outStream io.Writer
outStream = &buf
job.Stdout.Set(outStream)
if err := job.Run(); err != nil {
return ""
}
var out struct{ ID string }
json.NewDecoder(&buf).Decode(&out)
return out.ID
}

View file

@ -258,6 +258,7 @@ func TestEventsFilterImageName(t *testing.T) {
t.Fatal(out, err)
}
container1 := stripTrailingCharacters(out)
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_2", "-d", "busybox", "true"))
if err != nil {
t.Fatal(out, err)
@ -290,5 +291,98 @@ func TestEventsFilterImageName(t *testing.T) {
}
logDone("events - filters using image")
}
func TestEventsFilterContainerID(t *testing.T) {
since := time.Now().Unix()
defer deleteAllContainers()
out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "busybox", "true"))
if err != nil {
t.Fatal(out, err)
}
container1 := stripTrailingCharacters(out)
out, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "-d", "busybox", "true"))
if err != nil {
t.Fatal(out, err)
}
container2 := stripTrailingCharacters(out)
for _, s := range []string{container1, container2, container1[:12], container2[:12]} {
eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", time.Now().Unix()), "--filter", fmt.Sprintf("container=%s", s))
out, _, err := runCommandWithOutput(eventsCmd)
if err != nil {
t.Fatalf("Failed to get events, error: %s(%s)", err, out)
}
events := strings.Split(out, "\n")
events = events[:len(events)-1]
if len(events) == 0 || len(events) > 3 {
t.Fatalf("Expected 3 events, got %d: %v", len(events), events)
}
createEvent := strings.Fields(events[0])
if createEvent[len(createEvent)-1] != "create" {
t.Fatalf("first event should be create, not %#v", createEvent)
}
if len(events) > 1 {
startEvent := strings.Fields(events[1])
if startEvent[len(startEvent)-1] != "start" {
t.Fatalf("second event should be start, not %#v", startEvent)
}
}
if len(events) == 3 {
dieEvent := strings.Fields(events[len(events)-1])
if dieEvent[len(dieEvent)-1] != "die" {
t.Fatalf("event should be die, not %#v", dieEvent)
}
}
}
logDone("events - filters using container id")
}
func TestEventsFilterContainerName(t *testing.T) {
since := time.Now().Unix()
defer deleteAllContainers()
_, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_1", "busybox", "true"))
if err != nil {
t.Fatal(err)
}
_, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--name", "container_2", "busybox", "true"))
if err != nil {
t.Fatal(err)
}
for _, s := range []string{"container_1", "container_2"} {
eventsCmd := exec.Command(dockerBinary, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", time.Now().Unix()), "--filter", fmt.Sprintf("container=%s", s))
out, _, err := runCommandWithOutput(eventsCmd)
if err != nil {
t.Fatalf("Failed to get events, error : %s(%s)", err, out)
}
events := strings.Split(out, "\n")
events = events[:len(events)-1]
if len(events) == 0 || len(events) > 3 {
t.Fatalf("Expected 3 events, got %d: %v", len(events), events)
}
createEvent := strings.Fields(events[0])
if createEvent[len(createEvent)-1] != "create" {
t.Fatalf("first event should be create, not %#v", createEvent)
}
if len(events) > 1 {
startEvent := strings.Fields(events[1])
if startEvent[len(startEvent)-1] != "start" {
t.Fatalf("second event should be start, not %#v", startEvent)
}
}
if len(events) == 3 {
dieEvent := strings.Fields(events[len(events)-1])
if dieEvent[len(dieEvent)-1] != "die" {
t.Fatalf("event should be die, not %#v", dieEvent)
}
}
}
logDone("events - filters using container name")
}