mirror of
https://github.com/bcicen/ctop.git
synced 2024-08-30 18:23:19 +00:00
add container state checks, set status icon based on state string
This commit is contained in:
parent
9671fffbe9
commit
987da85db3
@ -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 {
|
||||
|
@ -15,6 +15,8 @@ type Metrics struct {
|
||||
|
||||
type Collector interface {
|
||||
Stream() chan Metrics
|
||||
Running() bool
|
||||
Start()
|
||||
Stop()
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
2
grid.go
2
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/<up>", func(ui.Event) {
|
||||
g.cursorUp()
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user