From cf340cd4575e95e5aa1c87b3599f1d9cb17dbabc Mon Sep 17 00:00:00 2001 From: fabianlee Date: Mon, 22 May 2017 15:44:33 +0000 Subject: [PATCH] containers: extra labels for name, removing links for multiply named containers --- containers.go | 40 ++++++++++++++++++++++++++++++++++++---- images.go | 13 +++++++++---- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/containers.go b/containers.go index de1f79a..62d4923 100644 --- a/containers.go +++ b/containers.go @@ -24,6 +24,7 @@ type Container struct { type ContainersCommand struct { Dot bool `short:"d" long:"dot" description:"Show container information as Graphviz dot."` NoTruncate bool `short:"n" long:"no-trunc" description:"Don't truncate the container IDs."` + //OnlyRunning bool `short:"r" long:"running" description:"Only show running containers, not Exited"` } var containersCommand ContainersCommand @@ -81,7 +82,8 @@ func (x *ContainersCommand) Execute(args []string) error { } if containersCommand.Dot { - fmt.Printf(jsonContainersToDot(containers)) + //fmt.Printf(jsonContainersToDot(containers, containersCommand.OnlyRunning)) + fmt.Printf(jsonContainersToDot(containers, true)) } else { return fmt.Errorf("Please specify --dot") } @@ -115,24 +117,49 @@ func parseContainersJSON(rawJSON []byte) (*[]Container, error) { return &containers, nil } -func jsonContainersToDot(containers *[]Container) string { +func jsonContainersToDot(containers *[]Container,OnlyRunning bool) string { var buffer bytes.Buffer buffer.WriteString("digraph docker {\n") + // build list of all primary container names + var PrimaryContainerNames map[string]string + PrimaryContainerNames = make(map[string]string) for _, container := range *containers { + for _, name := range container.Names { + if strings.Count(name, "/") == 1 { + //fmt.Printf("%s\n",name[1:]) + PrimaryContainerNames[name[1:]] = name[1:] + } + } + } + + // stores ony first value of link to avoid duplicates + var LinkMap map[string]string + LinkMap = make(map[string]string) + + for _, container := range *containers { + //if OnlyRunning && strings.HasPrefix(container.Status,"Exit") { continue } var containerName string + //fmt.Printf("container status/Names %s/%s\n",container.Status,container.Names) for _, name := range container.Names { if strings.Count(name, "/") == 1 { containerName = name[1:] } } + for _, name := range container.Names { nameParts := strings.Split(name, "/") if len(nameParts) > 2 { - buffer.WriteString(fmt.Sprintf(" \"%s\" -> \"%s\" [label = \" %s\" ]\n", containerName, nameParts[1], nameParts[len(nameParts)-1])) + //fmt.Printf("\t%s to %s\n",containerName,nameParts[1]) + if IsPrimaryContainerName(containerName,PrimaryContainerNames) && IsPrimaryContainerName(nameParts[1],PrimaryContainerNames) { + if _,ok := LinkMap[containerName + "-" + nameParts[1]]; !ok { + LinkMap[containerName + "-" + nameParts[1]] = "exists" + buffer.WriteString(fmt.Sprintf(" \"%s\" -> \"%s\" [label = \" %s\" ]\n", containerName, nameParts[1], nameParts[len(nameParts)-1] )) + } + } } } @@ -144,7 +171,7 @@ func jsonContainersToDot(containers *[]Container) string { containerBackground = "paleturquoise" } - buffer.WriteString(fmt.Sprintf(" \"%s\" [label=\"%s\\n%s\",shape=box,fillcolor=\"%s\",style=\"filled,rounded\"];\n", containerName, containerName, truncate(container.Id, 12), containerBackground)) + buffer.WriteString(fmt.Sprintf(" \"%s\" [label=\"%s\\n%s\\n%s\",shape=box,fillcolor=\"%s\",style=\"filled,rounded\"];\n", containerName, container.Image, containerName, truncate(container.Id, 12), containerBackground)) } buffer.WriteString("}\n") @@ -152,6 +179,11 @@ func jsonContainersToDot(containers *[]Container) string { return buffer.String() } +func IsPrimaryContainerName(Name string,PrimaryContainerNames map[string]string) bool { + _,ok := PrimaryContainerNames[Name] + return ok +} + func init() { parser.AddCommand("containers", "Visualize docker containers.", diff --git a/images.go b/images.go index 38fa272..a3982cf 100644 --- a/images.go +++ b/images.go @@ -468,7 +468,7 @@ func imagesToDot(buffer *bytes.Buffer, images []Image, byParent map[string][]Ima // show partial command and size to make up for // the fact that since Docker 1.10 content addressing // image ids are usually empty and report as - SanitizedCommand := SanitizeCommand(image.CreatedBy,24) + SanitizedCommand := SanitizeCommand(image.CreatedBy,30) buffer.WriteString(fmt.Sprintf(" \"%s\" [label=\"%s\"]\n", truncate(image.Id, 12), truncate(stripPrefix(image.OrigId), 12)+ "\n" + SanitizedCommand + "\n" + humanize.Bytes(uint64(image.Size)) )) } if subimages, exists := byParent[image.Id]; exists { @@ -511,21 +511,26 @@ func jsonToShort(images *[]Image) string { func SanitizeCommand(CommandStr string,MaxLength int) string { temp := CommandStr + + // remove prefixes that don't add meaning if(strings.HasPrefix(temp,"/bin/sh -c")) { temp = strings.TrimSpace(temp[10:]) } if(strings.HasPrefix(temp,"#(nop)")) { temp = strings.TrimSpace(temp[6:]) } - temp = strings.Replace(temp,"\\"," ",-1) + + // remove double and single quotes which make dot format invalid temp = strings.Replace(temp,"\""," ",-1) temp = strings.Replace(temp,"'"," ",-1) - //temp = strings.Replace(temp,"[","(",-1) - //temp = strings.Replace(temp,"]",")",-1) + + // remove double spaces inside + temp = strings.Join(strings.Fields(temp)," ") return truncate(temp,MaxLength) } + func init() { parser.AddCommand("images", "Visualize docker images.",