Skip to content

Commit

Permalink
Add container information to menu widget
Browse files Browse the repository at this point in the history
  • Loading branch information
moncho committed Jan 29, 2018
1 parent a25da5a commit 24e676c
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 30 deletions.
9 changes: 1 addition & 8 deletions appui/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ import (
"github.com/olekukonko/tablewriter"
)

const (
maxWidth = 80
)

//NewContainerInfo returns detailed container information. Returned int value
//is the number of lines.
func NewContainerInfo(container *docker.Container) (string, int) {
Expand All @@ -24,7 +20,6 @@ func NewContainerInfo(container *docker.Container) (string, int) {
} else {
status = ui.Red(container.Status)
}
lines := len(container.Command) / maxWidth
data := [][]string{
{ui.Blue("Container Name:"), ui.Yellow(container.Names[0]), ui.Blue("ID:"), ui.Yellow(docker.TruncateID(container.ID)), ui.Blue("Status:"), status},
{ui.Blue("Image:"), ui.Yellow(container.Image), ui.Blue("Created:"), ui.Yellow(docker.DurationForHumans(container.Created) + " ago")},
Expand All @@ -46,12 +41,10 @@ func NewContainerInfo(container *docker.Container) (string, int) {
strconv.Itoa(len(container.Labels)))})

table := tablewriter.NewWriter(buffer)
table.SetAutoFormatHeaders(false)
table.SetBorder(false)
table.SetColumnSeparator("")
table.SetAlignment(tablewriter.ALIGN_LEFT)
table.SetColWidth(maxWidth)
table.AppendBulk(data)
table.Render()
return buffer.String(), len(data) + lines
return buffer.String(), len(data)
}
19 changes: 16 additions & 3 deletions appui/container_details.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
package appui

import (
termui "github.com/gizak/termui"
"github.com/moncho/dry/docker"

drytermui "github.com/moncho/dry/ui/termui"
)

//ContainerDetailsWidget shows service information
type ContainerDetailsWidget struct {
container *docker.Container
drytermui.SizableBufferer
}

//NewContainerDetailsWidget creates ContainerDetailsWidget with information about the service with the given ID
func NewContainerDetailsWidget(container *docker.Container, y int) *ContainerDetailsWidget {
w := ContainerDetailsWidget{}
info, lines := NewContainerInfo(container)

cInfo := drytermui.NewParFromMarkupText(DryTheme, info)
cInfo.Y = y
cInfo.Height = lines + 1
cInfo.BorderLeft = false
cInfo.BorderRight = false
cInfo.BorderTop = false

cInfo.Bg = termui.Attribute(DryTheme.Bg)
cInfo.BorderBg = termui.Attribute(DryTheme.Bg)
cInfo.BorderFg = termui.Attribute(DryTheme.Footer)
cInfo.TextBgColor = termui.Attribute(DryTheme.Bg)

return &w
return &ContainerDetailsWidget{cInfo}
}
49 changes: 49 additions & 0 deletions appui/container_details_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package appui

import (
"testing"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/network"
"github.com/moncho/dry/docker"
)

func TestNewContainerDetailsWidget(t *testing.T) {
type args struct {
container *docker.Container
y int
}
tests := []struct {
name string
args args
}{
{
"a widget with container details can be created",
args{
&docker.Container{
Container: types.Container{
Names: []string{"container1"},
NetworkSettings: &types.SummaryNetworkSettings{
Networks: make(map[string]*network.EndpointSettings),
},
},
ContainerJSON: types.ContainerJSON{
NetworkSettings: &types.NetworkSettings{
Networks: make(map[string]*network.EndpointSettings),
},
},
},
0,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
w := NewContainerDetailsWidget(tt.args.container, tt.args.y)

if w == nil {
t.Error("ContainerDetailsWidget was not created")
}
})
}
}
25 changes: 16 additions & 9 deletions appui/container_menu.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ import (
"github.com/moncho/dry/ui"
)

const cMenuWidth = 30

