func containerOriginTable(nmd report.Node, addHostTag bool) (Table, bool) { rows := []Row{} for _, tuple := range []struct{ key, human string }{ {docker.ContainerState, "State"}, } { if val, ok := nmd.Latest.Lookup(tuple.key); ok && val != "" { rows = append(rows, Row{Key: tuple.human, ValueMajor: val, ValueMinor: ""}) } } for _, tuple := range []struct{ key, human string }{ {docker.ContainerID, "ID"}, {docker.ImageID, "Image ID"}, {docker.ContainerPorts, "Ports"}, {docker.ContainerCreated, "Created"}, {docker.ContainerCommand, "Command"}, {overlay.WeaveMACAddress, "Weave MAC"}, {overlay.WeaveDNSHostname, "Weave DNS Hostname"}, } { if val, ok := nmd.Metadata[tuple.key]; ok && val != "" { rows = append(rows, Row{Key: tuple.human, ValueMajor: val, ValueMinor: ""}) } } for _, ip := range docker.ExtractContainerIPs(nmd) { rows = append(rows, Row{Key: "IP Address", ValueMajor: ip, ValueMinor: ""}) } rows = append(rows, getDockerLabelRows(nmd)...) if addHostTag { rows = append([]Row{{Key: "Host", ValueMajor: report.ExtractHostID(nmd)}}, rows...) } if val, ok := nmd.Metrics[docker.MemoryUsage]; ok { rows = append(rows, sparklineRow("Memory Usage", val, formatMemory)) } if val, ok := nmd.Metrics[docker.CPUTotalUsage]; ok { rows = append(rows, sparklineRow("CPU Usage", val, formatPercent)) } var ( title = "Container" name, nameFound = GetRenderableContainerName(nmd) ) if nameFound { title += ` "` + name + `"` } return Table{ Title: title, Numeric: false, Rows: rows, Rank: containerRank, }, len(rows) > 0 || nameFound }
func (w Weave) tagContainer(r report.Report, containerIDPrefix, macAddress string, ips []string) { for nodeid, nmd := range r.Container.NodeMetadatas { idPrefix := nmd.Metadata[docker.ContainerID][:12] if idPrefix != containerIDPrefix { continue } existingIPs := report.MakeIDList(docker.ExtractContainerIPs(nmd)...) existingIPs = existingIPs.Add(ips...) nmd.Metadata[docker.ContainerIPs] = strings.Join(existingIPs, " ") nmd.Metadata[WeaveMACAddress] = macAddress r.Container.NodeMetadatas[nodeid] = nmd break } }
func containerOriginTable(nmd report.Node, addHostTag bool) (Table, bool) { rows := []Row{} for _, tuple := range []struct{ key, human string }{ {docker.ContainerState, "State"}, {docker.ContainerID, "ID"}, {docker.ImageID, "Image ID"}, {docker.ContainerPorts, "Ports"}, {docker.ContainerCreated, "Created"}, {docker.ContainerCommand, "Command"}, {overlay.WeaveMACAddress, "Weave MAC"}, {overlay.WeaveDNSHostname, "Weave DNS Hostname"}, } { if val, ok := nmd.Metadata[tuple.key]; ok && val != "" { rows = append(rows, Row{Key: tuple.human, ValueMajor: val, ValueMinor: ""}) } } for _, ip := range docker.ExtractContainerIPs(nmd) { rows = append(rows, Row{Key: "IP Address", ValueMajor: ip, ValueMinor: ""}) } rows = append(rows, getDockerLabelRows(nmd)...) if val, ok := nmd.Metadata[docker.MemoryUsage]; ok { memory, err := strconv.ParseFloat(val, 64) if err == nil { memoryStr := fmt.Sprintf("%0.2f", memory/float64(mb)) rows = append(rows, Row{Key: "Memory Usage (MB):", ValueMajor: memoryStr, ValueMinor: ""}) } } if addHostTag { rows = append([]Row{{Key: "Host", ValueMajor: report.ExtractHostID(nmd)}}, rows...) } var ( title = "Container" name, nameFound = GetRenderableContainerName(nmd) ) if nameFound { title += ` "` + name + `"` } return Table{ Title: title, Numeric: false, Rows: rows, Rank: containerRank, }, len(rows) > 0 || nameFound }
// Tag implements Tagger. func (w *Weave) Tag(r report.Report) (report.Report, error) { w.mtx.RLock() defer w.mtx.RUnlock() // Put information from weaveDNS on the container nodes for _, entry := range w.status.DNS.Entries { if entry.Tombstone > 0 { continue } nodeID := report.MakeContainerNodeID(w.hostID, entry.ContainerID) node, ok := r.Container.Nodes[nodeID] if !ok { continue } hostnames := report.IDList(strings.Fields(node.Metadata[WeaveDNSHostname])) hostnames = hostnames.Add(strings.TrimSuffix(entry.Hostname, ".")) node.Metadata[WeaveDNSHostname] = strings.Join(hostnames, " ") } // Put information from weave ps on the container nodes psEntries, err := w.ps() if err != nil { return r, nil } containersByPrefix := map[string]report.Node{} for _, node := range r.Container.Nodes { prefix := node.Metadata[docker.ContainerID][:12] containersByPrefix[prefix] = node } for _, e := range psEntries { node, ok := containersByPrefix[e.containerIDPrefix] if !ok { continue } existingIPs := report.MakeIDList(docker.ExtractContainerIPs(node)...) existingIPs = existingIPs.Add(e.ips...) node.Metadata[docker.ContainerIPs] = strings.Join(existingIPs, " ") node.Metadata[WeaveMACAddress] = e.macAddress } return r, nil }
func TestContainer(t *testing.T) { log.SetOutput(ioutil.Discard) oldDialStub, oldNewClientConnStub := docker.DialStub, docker.NewClientConnStub defer func() { docker.DialStub, docker.NewClientConnStub = oldDialStub, oldNewClientConnStub }() docker.DialStub = func(network, address string) (net.Conn, error) { return nil, nil } reader, writer := io.Pipe() connection := &mockConnection{reader} docker.NewClientConnStub = func(c net.Conn, r *bufio.Reader) docker.ClientConn { return connection } c := docker.NewContainer(container1) err := c.StartGatheringStats() if err != nil { t.Errorf("%v", err) } defer c.StopGatheringStats() now := time.Unix(12345, 67890).UTC() mtime.NowForce(now) defer mtime.NowReset() // Send some stats to the docker container stats := &client.Stats{} stats.Read = now stats.MemoryStats.Usage = 12345 if err = json.NewEncoder(writer).Encode(&stats); err != nil { t.Error(err) } // Now see if we go them uptime := (now.Sub(startTime) / time.Second) * time.Second want := report.MakeNode().WithLatests(map[string]string{ "docker_container_command": " ", "docker_container_created": "01 Jan 01 00:00 UTC", "docker_container_id": "ping", "docker_container_name": "pong", "docker_image_id": "baz", "docker_label_foo1": "bar1", "docker_label_foo2": "bar2", "docker_container_state": "running", "docker_container_uptime": uptime.String(), }).WithSets(report.EmptySets. Add("docker_container_ports", report.MakeStringSet("1.2.3.4:80->80/tcp", "81/tcp")). Add("docker_container_ips", report.MakeStringSet("1.2.3.4")). Add("docker_container_ips_with_scopes", report.MakeStringSet("scope;1.2.3.4")), ).WithControls( docker.RestartContainer, docker.StopContainer, docker.PauseContainer, docker.AttachContainer, docker.ExecContainer, ).WithMetrics(report.Metrics{ "docker_cpu_total_usage": report.MakeMetric(), "docker_memory_usage": report.MakeMetric().Add(now, 12345), }).WithParents(report.EmptySets. Add(report.ContainerImage, report.MakeStringSet(report.MakeContainerImageNodeID("baz"))), ) test.Poll(t, 100*time.Millisecond, want, func() interface{} { node := c.GetNode("scope", []net.IP{}) node.Latest.ForEach(func(k, v string) { if v == "0" || v == "" { node.Latest = node.Latest.Delete(k) } }) return node }) if c.Image() != "baz" { t.Errorf("%s != baz", c.Image()) } if c.PID() != 2 { t.Errorf("%d != 2", c.PID()) } if have := docker.ExtractContainerIPs(c.GetNode("", []net.IP{})); !reflect.DeepEqual(have, []string{"1.2.3.4"}) { t.Errorf("%v != %v", have, []string{"1.2.3.4"}) } }
func TestContainer(t *testing.T) { log.SetOutput(ioutil.Discard) oldDialStub, oldNewClientConnStub := docker.DialStub, docker.NewClientConnStub defer func() { docker.DialStub, docker.NewClientConnStub = oldDialStub, oldNewClientConnStub }() docker.DialStub = func(network, address string) (net.Conn, error) { return nil, nil } reader, writer := io.Pipe() connection := &mockConnection{reader} docker.NewClientConnStub = func(c net.Conn, r *bufio.Reader) docker.ClientConn { return connection } c := docker.NewContainer(container1) err := c.StartGatheringStats() if err != nil { t.Errorf("%v", err) } defer c.StopGatheringStats() // Send some stats to the docker container stats := &client.Stats{} stats.MemoryStats.Usage = 12345 if err = json.NewEncoder(writer).Encode(&stats); err != nil { t.Error(err) } // Now see if we go them want := report.MakeNode().WithMetadata(map[string]string{ "docker_container_command": " ", "docker_container_created": "01 Jan 01 00:00 UTC", "docker_container_id": "ping", "docker_container_name": "pong", "docker_image_id": "baz", "docker_label_foo1": "bar1", "docker_label_foo2": "bar2", "memory_usage": "12345", "docker_container_state": "running", }).WithSets(report.Sets{ "docker_container_ports": report.MakeStringSet("1.2.3.4:80->80/tcp", "81/tcp"), "docker_container_ips": report.MakeStringSet("1.2.3.4"), "docker_container_ips_with_scopes": report.MakeStringSet("scope;1.2.3.4"), }).WithControls(docker.RestartContainer, docker.StopContainer, docker.PauseContainer) test.Poll(t, 100*time.Millisecond, want, func() interface{} { node := c.GetNode("scope", []net.IP{}) for k, v := range node.Metadata { if v == "0" || v == "" { delete(node.Metadata, k) } } return node }) if c.Image() != "baz" { t.Errorf("%s != baz", c.Image()) } if c.PID() != 1 { t.Errorf("%d != 1", c.PID()) } if have := docker.ExtractContainerIPs(c.GetNode("", []net.IP{})); !reflect.DeepEqual(have, []string{"1.2.3.4"}) { t.Errorf("%v != %v", have, []string{"1.2.3.4"}) } }