restructure container,connectors in subpackage

This commit is contained in:
Bradley Cicenas 2017-06-08 14:51:02 +00:00
parent 8fb7a8988f
commit b85ca680f0
9 changed files with 50 additions and 32 deletions

View File

@ -1,4 +1,4 @@
package main package connector
import ( import (
"fmt" "fmt"
@ -6,18 +6,24 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/bcicen/ctop/container"
"github.com/bcicen/ctop/logging"
"github.com/bcicen/ctop/metrics" "github.com/bcicen/ctop/metrics"
"github.com/fsouza/go-dockerclient" "github.com/fsouza/go-dockerclient"
) )
var (
log = logging.Init()
)
type ContainerSource interface { type ContainerSource interface {
All() Containers All() container.Containers
Get(string) (*Container, bool) Get(string) (*container.Container, bool)
} }
type DockerContainerSource struct { type DockerContainerSource struct {
client *docker.Client client *docker.Client
containers map[string]*Container containers map[string]*container.Container
needsRefresh chan string // container IDs requiring refresh needsRefresh chan string // container IDs requiring refresh
lock sync.RWMutex lock sync.RWMutex
} }
@ -30,7 +36,7 @@ func NewDockerContainerSource() *DockerContainerSource {
} }
cm := &DockerContainerSource{ cm := &DockerContainerSource{
client: client, client: client,
containers: make(map[string]*Container), containers: make(map[string]*container.Container),
needsRefresh: make(chan string, 60), needsRefresh: make(chan string, 60),
lock: sync.RWMutex{}, lock: sync.RWMutex{},
} }
@ -79,7 +85,7 @@ func portsFormat(ports map[docker.Port][]docker.PortBinding) string {
return strings.Join(append(exposed, published...), "\n") return strings.Join(append(exposed, published...), "\n")
} }
func (cm *DockerContainerSource) refresh(c *Container) { func (cm *DockerContainerSource) refresh(c *container.Container) {
insp := cm.inspect(c.Id) insp := cm.inspect(c.Id)
// remove container if no longer exists // remove container if no longer exists
if insp == nil { if insp == nil {
@ -127,14 +133,14 @@ func (cm *DockerContainerSource) Loop() {
} }
// Get a single container, creating one anew if not existing // Get a single container, creating one anew if not existing
func (cm *DockerContainerSource) MustGet(id string) *Container { func (cm *DockerContainerSource) MustGet(id string) *container.Container {
c, ok := cm.Get(id) c, ok := cm.Get(id)
// append container struct for new containers // append container struct for new containers
if !ok { if !ok {
// create collector // create collector
collector := metrics.NewDocker(cm.client, id) collector := metrics.NewDocker(cm.client, id)
// create container // create container
c = NewContainer(id, collector) c = container.New(id, collector)
cm.lock.Lock() cm.lock.Lock()
cm.containers[id] = c cm.containers[id] = c
cm.lock.Unlock() cm.lock.Unlock()
@ -143,7 +149,7 @@ func (cm *DockerContainerSource) MustGet(id string) *Container {
} }
// Get a single container, by ID // Get a single container, by ID
func (cm *DockerContainerSource) Get(id string) (*Container, bool) { func (cm *DockerContainerSource) Get(id string) (*container.Container, bool) {
cm.lock.Lock() cm.lock.Lock()
c, ok := cm.containers[id] c, ok := cm.containers[id]
cm.lock.Unlock() cm.lock.Unlock()
@ -159,7 +165,7 @@ func (cm *DockerContainerSource) delByID(id string) {
} }
// Return array of all containers, sorted by field // Return array of all containers, sorted by field
func (cm *DockerContainerSource) All() (containers Containers) { func (cm *DockerContainerSource) All() (containers container.Containers) {
cm.lock.Lock() cm.lock.Lock()
for _, c := range cm.containers { for _, c := range cm.containers {
containers = append(containers, c) containers = append(containers, c)

View File

@ -1,6 +1,6 @@
// +build !release // +build !release
package main package connector
import ( import (
"math/rand" "math/rand"
@ -8,13 +8,14 @@ import (
"strings" "strings"
"time" "time"
"github.com/bcicen/ctop/container"
"github.com/bcicen/ctop/metrics" "github.com/bcicen/ctop/metrics"
"github.com/jgautheron/codename-generator" "github.com/jgautheron/codename-generator"
"github.com/nu7hatch/gouuid" "github.com/nu7hatch/gouuid"
) )
type MockContainerSource struct { type MockContainerSource struct {
containers Containers containers container.Containers
} }
func NewMockContainerSource() *MockContainerSource { func NewMockContainerSource() *MockContainerSource {
@ -40,7 +41,7 @@ func (cs *MockContainerSource) Init() {
func (cs *MockContainerSource) makeContainer(aggression int64) { func (cs *MockContainerSource) makeContainer(aggression int64) {
collector := metrics.NewMock(aggression) collector := metrics.NewMock(aggression)
c := NewContainer(makeID(), collector) c := container.New(makeID(), collector)
c.SetMeta("name", makeName()) c.SetMeta("name", makeName())
c.SetState(makeState()) c.SetState(makeState())
cs.containers = append(cs.containers, c) cs.containers = append(cs.containers, c)
@ -60,7 +61,7 @@ func (cs *MockContainerSource) Loop() {
} }
// Get a single container, by ID // Get a single container, by ID
func (cs *MockContainerSource) Get(id string) (*Container, bool) { func (cs *MockContainerSource) Get(id string) (*container.Container, bool) {
for _, c := range cs.containers { for _, c := range cs.containers {
if c.Id == id { if c.Id == id {
return c, true return c, true
@ -70,7 +71,7 @@ func (cs *MockContainerSource) Get(id string) (*Container, bool) {
} }
// Return array of all containers, sorted by field // Return array of all containers, sorted by field
func (cs *MockContainerSource) All() Containers { func (cs *MockContainerSource) All() container.Containers {
sort.Sort(cs.containers) sort.Sort(cs.containers)
cs.containers.Filter() cs.containers.Filter()
return cs.containers return cs.containers

View File

@ -1,23 +1,28 @@
package main package container
import ( import (
"github.com/bcicen/ctop/cwidgets" "github.com/bcicen/ctop/cwidgets"
"github.com/bcicen/ctop/cwidgets/compact" "github.com/bcicen/ctop/cwidgets/compact"
"github.com/bcicen/ctop/logging"
"github.com/bcicen/ctop/metrics" "github.com/bcicen/ctop/metrics"
) )
var (
log = logging.Init()
)
// Metrics and metadata representing a container // Metrics and metadata representing a container
type Container struct { type Container struct {
metrics.Metrics metrics.Metrics
Id string Id string
Meta map[string]string Meta map[string]string
Widgets *compact.Compact Widgets *compact.Compact
Display bool // display this container in compact view
updater cwidgets.WidgetUpdater updater cwidgets.WidgetUpdater
collector metrics.Collector collector metrics.Collector
display bool // display this container in compact view
} }
func NewContainer(id string, collector metrics.Collector) *Container { func New(id string, collector metrics.Collector) *Container {
widgets := compact.NewCompact(id) widgets := compact.NewCompact(id)
return &Container{ return &Container{
Metrics: metrics.NewMetrics(), Metrics: metrics.NewMetrics(),

View File

@ -1,4 +1,4 @@
package main package container
import ( import (
"fmt" "fmt"
@ -104,14 +104,14 @@ func (a Containers) Filter() {
re := regexp.MustCompile(fmt.Sprintf(".*%s", filter)) re := regexp.MustCompile(fmt.Sprintf(".*%s", filter))
for _, c := range a { for _, c := range a {
c.display = true c.Display = true
// Apply name filter // Apply name filter
if re.FindAllString(c.GetMeta("name"), 1) == nil { if re.FindAllString(c.GetMeta("name"), 1) == nil {
c.display = false c.Display = false
} }
// Apply state filter // Apply state filter
if !config.GetSwitchVal("allContainers") && c.GetMeta("state") != "running" { if !config.GetSwitchVal("allContainers") && c.GetMeta("state") != "running" {
c.display = false c.Display = false
} }
} }
} }

View File

@ -3,24 +3,26 @@ package main
import ( import (
"math" "math"
"github.com/bcicen/ctop/connector"
"github.com/bcicen/ctop/container"
ui "github.com/gizak/termui" ui "github.com/gizak/termui"
) )
type GridCursor struct { type GridCursor struct {
selectedID string // id of currently selected container selectedID string // id of currently selected container
filtered Containers filtered container.Containers
cSource ContainerSource cSource connector.ContainerSource
} }
func NewGridCursor() *GridCursor { func NewGridCursor() *GridCursor {
return &GridCursor{ return &GridCursor{
cSource: NewDockerContainerSource(), cSource: connector.NewDockerContainerSource(),
} }
} }
func (gc *GridCursor) Len() int { return len(gc.filtered) } func (gc *GridCursor) Len() int { return len(gc.filtered) }
func (gc *GridCursor) Selected() *Container { func (gc *GridCursor) Selected() *container.Container {
idx := gc.Idx() idx := gc.Idx()
if idx < gc.Len() { if idx < gc.Len() {
return gc.filtered[idx] return gc.filtered[idx]
@ -33,10 +35,10 @@ func (gc *GridCursor) RefreshContainers() (lenChanged bool) {
oldLen := gc.Len() oldLen := gc.Len()
// Containers filtered by display bool // Containers filtered by display bool
gc.filtered = Containers{} gc.filtered = container.Containers{}
var cursorVisible bool var cursorVisible bool
for _, c := range gc.cSource.All() { for _, c := range gc.cSource.All() {
if c.display { if c.Display {
if c.Id == gc.selectedID { if c.Id == gc.selectedID {
cursorVisible = true cursorVisible = true
} }

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"reflect" "reflect"
"github.com/bcicen/ctop/container"
ui "github.com/gizak/termui" ui "github.com/gizak/termui"
) )
@ -19,7 +20,7 @@ func logEvent(e ui.Event) {
} }
// log container, metrics, and widget state // log container, metrics, and widget state
func dumpContainer(c *Container) { func dumpContainer(c *container.Container) {
msg := fmt.Sprintf("logging state for container: %s\n", c.Id) msg := fmt.Sprintf("logging state for container: %s\n", c.Id)
for k, v := range c.Meta { for k, v := range c.Meta {
msg += fmt.Sprintf("Meta.%s = %s\n", k, v) msg += fmt.Sprintf("Meta.%s = %s\n", k, v)

View File

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/bcicen/ctop/config" "github.com/bcicen/ctop/config"
"github.com/bcicen/ctop/container"
"github.com/bcicen/ctop/cwidgets/expanded" "github.com/bcicen/ctop/cwidgets/expanded"
ui "github.com/gizak/termui" ui "github.com/gizak/termui"
) )
@ -34,7 +35,7 @@ func RedrawRows(clr bool) {
ui.Render(cGrid) ui.Render(cGrid)
} }
func ExpandView(c *Container) { func ExpandView(c *container.Container) {
ui.Clear() ui.Clear()
ui.DefaultEvtStream.ResetHandlers() ui.DefaultEvtStream.ResetHandlers()
defer ui.DefaultEvtStream.ResetHandlers() defer ui.DefaultEvtStream.ResetHandlers()

View File

@ -6,6 +6,7 @@ import (
"os" "os"
"github.com/bcicen/ctop/config" "github.com/bcicen/ctop/config"
"github.com/bcicen/ctop/container"
"github.com/bcicen/ctop/cwidgets/compact" "github.com/bcicen/ctop/cwidgets/compact"
"github.com/bcicen/ctop/logging" "github.com/bcicen/ctop/logging"
"github.com/bcicen/ctop/widgets" "github.com/bcicen/ctop/widgets"
@ -102,7 +103,7 @@ func Shutdown() {
// ensure a given sort field is valid // ensure a given sort field is valid
func validSort(s string) { func validSort(s string) {
if _, ok := Sorters[s]; !ok { if _, ok := container.Sorters[s]; !ok {
fmt.Printf("invalid sort field: %s\n", s) fmt.Printf("invalid sort field: %s\n", s)
os.Exit(1) os.Exit(1)
} }

View File

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/bcicen/ctop/config" "github.com/bcicen/ctop/config"
"github.com/bcicen/ctop/container"
"github.com/bcicen/ctop/widgets" "github.com/bcicen/ctop/widgets"
"github.com/bcicen/ctop/widgets/menu" "github.com/bcicen/ctop/widgets/menu"
ui "github.com/gizak/termui" ui "github.com/gizak/termui"
@ -74,7 +75,7 @@ func SortMenu() {
m.SortItems = true m.SortItems = true
m.BorderLabel = "Sort Field" m.BorderLabel = "Sort Field"
for _, field := range SortFields() { for _, field := range container.SortFields() {
m.AddItems(menu.Item{field, ""}) m.AddItems(menu.Item{field, ""})
} }