diff --git a/container/statssum.go b/container/statssum.go index b18c7222..6756456b 100644 --- a/container/statssum.go +++ b/container/statssum.go @@ -63,8 +63,10 @@ func (self *percentilesContainerHandlerWrapper) GetStats() (*info.ContainerStats if err != nil { return nil, err } + // nil stats and nil error is possible for /docker container. if stats == nil { - return nil, fmt.Errorf("container handler returns a nil error and a nil stats") + // return nil, fmt.Errorf("container handler returns a nil error and a nil stats") + return nil, nil } if stats.Timestamp.IsZero() { return nil, fmt.Errorf("container handler did not set timestamp") diff --git a/manager/container.go b/manager/container.go index be7eea1e..bba9db7d 100644 --- a/manager/container.go +++ b/manager/container.go @@ -35,8 +35,8 @@ type containerStat struct { Data *info.ContainerStats } type containerInfo struct { - Name string - Subcontainers []string + info.ContainerRef + Subcontainers []info.ContainerRef Spec *info.ContainerSpec Stats *list.List StatsSummary *info.ContainerStatsPercentiles diff --git a/manager/manager.go b/manager/manager.go index 6320fa19..474e7139 100644 --- a/manager/manager.go +++ b/manager/manager.go @@ -111,7 +111,9 @@ func (m *manager) GetContainerInfo(containerName string) (*info.ContainerInfo, e // Make a copy of the info for the user. ret := &info.ContainerInfo{ - Name: cinfo.Name, + ContainerRef: info.ContainerRef{ + Name: cinfo.Name, + }, Subcontainers: cinfo.Subcontainers, Spec: cinfo.Spec, StatsSummary: cinfo.StatsSummary, @@ -180,10 +182,8 @@ func (m *manager) destroyContainer(containerName string) error { return nil } -type empty struct{} - // Detect all containers that have been added or deleted. -func (m *manager) getContainersDiff() (added []string, removed []string, err error) { +func (m *manager) getContainersDiff() (added []info.ContainerRef, removed []info.ContainerRef, err error) { // TODO(vmarmol): We probably don't need to lock around / since it will always be there. m.containersLock.RLock() defer m.containersLock.RUnlock() @@ -197,24 +197,24 @@ func (m *manager) getContainersDiff() (added []string, removed []string, err err if err != nil { return nil, nil, err } - allContainers = append(allContainers, "/") + allContainers = append(allContainers, info.ContainerRef{Name: "/"}) // Determine which were added and which were removed. - allContainersSet := make(map[string]*empty) - for name, _ := range m.containers { - allContainersSet[name] = &empty{} + allContainersSet := make(map[string]*containerData) + for name, d := range m.containers { + allContainersSet[name] = d } - for _, name := range allContainers { - delete(allContainersSet, name) - _, ok := m.containers[name] + for _, c := range allContainers { + delete(allContainersSet, c.Name) + _, ok := m.containers[c.Name] if !ok { - added = append(added, name) + added = append(added, c) } } // Removed ones are no longer in the container listing. - for name, _ := range allContainersSet { - removed = append(removed, name) + for _, d := range allContainersSet { + removed = append(removed, d.info.ContainerRef) } return @@ -228,18 +228,18 @@ func (m *manager) detectContainers() error { } // Add the new containers. - for _, name := range added { - _, err = m.createContainer(name) + for _, c := range added { + _, err = m.createContainer(c.Name) if err != nil { - return fmt.Errorf("Failed to create existing container: %s: %s", name, err) + return fmt.Errorf("Failed to create existing container: %s: %s", c.Name, err) } } // Remove the old containers. - for _, name := range removed { - err = m.destroyContainer(name) + for _, c := range removed { + err = m.destroyContainer(c.Name) if err != nil { - return fmt.Errorf("Failed to destroy existing container: %s: %s", name, err) + return fmt.Errorf("Failed to destroy existing container: %s: %s", c.Name, err) } } diff --git a/pages/containers.go b/pages/containers.go index 8efb84d2..c2522cb7 100644 --- a/pages/containers.go +++ b/pages/containers.go @@ -50,8 +50,8 @@ var pageTemplate *template.Template type pageData struct { ContainerName string - ParentContainers []string - Subcontainers []string + ParentContainers []info.ContainerRef + Subcontainers []info.ContainerRef Spec *info.ContainerSpec Stats []*info.ContainerStats MachineInfo *info.MachineInfo @@ -69,14 +69,17 @@ func init() { } // TODO(vmarmol): Escape this correctly. -func containerLink(containerName string, basenameOnly bool, cssClasses string) interface{} { +func containerLink(containerRef info.ContainerRef, basenameOnly bool, cssClasses string) interface{} { var displayName string - if basenameOnly { - displayName = path.Base(string(containerName)) + containerName := containerRef.Name + if len(containerRef.Aliases) > 0 { + displayName = containerRef.Aliases[0] + } else if basenameOnly { + displayName = path.Base(string(containerRef.Name)) } else { - displayName = string(containerName) + displayName = string(containerRef.Name) } - if containerName == "root" { + if containerRef.Name == "root" { containerName = "/" } return template.HTML(fmt.Sprintf("%s", cssClasses, ContainersPage[:len(ContainersPage)-1], containerName, displayName)) @@ -167,15 +170,15 @@ func ServerContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL) } // Make a list of the parent containers and their links - var parentContainers []string - parentContainers = append(parentContainers, string("root")) + var parentContainers []info.ContainerRef + parentContainers = append(parentContainers, info.ContainerRef{Name: "root"}) parentName := "" for _, part := range strings.Split(string(cont.Name), "/") { if part == "" { continue } parentName += "/" + part - parentContainers = append(parentContainers, string(parentName)) + parentContainers = append(parentContainers, info.ContainerRef{Name: parentName}) } data := &pageData{