From 987da85db3c3baebc32fb7746cb982fbcb70470f Mon Sep 17 00:00:00 2001 From: Bradley Cicenas Date: Thu, 2 Feb 2017 07:09:43 +0000 Subject: [PATCH] add container state checks, set status icon based on state string --- collector/docker.go | 20 ++++++++++++++++---- collector/main.go | 2 ++ container.go | 1 + containermap.go | 32 +++++++++++++++++--------------- grid.go | 2 +- widgets/compact.go | 20 +++++++++++++++----- widgets/expanded.go | 2 +- 7 files changed, 53 insertions(+), 26 deletions(-) diff --git a/collector/docker.go b/collector/docker.go index 2dd227f..5cb1ccc 100644 --- a/collector/docker.go +++ b/collector/docker.go @@ -7,6 +7,9 @@ import ( // Docker collector type Docker struct { Metrics + id string + client *api.Client + running bool stream chan Metrics done chan bool lastCpu float64 @@ -14,22 +17,27 @@ type Docker struct { } func NewDocker(client *api.Client, id string) *Docker { - c := &Docker{ + return &Docker{ Metrics: Metrics{}, + id: id, + client: client, stream: make(chan Metrics), done: make(chan bool), } +} +func (c *Docker) Start() { stats := make(chan *api.Stats) go func() { opts := api.StatsOptions{ - ID: id, + ID: c.id, Stats: stats, Stream: true, Done: c.done, } - client.Stats(opts) + c.client.Stats(opts) + c.running = false }() go func() { @@ -42,7 +50,11 @@ func NewDocker(client *api.Client, id string) *Docker { } }() - return c + c.running = true +} + +func (c *Docker) Running() bool { + return c.running } func (c *Docker) Stream() chan Metrics { diff --git a/collector/main.go b/collector/main.go index bda71d2..8c3ea25 100644 --- a/collector/main.go +++ b/collector/main.go @@ -15,6 +15,8 @@ type Metrics struct { type Collector interface { Stream() chan Metrics + Running() bool + Start() Stop() } diff --git a/container.go b/container.go index 6fb7ca1..f023560 100644 --- a/container.go +++ b/container.go @@ -23,6 +23,7 @@ func (c *Container) Collapse() { } func (c *Container) Collect() { + c.collect.Start() go func() { for metrics := range c.collect.Stream() { c.metrics = metrics diff --git a/containermap.go b/containermap.go index 531e8b1..8a68c1d 100644 --- a/containermap.go +++ b/containermap.go @@ -11,10 +11,6 @@ import ( "github.com/fsouza/go-dockerclient" ) -var filters = map[string][]string{ - "status": []string{"running"}, -} - func NewContainerMap() *ContainerMap { // init docker client client, err := docker.NewClient(GlobalConfig["dockerHost"]) @@ -37,17 +33,17 @@ type ContainerMap struct { func (cm *ContainerMap) Refresh() { var id, name string - opts := docker.ListContainersOptions{ - Filters: filters, - } + opts := docker.ListContainersOptions{All: true} containers, err := cm.client.ListContainers(opts) if err != nil { panic(err) } // add new containers + states := make(map[string]string) for _, c := range containers { id = c.ID[:12] + states[id] = c.State if _, ok := cm.containers[id]; ok == false { name = strings.Replace(c.Names[0], "/", "", 1) // use primary container name cm.containers[id] = &Container{ @@ -56,19 +52,25 @@ func (cm *ContainerMap) Refresh() { collect: collector.NewDocker(cm.client, id), widgets: widgets.NewCompact(id, name), } - cm.containers[id].Collect() } } + var removeIDs []string + for id, c := range cm.containers { + // mark stale internal containers + if _, ok := states[id]; ok == false { + removeIDs = append(removeIDs, id) + continue + } + // start collector if necessary + if states[id] == "running" && !c.collect.Running() { + c.Collect() + } + c.widgets.SetStatus(states[id]) + } + // remove dead containers - var removeIDs []string - for id, c := range cm.containers { - if c.dead { - removeIDs = append(removeIDs, id) - } - } cm.Del(removeIDs...) - } // Kill a container by ID diff --git a/grid.go b/grid.go index e9e6378..0aa1393 100644 --- a/grid.go +++ b/grid.go @@ -135,7 +135,7 @@ func Display(g *Grid) bool { // calculate layout ui.Body.Align() g.redrawCursor() - ui.Render(ui.Body) + g.redrawRows() ui.Handle("/sys/kbd/", func(ui.Event) { g.cursorUp() diff --git a/widgets/compact.go b/widgets/compact.go index efb7399..3c004c4 100644 --- a/widgets/compact.go +++ b/widgets/compact.go @@ -8,7 +8,8 @@ import ( ) const ( - mark = '\u25C9' + mark = '\u25C9' + pause = '\u25AE' ) type ContainerWidgets interface { @@ -16,7 +17,7 @@ type ContainerWidgets interface { Render() Highlight() UnHighlight() - SetStatus(int) + SetStatus(string) SetCPU(int) SetNet(int64, int64) SetMem(int64, int64, int) @@ -33,7 +34,7 @@ type Compact struct { func NewCompact(id string, name string) *Compact { return &Compact{ - Status: slimPar(string(mark)), + Status: slimPar(""), Cid: slimPar(id), Net: slimPar("-"), Name: slimPar(name), @@ -67,11 +68,19 @@ func (w *Compact) UnHighlight() { w.Name.TextBgColor = ui.ColorDefault } -func (w *Compact) SetStatus(val int) { +func (w *Compact) SetStatus(val string) { switch val { - case 0: + case "running": + w.Status.Text = string(mark) w.Status.TextFgColor = ui.ColorGreen + case "exited": + w.Status.Text = string(mark) + w.Status.TextFgColor = ui.ColorRed + case "paused": + w.Status.Text = fmt.Sprintf("%s%s", string(pause), string(pause)) + w.Status.TextFgColor = ui.ColorDefault default: + w.Status.Text = string(mark) w.Status.TextFgColor = ui.ColorRed } } @@ -109,6 +118,7 @@ func centerParText(p *ui.Par) { for i, ch := range p.Text { if string(ch) != " " { text = p.Text[i:] + break } } diff --git a/widgets/expanded.go b/widgets/expanded.go index 517b7ab..d066bd0 100644 --- a/widgets/expanded.go +++ b/widgets/expanded.go @@ -58,7 +58,7 @@ func (w *Expanded) Highlight() { func (w *Expanded) UnHighlight() { } -func (w *Expanded) SetStatus(val int) { +func (w *Expanded) SetStatus(val string) { } func (w *Expanded) SetCPU(val int) {