mirror of
https://github.com/bcicen/ctop.git
synced 2024-08-30 18:23:19 +00:00
add client to containermap, add views package, help view
This commit is contained in:
parent
adaa07fd4d
commit
6e87539b9d
@ -8,6 +8,7 @@ import (
|
||||
|
||||
type Container struct {
|
||||
id string
|
||||
name string
|
||||
done chan bool
|
||||
stats chan *docker.Stats
|
||||
widgets *Widgets
|
||||
|
@ -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
30
grid.go
@ -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
39
main.go
@ -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)
|
||||
|
||||
}
|
||||
|
4
sort.go
4
sort.go
@ -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
26
views/help.go
Normal 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()
|
||||
}
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user