mirror of
https://github.com/bcicen/ctop.git
synced 2024-08-30 18:23:19 +00:00
added container menu closes #28
This commit is contained in:
parent
e1ec264345
commit
436266b1a4
@ -8,6 +8,7 @@ import (
|
||||
"github.com/bcicen/ctop/connector/collector"
|
||||
"github.com/bcicen/ctop/container"
|
||||
api "github.com/fsouza/go-dockerclient"
|
||||
"github.com/bcicen/ctop/connector/manager"
|
||||
)
|
||||
|
||||
type Docker struct {
|
||||
@ -132,8 +133,10 @@ func (cm *Docker) MustGet(id string) *container.Container {
|
||||
if !ok {
|
||||
// create collector
|
||||
collector := collector.NewDocker(cm.client, id)
|
||||
// create manager
|
||||
manager := manager.NewDocker(cm.client, id)
|
||||
// create container
|
||||
c = container.New(id, collector)
|
||||
c = container.New(id, collector, manager)
|
||||
cm.lock.Lock()
|
||||
cm.containers[id] = c
|
||||
cm.lock.Unlock()
|
||||
|
44
connector/manager/docker.go
Normal file
44
connector/manager/docker.go
Normal file
@ -0,0 +1,44 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
api "github.com/fsouza/go-dockerclient"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Docker struct {
|
||||
id string
|
||||
client *api.Client
|
||||
}
|
||||
|
||||
func NewDocker(client *api.Client, id string) *Docker {
|
||||
return &Docker{
|
||||
id: id,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (dc *Docker) Start() error {
|
||||
c, err := dc.client.InspectContainer(dc.id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot inspect container: %v", err)
|
||||
}
|
||||
|
||||
if err := dc.client.StartContainer(c.ID, c.HostConfig); err != nil {
|
||||
return fmt.Errorf("cannot start container: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dc *Docker) Stop() error {
|
||||
if err := dc.client.StopContainer(dc.id, 3); err != nil {
|
||||
return fmt.Errorf("cannot stop container: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dc *Docker) Remove() error {
|
||||
if err := dc.client.RemoveContainer(api.RemoveContainerOptions{ID: dc.id}); err != nil {
|
||||
return fmt.Errorf("cannot remove container: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
7
connector/manager/main.go
Normal file
7
connector/manager/main.go
Normal file
@ -0,0 +1,7 @@
|
||||
package manager
|
||||
|
||||
type Manager interface {
|
||||
Start() error
|
||||
Stop() error
|
||||
Remove() error
|
||||
}
|
19
connector/manager/mock.go
Normal file
19
connector/manager/mock.go
Normal file
@ -0,0 +1,19 @@
|
||||
package manager
|
||||
|
||||
type Mock struct {}
|
||||
|
||||
func NewMock() *Mock {
|
||||
return &Mock{}
|
||||
}
|
||||
|
||||
func (m *Mock) Start() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Mock) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Mock) Remove() error {
|
||||
return nil
|
||||
}
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/bcicen/ctop/container"
|
||||
"github.com/jgautheron/codename-generator"
|
||||
"github.com/nu7hatch/gouuid"
|
||||
"github.com/bcicen/ctop/connector/manager"
|
||||
)
|
||||
|
||||
type Mock struct {
|
||||
@ -40,7 +41,8 @@ func (cs *Mock) Init() {
|
||||
|
||||
func (cs *Mock) makeContainer(aggression int64) {
|
||||
collector := collector.NewMock(aggression)
|
||||
c := container.New(makeID(), collector)
|
||||
manager := manager.NewMock()
|
||||
c := container.New(makeID(), collector, manager)
|
||||
c.SetMeta("name", makeName())
|
||||
c.SetState(makeState())
|
||||
cs.containers = append(cs.containers, c)
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"github.com/bcicen/ctop/cwidgets/compact"
|
||||
"github.com/bcicen/ctop/logging"
|
||||
"github.com/bcicen/ctop/models"
|
||||
"github.com/bcicen/ctop/connector/manager"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -21,9 +22,10 @@ type Container struct {
|
||||
Display bool // display this container in compact view
|
||||
updater cwidgets.WidgetUpdater
|
||||
collector collector.Collector
|
||||
manager manager.Manager
|
||||
}
|
||||
|
||||
func New(id string, collector collector.Collector) *Container {
|
||||
func New(id string, collector collector.Collector, manager manager.Manager) *Container {
|
||||
widgets := compact.NewCompact(id)
|
||||
return &Container{
|
||||
Metrics: models.NewMetrics(),
|
||||
@ -32,6 +34,7 @@ func New(id string, collector collector.Collector) *Container {
|
||||
Widgets: widgets,
|
||||
updater: widgets,
|
||||
collector: collector,
|
||||
manager: manager,
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,3 +88,31 @@ func (c *Container) Read(stream chan models.Metrics) {
|
||||
}()
|
||||
log.Infof("reader started for container: %s", c.Id)
|
||||
}
|
||||
|
||||
func (c *Container) Start() {
|
||||
if c.Meta["state"] != "running" {
|
||||
if err := c.manager.Start(); err != nil {
|
||||
log.Warningf("container %s: %v", c.Id, err)
|
||||
return
|
||||
}
|
||||
c.SetState("running")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Container) Stop() {
|
||||
if c.Meta["state"] == "running" {
|
||||
if err := c.manager.Stop(); err != nil {
|
||||
log.Warningf("container %s: %v", c.Id, err)
|
||||
return
|
||||
}
|
||||
c.SetState("exited")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Container) Remove() {
|
||||
if c.Meta["state"] == "exited" {
|
||||
if err := c.manager.Remove(); err != nil {
|
||||
log.Warningf("container %s: %v", c.Id, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
4
grid.go
4
grid.go
@ -93,6 +93,10 @@ func Display() bool {
|
||||
ui.StopLoop()
|
||||
})
|
||||
|
||||
ui.Handle("/sys/kbd/m", func(ui.Event) {
|
||||
menu = ContainerMenu
|
||||
ui.StopLoop()
|
||||
})
|
||||
ui.Handle("/sys/kbd/<enter>", func(ui.Event) {
|
||||
single = true
|
||||
ui.StopLoop()
|
||||
|
50
menus.go
50
menus.go
@ -94,3 +94,53 @@ func SortMenu() {
|
||||
ui.Render(m)
|
||||
ui.Loop()
|
||||
}
|
||||
|
||||
func ContainerMenu() {
|
||||
|
||||
c := cursor.Selected()
|
||||
if c == nil {
|
||||
return
|
||||
}
|
||||
|
||||
ui.DefaultEvtStream.ResetHandlers()
|
||||
defer ui.DefaultEvtStream.ResetHandlers()
|
||||
|
||||
m := menu.NewMenu()
|
||||
m.Selectable = true
|
||||
|
||||
m.BorderLabel = "Menu"
|
||||
var items []menu.Item
|
||||
if c.Meta["state"] == "running" {
|
||||
items = append(items, menu.Item{Val: "stop", Label: "stop"})
|
||||
}
|
||||
if c.Meta["state"] == "exited" {
|
||||
items = append(items, menu.Item{Val: "start", Label: "start"})
|
||||
items = append(items, menu.Item{Val: "remove", Label: "remove"})
|
||||
}
|
||||
items = append(items, menu.Item{Val: "cancel", Label: "cancel"})
|
||||
|
||||
m.AddItems(items...)
|
||||
ui.Render(m)
|
||||
|
||||
HandleKeys("up", m.Up)
|
||||
HandleKeys("down", m.Down)
|
||||
ui.Handle("/sys/kbd/<enter>", func(ui.Event) {
|
||||
switch m.SelectedItem().Val {
|
||||
case "start":
|
||||
c.Start()
|
||||
ui.StopLoop()
|
||||
case "stop":
|
||||
c.Stop()
|
||||
ui.StopLoop()
|
||||
case "remove":
|
||||
c.Remove()
|
||||
ui.StopLoop()
|
||||
case "cancel":
|
||||
ui.StopLoop()
|
||||
}
|
||||
})
|
||||
ui.Handle("/sys/kbd/", func(ui.Event) {
|
||||
ui.StopLoop()
|
||||
})
|
||||
ui.Loop()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user