add client to containermap, add views package, help view

This commit is contained in:
Bradley Cicenas 2017-01-01 22:42:13 +00:00
parent adaa07fd4d
commit 6e87539b9d
7 changed files with 103 additions and 43 deletions

View File

@ -8,6 +8,7 @@ import (
type Container struct {
id string
name string
done chan bool
stats chan *docker.Stats
widgets *Widgets

View File

@ -1,23 +1,57 @@
package main
import (
"os"
"strings"
"github.com/fsouza/go-dockerclient"
)
var filters = map[string][]string{
"status": []string{"running"},
}
func NewContainerMap() *ContainerMap {
return &ContainerMap{
containers: make(map[string]*Container),
sortField: "cpu",
// init docker client
host := os.Getenv("DOCKER_HOST")
if host == "" {
host = "unix:///var/run/docker.sock"
}
client, err := docker.NewClient(host)
if err != nil {
panic(err)
}
cm := &ContainerMap{
client: client,
containers: make(map[string]*Container),
sortField: SortFields[0],
}
cm.Refresh()
return cm
}
type ContainerMap struct {
client *docker.Client
containers map[string]*Container
sortField string
}
func (cm *ContainerMap) Refresh() {
opts := docker.ListContainersOptions{
Filters: filters,
}
containers, err := cm.client.ListContainers(opts)
if err != nil {
panic(err)
}
for _, c := range containers {
if _, ok := cm.containers[c.ID[:12]]; ok == false {
cm.Add(c)
}
}
}
// Return number of containers/rows
func (cm *ContainerMap) Len() uint {
return uint(len(cm.containers))
@ -28,11 +62,13 @@ func (cm *ContainerMap) Add(c docker.APIContainers) {
name := strings.Replace(c.Names[0], "/", "", 1) // use primary container name
cm.containers[id] = &Container{
id: id,
name: name,
done: make(chan bool),
stats: make(chan *docker.Stats),
widgets: NewWidgets(cid, name),
widgets: NewWidgets(id, name),
reader: &StatReader{},
}
cm.containers[id].Collect(cm.client)
}
// Get a single container, by ID

30
grid.go
View File

@ -3,6 +3,7 @@ package main
import (
"fmt"
"github.com/bcicen/ctop/views"
ui "github.com/gizak/termui"
)
@ -58,7 +59,7 @@ func (g *Grid) Redraw() {
func header() *ui.Row {
return ui.NewRow(
ui.NewCol(2, 0, headerPar("NAME")),
ui.NewCol(1, 0, headerPar("CID")),
ui.NewCol(2, 0, headerPar("CID")),
ui.NewCol(2, 0, headerPar("CPU")),
ui.NewCol(2, 0, headerPar("MEM")),
ui.NewCol(2, 0, headerPar("NET RX/TX")),
@ -74,12 +75,26 @@ func headerPar(s string) *ui.Par {
return p
}
func Display(g *Grid) {
type View func()
func ResetView() {
ui.DefaultEvtStream.ResetHandlers()
ui.Clear()
}
func OpenView(v View) {
ResetView()
defer ResetView()
v()
}
func Display(g *Grid) bool {
var newView View
if err := ui.Init(); err != nil {
panic(err)
}
defer ui.Close()
// calculate layout
ui.Body.Align()
g.Cursor()
@ -97,6 +112,10 @@ func Display(g *Grid) {
g.Cursor()
}
})
ui.Handle("/sys/kbd/h", func(ui.Event) {
newView = views.Help
ui.StopLoop()
})
ui.Handle("/sys/kbd/q", func(ui.Event) {
ui.StopLoop()
})
@ -112,4 +131,9 @@ func Display(g *Grid) {
})
ui.Loop()
if newView != nil {
OpenView(newView)
return false
}
return true
}

39
main.go
View File

@ -2,43 +2,14 @@ package main
import (
"os"
"github.com/fsouza/go-dockerclient"
)
func getContainers(client *docker.Client) []docker.APIContainers {
filters := make(map[string][]string)
filters["status"] = []string{"running"}
opts := docker.ListContainersOptions{
Filters: filters,
}
containers, err := client.ListContainers(opts)
if err != nil {
panic(err)
}
return containers
}
func main() {
dockerhost := os.Getenv("DOCKER_HOST")
if dockerhost == "" {
dockerhost = "unix:///var/run/docker.sock"
}
client, err := docker.NewClient(dockerhost)
if err != nil {
panic(err)
}
g := NewGrid()
for _, c := range getContainers(client) {
g.containers.Add(c)
for {
exit := Display(g)
if exit {
os.Exit(0)
}
}
for _, c := range g.containers.All() {
c.Collect(client)
}
Display(g)
}

View File

@ -4,6 +4,8 @@ import (
"sort"
)
var SortFields = []string{"id", "name", "cpu", "mem"}
type ByID []*Container
func (a ByID) Len() int { return len(a) }
@ -14,7 +16,7 @@ type ByName []*Container
func (a ByName) Len() int { return len(a) }
func (a ByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByName) Less(i, j int) bool { return a[i].id < a[j].id }
func (a ByName) Less(i, j int) bool { return a[i].name < a[j].name }
type ByCPU []*Container

26
views/help.go Normal file
View File

@ -0,0 +1,26 @@
package views
import (
"strings"
ui "github.com/gizak/termui"
)
var helpDialog = []string{
"[h] - open this help dialog",
"[q] - exit ctop",
}
func Help() {
p := ui.NewPar(strings.Join(helpDialog, "\n"))
p.Height = 10
p.Width = 50
p.TextFgColor = ui.ColorWhite
p.BorderLabel = "Help"
p.BorderFg = ui.ColorCyan
ui.Render(p)
ui.Handle("/sys/kbd/q", func(ui.Event) {
ui.StopLoop()
})
ui.Loop()
}

View File

@ -18,7 +18,7 @@ type Widgets struct {
func (w *Widgets) MakeRow() *ui.Row {
return ui.NewRow(
ui.NewCol(2, 0, w.name),
ui.NewCol(1, 0, w.cid),
ui.NewCol(2, 0, w.cid),
ui.NewCol(2, 0, w.cpu),
ui.NewCol(2, 0, w.memory),
ui.NewCol(2, 0, w.net),