This commit is contained in:
Sergey Ponomarev 2021-07-02 20:26:03 +05:30 committed by GitHub
commit 792976d1b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 92 additions and 0 deletions

View File

@ -1,6 +1,7 @@
package manager
import (
"encoding/json"
"fmt"
api "github.com/fsouza/go-dockerclient"
"github.com/pkg/errors"
@ -102,6 +103,19 @@ func (dc *Docker) Exec(cmd []string) error {
})
}
func (dc *Docker) Inspect() string {
i, err := dc.client.InspectContainer(dc.id)
if err != nil {
return err.Error()
}
// Convert Container struct back to JSON but pretty print
out, err := json.MarshalIndent(i, "", " ")
if err != nil {
return err.Error()
}
return string(out)
}
func (dc *Docker) Start() error {
c, err := dc.client.InspectContainer(dc.id)
if err != nil {

View File

@ -12,4 +12,5 @@ type Manager interface {
Unpause() error
Restart() error
Exec(cmd []string) error
Inspect() string
}

View File

@ -33,3 +33,7 @@ func (m *Mock) Restart() error {
func (m *Mock) Exec(cmd []string) error {
return ActionNotImplErr
}
func (m *Mock) Inspect() string {
return ""
}

View File

@ -33,3 +33,7 @@ func (rc *Runc) Restart() error {
func (rc *Runc) Exec(cmd []string) error {
return ActionNotImplErr
}
func (rc *Runc) Inspect() string {
return ""
}

View File

@ -158,3 +158,7 @@ func (c *Container) Restart() {
func (c *Container) Exec(cmd []string) error {
return c.manager.Exec(cmd)
}
func (c *Container) Inspect() string {
return c.manager.Inspect()
}

View File

@ -162,6 +162,10 @@ func Display() bool {
menu = ExecShell
ui.StopLoop()
})
ui.Handle("/sys/kbd/i", func(ui.Event) {
menu = InspectView
ui.StopLoop()
})
ui.Handle("/sys/kbd/o", func(ui.Event) {
menu = SingleView
ui.StopLoop()

View File

@ -1,6 +1,7 @@
package main
import (
"bufio"
"fmt"
"strings"
"time"
@ -27,6 +28,7 @@ var helpDialog = []menu.Item{
{"[o] - open single view", ""},
{"[l] - view container logs ([t] to toggle timestamp when open)", ""},
{"[e] - exec shell", ""},
{"[i] - inspect", ""},
{"[c] - configure columns", ""},
{"[S] - save current configuration to file", ""},
{"[q] - exit ctop", ""},
@ -214,6 +216,7 @@ func ContainerMenu() MenuFn {
items := []menu.Item{
menu.Item{Val: "single", Label: "[o] single view"},
menu.Item{Val: "logs", Label: "[l] log view"},
menu.Item{Val: "inspect", Label: "[i] inspect"},
}
if c.Meta["state"] == "running" {
@ -303,6 +306,8 @@ func ContainerMenu() MenuFn {
nextMenu = LogMenu
case "exec":
nextMenu = ExecShell
case "inspect":
nextMenu = InspectView
case "start":
nextMenu = Confirm(confirmTxt("start", c.GetMeta("name")), c.Start)
case "stop":
@ -374,6 +379,34 @@ func ExecShell() MenuFn {
return nil
}
func InspectView() MenuFn {
c := cursor.Selected()
if c == nil {
return nil
}
ui.DefaultEvtStream.ResetHandlers()
defer ui.DefaultEvtStream.ResetHandlers()
inspectLines, quit := inspectReader(c)
m := widgets.NewTextView(inspectLines)
m.BorderLabel = fmt.Sprintf("Inspect [%s]", c.GetMeta("name"))
ui.Render(m)
ui.Handle("/sys/wnd/resize", func(e ui.Event) {
m.Resize()
})
ui.Handle("/sys/kbd/t", func(ui.Event) {
m.Toggle()
})
ui.Handle("/sys/kbd/q", func(ui.Event) {
quit <- true
ui.StopLoop()
})
ui.Loop()
return nil
}
// Create a confirmation dialog with a given description string and
// func to perform if confirmed
func Confirm(txt string, fn func()) MenuFn {
@ -464,4 +497,32 @@ func logReader(container *container.Container) (logs chan widgets.ToggleText, qu
return
}
type toggleInspect struct {
json string
}
func (t *toggleInspect) Toggle(on bool) string {
return t.json
}
func inspectReader(container *container.Container) (lines chan widgets.ToggleText, quit chan bool) {
inspectLines := container.Inspect()
lines = make(chan widgets.ToggleText)
quit = make(chan bool)
go func() {
// Split inspectLines to lines
scanner := bufio.NewScanner(strings.NewReader(inspectLines))
for scanner.Scan() {
lines <- &toggleInspect{json: scanner.Text()}
}
for {
select {
case <-quit:
return
}
}
}()
return
}
func confirmTxt(a, n string) string { return fmt.Sprintf("%s container %s?", a, n) }