//ContainerMenuWidget shows the actions menu of a container
type ContainerMenuWidget struct {
dockerDaemon docker.ContainerAPI
rows []*Row
cInfo *ContainerDetailsWidget
cID string
height, width int
mounted bool
Expand All @@ -25,10 +28,12 @@ type ContainerMenuWidget struct {
//NewContainerMenuWidget creates a TasksWidget
func NewContainerMenuWidget(dockerDaemon docker.ContainerAPI, y int) *ContainerMenuWidget {
w := ContainerMenuWidget{
height: MainScreenAvailableHeight(),
width: 30,
y: y,
dockerDaemon: dockerDaemon,
height: MainScreenAvailableHeight(),
width: ui.ActiveScreen.Dimensions.Width,
y: y,
}

return &w
}

Expand All @@ -40,7 +45,8 @@ func (s *ContainerMenuWidget) Buffer() gizaktermui.Buffer {
if s.mounted {
y := s.y
s.prepareForRendering()

buf.Merge(s.cInfo.Buffer())
y += s.cInfo.GetHeight()
for i, row := range s.rows {
row.SetY(y)
y += row.GetHeight()
Expand Down Expand Up @@ -76,6 +82,7 @@ func (s *ContainerMenuWidget) Mount() error {
s.Lock()
defer s.Unlock()
if !s.mounted {
s.cInfo = NewContainerDetailsWidget(s.dockerDaemon.ContainerByID(s.cID), s.y)
rows := make([]*Row, len(docker.CommandDescriptions))
for i, command := range docker.CommandDescriptions {
r := &Row{
Expand Down Expand Up @@ -121,12 +128,12 @@ func (s *ContainerMenuWidget) Unmount() error {
}

func (s *ContainerMenuWidget) align() {
x := s.x
width := s.width

s.cInfo.SetWidth(s.width)
s.cInfo.SetX(s.x)
rowsX := (ui.ActiveScreen.Dimensions.Width - cMenuWidth) / 2
for _, row := range s.rows {
row.SetX(x)
row.SetWidth(width)
row.SetX(rowsX)
row.SetWidth(cMenuWidth)
}
}

Expand Down
20 changes: 10 additions & 10 deletions appui/stats_row.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type ContainerStatsRow struct {
//NewContainerStatsRow creats a new ContainerStatsRow widget
func NewContainerStatsRow(container *docker.Container, table drytermui.Table) *ContainerStatsRow {
cf := formatter.NewContainerFormatter(container, true)
row := &ContainerStatsRow{
row := ContainerStatsRow{
container: container,
Status: drytermui.NewThemedParColumn(DryTheme, statusSymbol),
Name: drytermui.NewThemedParColumn(DryTheme, cf.Names()),
Expand Down Expand Up @@ -67,7 +67,7 @@ func NewContainerStatsRow(container *docker.Container, table drytermui.Table) *C
} else {
row.Status.TextFgColor = Running
}
return row
return &row

}

Expand Down Expand Up @@ -144,14 +144,14 @@ func (row *ContainerStatsRow) Reset() {

//Update updates the content of this row with the given stats
func (row *ContainerStatsRow) Update(container *docker.Container, stat *docker.Stats) {
if stat != nil {
row.setNet(stat.NetworkRx, stat.NetworkTx)
row.setCPU(stat.CPUPercentage)
row.setMem(stat.Memory, stat.MemoryLimit, stat.MemoryPercentage)
row.setBlockIO(stat.BlockRead, stat.BlockWrite)
row.setPids(stat.PidsCurrent)
row.setUptime(container.ContainerJSON.State.StartedAt)
}

row.setNet(stat.NetworkRx, stat.NetworkTx)
row.setCPU(stat.CPUPercentage)
row.setMem(stat.Memory, stat.MemoryLimit, stat.MemoryPercentage)
row.setBlockIO(stat.BlockRead, stat.BlockWrite)
row.setPids(stat.PidsCurrent)
row.setUptime(container.ContainerJSON.State.StartedAt)

}

func (row *ContainerStatsRow) setNet(rx float64, tx float64) {
Expand Down

0 comments on commit 24e676c

Please sign in to comment.