Signed-off-by: Vincent Demeester <vincent@sbr.pm>
| ... | ... |
@@ -204,7 +204,10 @@ func (daemon *Daemon) Commit(name string, c *types.ContainerCommitConfig) (strin |
| 204 | 204 |
} |
| 205 | 205 |
} |
| 206 | 206 |
|
| 207 |
- daemon.LogContainerEvent(container, "commit") |
|
| 207 |
+ attributes := map[string]string{
|
|
| 208 |
+ "comment": c.Comment, |
|
| 209 |
+ } |
|
| 210 |
+ daemon.LogContainerEventWithAttributes(container, "commit", attributes) |
|
| 208 | 211 |
return id.String(), nil |
| 209 | 212 |
} |
| 210 | 213 |
|
| ... | ... |
@@ -8,9 +8,14 @@ import ( |
| 8 | 8 |
"github.com/docker/libnetwork" |
| 9 | 9 |
) |
| 10 | 10 |
|
| 11 |
-// LogContainerEvent generates an event related to a container. |
|
| 11 |
+// LogContainerEvent generates an event related to a container with only the default attributes. |
|
| 12 | 12 |
func (daemon *Daemon) LogContainerEvent(container *container.Container, action string) {
|
| 13 |
- attributes := copyAttributes(container.Config.Labels) |
|
| 13 |
+ daemon.LogContainerEventWithAttributes(container, action, map[string]string{})
|
|
| 14 |
+} |
|
| 15 |
+ |
|
| 16 |
+// LogContainerEventWithAttributes generates an event related to a container with specific given attributes. |
|
| 17 |
+func (daemon *Daemon) LogContainerEventWithAttributes(container *container.Container, action string, attributes map[string]string) {
|
|
| 18 |
+ copyAttributes(attributes, container.Config.Labels) |
|
| 14 | 19 |
if container.Config.Image != "" {
|
| 15 | 20 |
attributes["image"] = container.Config.Image |
| 16 | 21 |
} |
| ... | ... |
@@ -23,14 +28,18 @@ func (daemon *Daemon) LogContainerEvent(container *container.Container, action s |
| 23 | 23 |
daemon.EventsService.Log(action, events.ContainerEventType, actor) |
| 24 | 24 |
} |
| 25 | 25 |
|
| 26 |
-// LogImageEvent generates an event related to a container. |
|
| 26 |
+// LogImageEvent generates an event related to a container with only the default attributes. |
|
| 27 | 27 |
func (daemon *Daemon) LogImageEvent(imageID, refName, action string) {
|
| 28 |
- attributes := map[string]string{}
|
|
| 28 |
+ daemon.LogImageEventWithAttributes(imageID, refName, action, map[string]string{})
|
|
| 29 |
+} |
|
| 30 |
+ |
|
| 31 |
+// LogImageEventWithAttributes generates an event related to a container with specific given attributes. |
|
| 32 |
+func (daemon *Daemon) LogImageEventWithAttributes(imageID, refName, action string, attributes map[string]string) {
|
|
| 29 | 33 |
img, err := daemon.GetImage(imageID) |
| 30 | 34 |
if err == nil && img.Config != nil {
|
| 31 | 35 |
// image has not been removed yet. |
| 32 | 36 |
// it could be missing if the event is `delete`. |
| 33 |
- attributes = copyAttributes(img.Config.Labels) |
|
| 37 |
+ copyAttributes(attributes, img.Config.Labels) |
|
| 34 | 38 |
} |
| 35 | 39 |
if refName != "" {
|
| 36 | 40 |
attributes["name"] = refName |
| ... | ... |
@@ -69,13 +78,11 @@ func (daemon *Daemon) LogNetworkEventWithAttributes(nw libnetwork.Network, actio |
| 69 | 69 |
} |
| 70 | 70 |
|
| 71 | 71 |
// copyAttributes guarantees that labels are not mutated by event triggers. |
| 72 |
-func copyAttributes(labels map[string]string) map[string]string {
|
|
| 73 |
- attributes := map[string]string{}
|
|
| 72 |
+func copyAttributes(attributes, labels map[string]string) {
|
|
| 74 | 73 |
if labels == nil {
|
| 75 |
- return attributes |
|
| 74 |
+ return |
|
| 76 | 75 |
} |
| 77 | 76 |
for k, v := range labels {
|
| 78 | 77 |
attributes[k] = v |
| 79 | 78 |
} |
| 80 |
- return attributes |
|
| 81 | 79 |
} |
| ... | ... |
@@ -2,13 +2,15 @@ package daemon |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"testing" |
| 5 |
+ "time" |
|
| 5 | 6 |
|
| 6 | 7 |
"github.com/docker/docker/container" |
| 7 | 8 |
"github.com/docker/docker/daemon/events" |
| 8 | 9 |
containertypes "github.com/docker/engine-api/types/container" |
| 10 |
+ eventtypes "github.com/docker/engine-api/types/events" |
|
| 9 | 11 |
) |
| 10 | 12 |
|
| 11 |
-func TestLogContainerCopyLabels(t *testing.T) {
|
|
| 13 |
+func TestLogContainerEventCopyLabels(t *testing.T) {
|
|
| 12 | 14 |
e := events.New() |
| 13 | 15 |
_, l, _ := e.Subscribe() |
| 14 | 16 |
defer e.Evict(l) |
| ... | ... |
@@ -18,6 +20,7 @@ func TestLogContainerCopyLabels(t *testing.T) {
|
| 18 | 18 |
ID: "container_id", |
| 19 | 19 |
Name: "container_name", |
| 20 | 20 |
Config: &containertypes.Config{
|
| 21 |
+ Image: "image_name", |
|
| 21 | 22 |
Labels: map[string]string{
|
| 22 | 23 |
"node": "1", |
| 23 | 24 |
"os": "alpine", |
| ... | ... |
@@ -33,4 +36,59 @@ func TestLogContainerCopyLabels(t *testing.T) {
|
| 33 | 33 |
if _, mutated := container.Config.Labels["image"]; mutated {
|
| 34 | 34 |
t.Fatalf("Expected to not mutate the container labels, got %q", container.Config.Labels)
|
| 35 | 35 |
} |
| 36 |
+ |
|
| 37 |
+ validateTestAttributes(t, l, map[string]string{
|
|
| 38 |
+ "node": "1", |
|
| 39 |
+ "os": "alpine", |
|
| 40 |
+ }) |
|
| 41 |
+} |
|
| 42 |
+ |
|
| 43 |
+func TestLogContainerEventWithAttributes(t *testing.T) {
|
|
| 44 |
+ e := events.New() |
|
| 45 |
+ _, l, _ := e.Subscribe() |
|
| 46 |
+ defer e.Evict(l) |
|
| 47 |
+ |
|
| 48 |
+ container := &container.Container{
|
|
| 49 |
+ CommonContainer: container.CommonContainer{
|
|
| 50 |
+ ID: "container_id", |
|
| 51 |
+ Name: "container_name", |
|
| 52 |
+ Config: &containertypes.Config{
|
|
| 53 |
+ Labels: map[string]string{
|
|
| 54 |
+ "node": "1", |
|
| 55 |
+ "os": "alpine", |
|
| 56 |
+ }, |
|
| 57 |
+ }, |
|
| 58 |
+ }, |
|
| 59 |
+ } |
|
| 60 |
+ daemon := &Daemon{
|
|
| 61 |
+ EventsService: e, |
|
| 62 |
+ } |
|
| 63 |
+ attributes := map[string]string{
|
|
| 64 |
+ "node": "2", |
|
| 65 |
+ "foo": "bar", |
|
| 66 |
+ } |
|
| 67 |
+ daemon.LogContainerEventWithAttributes(container, "create", attributes) |
|
| 68 |
+ |
|
| 69 |
+ validateTestAttributes(t, l, map[string]string{
|
|
| 70 |
+ "node": "1", |
|
| 71 |
+ "foo": "bar", |
|
| 72 |
+ }) |
|
| 73 |
+} |
|
| 74 |
+ |
|
| 75 |
+func validateTestAttributes(t *testing.T, l chan interface{}, expectedAttributesToTest map[string]string) {
|
|
| 76 |
+ select {
|
|
| 77 |
+ case ev := <-l: |
|
| 78 |
+ event, ok := ev.(eventtypes.Message) |
|
| 79 |
+ if !ok {
|
|
| 80 |
+ t.Fatalf("Unexpected event message: %q", ev)
|
|
| 81 |
+ } |
|
| 82 |
+ for key, expected := range expectedAttributesToTest {
|
|
| 83 |
+ actual, ok := event.Actor.Attributes[key] |
|
| 84 |
+ if !ok || actual != expected {
|
|
| 85 |
+ t.Fatalf("Expected value for key %s to be %s, but was %s (event:%v)", key, expected, actual, event)
|
|
| 86 |
+ } |
|
| 87 |
+ } |
|
| 88 |
+ case <-time.After(10 * time.Second): |
|
| 89 |
+ t.Fatalf("LogEvent test timed out")
|
|
| 90 |
+ } |
|
| 36 | 91 |
} |
| ... | ... |
@@ -65,7 +65,10 @@ func (daemon *Daemon) killWithSignal(container *container.Container, sig int) er |
| 65 | 65 |
return err |
| 66 | 66 |
} |
| 67 | 67 |
|
| 68 |
- daemon.LogContainerEvent(container, "kill") |
|
| 68 |
+ attributes := map[string]string{
|
|
| 69 |
+ "signal": fmt.Sprintf("%d", sig),
|
|
| 70 |
+ } |
|
| 71 |
+ daemon.LogContainerEventWithAttributes(container, "kill", attributes) |
|
| 69 | 72 |
return nil |
| 70 | 73 |
} |
| 71 | 74 |
|
| ... | ... |
@@ -49,8 +49,12 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) error {
|
| 49 | 49 |
return err |
| 50 | 50 |
} |
| 51 | 51 |
|
| 52 |
+ attributes := map[string]string{
|
|
| 53 |
+ "oldName": oldName, |
|
| 54 |
+ } |
|
| 55 |
+ |
|
| 52 | 56 |
if !container.Running {
|
| 53 |
- daemon.LogContainerEvent(container, "rename") |
|
| 57 |
+ daemon.LogContainerEventWithAttributes(container, "rename", attributes) |
|
| 54 | 58 |
return nil |
| 55 | 59 |
} |
| 56 | 60 |
|
| ... | ... |
@@ -73,6 +77,7 @@ func (daemon *Daemon) ContainerRename(oldName, newName string) error {
|
| 73 | 73 |
if err != nil {
|
| 74 | 74 |
return err |
| 75 | 75 |
} |
| 76 |
- daemon.LogContainerEvent(container, "rename") |
|
| 76 |
+ |
|
| 77 |
+ daemon.LogContainerEventWithAttributes(container, "rename", attributes) |
|
| 77 | 78 |
return nil |
| 78 | 79 |
} |
| ... | ... |
@@ -1,6 +1,10 @@ |
| 1 | 1 |
package daemon |
| 2 | 2 |
|
| 3 |
-import derr "github.com/docker/docker/errors" |
|
| 3 |
+import ( |
|
| 4 |
+ "fmt" |
|
| 5 |
+ |
|
| 6 |
+ derr "github.com/docker/docker/errors" |
|
| 7 |
+) |
|
| 4 | 8 |
|
| 5 | 9 |
// ContainerResize changes the size of the TTY of the process running |
| 6 | 10 |
// in the container with the given name to the given height and width. |
| ... | ... |
@@ -15,7 +19,11 @@ func (daemon *Daemon) ContainerResize(name string, height, width int) error {
|
| 15 | 15 |
} |
| 16 | 16 |
|
| 17 | 17 |
if err = container.Resize(height, width); err == nil {
|
| 18 |
- daemon.LogContainerEvent(container, "resize") |
|
| 18 |
+ attributes := map[string]string{
|
|
| 19 |
+ "height": fmt.Sprintf("%d", height),
|
|
| 20 |
+ "width": fmt.Sprintf("%d", width),
|
|
| 21 |
+ } |
|
| 22 |
+ daemon.LogContainerEventWithAttributes(container, "resize", attributes) |
|
| 19 | 23 |
} |
| 20 | 24 |
return err |
| 21 | 25 |
} |
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package daemon |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "fmt" |
|
| 4 | 5 |
"runtime" |
| 5 | 6 |
|
| 6 | 7 |
"github.com/Sirupsen/logrus" |
| ... | ... |
@@ -101,7 +102,10 @@ func (daemon *Daemon) containerStart(container *container.Container) (err error) |
| 101 | 101 |
} |
| 102 | 102 |
container.ToDisk() |
| 103 | 103 |
daemon.Cleanup(container) |
| 104 |
- daemon.LogContainerEvent(container, "die") |
|
| 104 |
+ attributes := map[string]string{
|
|
| 105 |
+ "exitCode": fmt.Sprintf("%d", container.ExitCode),
|
|
| 106 |
+ } |
|
| 107 |
+ daemon.LogContainerEventWithAttributes(container, "die", attributes) |
|
| 105 | 108 |
} |
| 106 | 109 |
}() |
| 107 | 110 |
|