From a49c3893dec281087774a23dd24b39c97fb6151c Mon Sep 17 00:00:00 2001 From: Ilya Dmitrichenko Date: Mon, 18 Apr 2016 12:10:18 +0100 Subject: [PATCH] More sensible container names for Mesos/Marathon (#1316) * Collect container environment variales (close #1314) * Containers managed by Marathon can have meaningful names (close #1309) * Make linter happy and fix tests --- probe/docker/container.go | 1 + probe/docker/env.go | 39 ++++++++++++++++++++++++++++++++++++++ probe/docker/env_test.go | 38 +++++++++++++++++++++++++++++++++++++ render/detailed/summary.go | 4 ++++ 4 files changed, 82 insertions(+) create mode 100644 probe/docker/env.go create mode 100644 probe/docker/env_test.go diff --git a/probe/docker/container.go b/probe/docker/container.go index 6ffa10946..86bf81aed 100644 --- a/probe/docker/container.go +++ b/probe/docker/container.go @@ -377,6 +377,7 @@ func (c *container) GetNode(hostID string, localAddrs []net.IP) report.Node { } result = AddLabels(result, c.container.Config.Labels) + result = AddEnv(result, c.container.Config.Env) result = result.WithMetrics(c.metrics()) return result } diff --git a/probe/docker/env.go b/probe/docker/env.go new file mode 100644 index 000000000..1d216750b --- /dev/null +++ b/probe/docker/env.go @@ -0,0 +1,39 @@ +package docker + +import ( + "strings" + + "github.com/weaveworks/scope/report" +) + +// EnvPrefix is the key prefix used for Docker environment variables in Node +// (e.g. "TERM=vt200" will get encoded as "docker_env_TERM"="vt200" in the +// metadata) +const EnvPrefix = "docker_env_" + +// AddEnv appends Docker environment variables to the Node from a topology. +func AddEnv(node report.Node, env []string) report.Node { + node = node.Copy() + for _, value := range env { + v := strings.SplitN(value, "=", 2) + if len(v) == 2 { + key, value := v[0], v[1] + node = node.WithLatests(map[string]string{ + EnvPrefix + key: value, + }) + } + } + return node +} + +// ExtractEnv returns the list of Docker environment variables given a Node from a topology. +func ExtractEnv(node report.Node) map[string]string { + result := map[string]string{} + node.Latest.ForEach(func(key, value string) { + if strings.HasPrefix(key, EnvPrefix) { + env := key[len(EnvPrefix):] + result[env] = value + } + }) + return result +} diff --git a/probe/docker/env_test.go b/probe/docker/env_test.go new file mode 100644 index 000000000..5897f256a --- /dev/null +++ b/probe/docker/env_test.go @@ -0,0 +1,38 @@ +package docker_test + +import ( + "testing" + + "github.com/weaveworks/scope/probe/docker" + "github.com/weaveworks/scope/report" + _ "github.com/weaveworks/scope/test" +) + +func TestEnv(t *testing.T) { + given := []string{ + "TERM=vt200", + "SHELL=/bin/ksh", + "FOO1=\"foo=bar\"", + "FOO2", + } + nmd := report.MakeNode() + + nmd = docker.AddEnv(nmd, given) + have := docker.ExtractEnv(nmd) + + if "vt200" != have["TERM"] { + t.Errorf("Expected \"vt200\", got \"%s\"", have["TERM"]) + } + + if "/bin/ksh" != have["SHELL"] { + t.Errorf("Expected \"/bin/ksh\", got \"%s\"", have["SHELL"]) + } + + if "\"foo=bar\"" != have["FOO1"] { + t.Errorf("Expected \"\"foo=bar\"\", got \"%s\"", have["FOO1"]) + } + + if len(have) != 3 { + t.Errorf("Expected only 3 items, got %d", len(have)) + } +} diff --git a/render/detailed/summary.go b/render/detailed/summary.go index d98ec9cd2..4bc9c38a8 100644 --- a/render/detailed/summary.go +++ b/render/detailed/summary.go @@ -26,6 +26,7 @@ const ( // Keys we use to render container names AmazonECSContainerNameLabel = "com.amazonaws.ecs.container-name" KubernetesContainerNameLabel = "io.kubernetes.container.name" + MarathonAppIDEnv = "MARATHON_APP_ID" ) // NodeSummaryGroup is a topology-typed group of children for a Node. @@ -370,6 +371,9 @@ func getRenderableContainerName(nmd report.Node) string { // is only provided by Kubernetes versions >= 1.2 (see // https://github.com/kubernetes/kubernetes/pull/17234/ ) docker.LabelPrefix + KubernetesContainerNameLabel, + // Marathon doesn't set any Docker labels and this is the only meaningful + // attribute we can find to make Scope useful without Mesos plugin + docker.EnvPrefix + MarathonAppIDEnv, docker.ContainerName, docker.ContainerHostname, } {