containers: extra labels for name, removing links for multiply named containers
This commit is contained in:
parent
18ad950cd1
commit
cf340cd457
2 changed files with 45 additions and 8 deletions
|
@ -24,6 +24,7 @@ type Container struct {
|
||||||
type ContainersCommand struct {
|
type ContainersCommand struct {
|
||||||
Dot bool `short:"d" long:"dot" description:"Show container information as Graphviz dot."`
|
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."`
|
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
|
var containersCommand ContainersCommand
|
||||||
|
@ -81,7 +82,8 @@ func (x *ContainersCommand) Execute(args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if containersCommand.Dot {
|
if containersCommand.Dot {
|
||||||
fmt.Printf(jsonContainersToDot(containers))
|
//fmt.Printf(jsonContainersToDot(containers, containersCommand.OnlyRunning))
|
||||||
|
fmt.Printf(jsonContainersToDot(containers, true))
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("Please specify --dot")
|
return fmt.Errorf("Please specify --dot")
|
||||||
}
|
}
|
||||||
|
@ -115,24 +117,49 @@ func parseContainersJSON(rawJSON []byte) (*[]Container, error) {
|
||||||
return &containers, nil
|
return &containers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsonContainersToDot(containers *[]Container) string {
|
func jsonContainersToDot(containers *[]Container,OnlyRunning bool) string {
|
||||||
|
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
buffer.WriteString("digraph docker {\n")
|
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 _, 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
|
var containerName string
|
||||||
|
|
||||||
|
//fmt.Printf("container status/Names %s/%s\n",container.Status,container.Names)
|
||||||
for _, name := range container.Names {
|
for _, name := range container.Names {
|
||||||
if strings.Count(name, "/") == 1 {
|
if strings.Count(name, "/") == 1 {
|
||||||
containerName = name[1:]
|
containerName = name[1:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range container.Names {
|
for _, name := range container.Names {
|
||||||
nameParts := strings.Split(name, "/")
|
nameParts := strings.Split(name, "/")
|
||||||
if len(nameParts) > 2 {
|
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"
|
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")
|
buffer.WriteString("}\n")
|
||||||
|
@ -152,6 +179,11 @@ func jsonContainersToDot(containers *[]Container) string {
|
||||||
return buffer.String()
|
return buffer.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsPrimaryContainerName(Name string,PrimaryContainerNames map[string]string) bool {
|
||||||
|
_,ok := PrimaryContainerNames[Name]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
parser.AddCommand("containers",
|
parser.AddCommand("containers",
|
||||||
"Visualize docker containers.",
|
"Visualize docker containers.",
|
||||||
|
|
13
images.go
13
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
|
// show partial command and size to make up for
|
||||||
// the fact that since Docker 1.10 content addressing
|
// the fact that since Docker 1.10 content addressing
|
||||||
// image ids are usually empty and report as <missing>
|
// image ids are usually empty and report as <missing>
|
||||||
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)) ))
|
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 {
|
if subimages, exists := byParent[image.Id]; exists {
|
||||||
|
@ -511,21 +511,26 @@ func jsonToShort(images *[]Image) string {
|
||||||
func SanitizeCommand(CommandStr string,MaxLength int) string {
|
func SanitizeCommand(CommandStr string,MaxLength int) string {
|
||||||
|
|
||||||
temp := CommandStr
|
temp := CommandStr
|
||||||
|
|
||||||
|
// remove prefixes that don't add meaning
|
||||||
if(strings.HasPrefix(temp,"/bin/sh -c")) {
|
if(strings.HasPrefix(temp,"/bin/sh -c")) {
|
||||||
temp = strings.TrimSpace(temp[10:])
|
temp = strings.TrimSpace(temp[10:])
|
||||||
}
|
}
|
||||||
if(strings.HasPrefix(temp,"#(nop)")) {
|
if(strings.HasPrefix(temp,"#(nop)")) {
|
||||||
temp = strings.TrimSpace(temp[6:])
|
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)
|
||||||
//temp = strings.Replace(temp,"[","(",-1)
|
|
||||||
//temp = strings.Replace(temp,"]",")",-1)
|
// remove double spaces inside
|
||||||
|
temp = strings.Join(strings.Fields(temp)," ")
|
||||||
|
|
||||||
return truncate(temp,MaxLength)
|
return truncate(temp,MaxLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
parser.AddCommand("images",
|
parser.AddCommand("images",
|
||||||
"Visualize docker images.",
|
"Visualize docker images.",
|
||||||
|
|
Loading…
Reference in a new issue