Skip to content

Commit

Permalink
Refactor container watching out of raw handler into its own inteface …
Browse files Browse the repository at this point in the history
…/ package
  • Loading branch information
sjpotter committed May 12, 2016
1 parent 9a62ee1 commit e026324
Show file tree
Hide file tree
Showing 14 changed files with 357 additions and 262 deletions.
23 changes: 0 additions & 23 deletions container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,6 @@ const (
ListRecursive
)

// SubcontainerEventType indicates an addition or deletion event.
type SubcontainerEventType int

const (
SubcontainerAdd SubcontainerEventType = iota
SubcontainerDelete
)

// SubcontainerEvent represents a
type SubcontainerEvent struct {
// The type of event that occurred.
EventType SubcontainerEventType

// The full container name of the container where the event occurred.
Name string
}

// Interface for container operation handlers.
type ContainerHandler interface {
// Returns the ContainerReference
Expand All @@ -61,12 +44,6 @@ type ContainerHandler interface {
// Returns the processes inside this container.
ListProcesses(listType ListType) ([]int, error)

// Registers a channel to listen for events affecting subcontainers (recursively).
WatchSubcontainers(events chan SubcontainerEvent) error

// Stops watching for subcontainer changes.
StopWatchingSubcontainers() error

// Returns absolute cgroup path for the requested resource.
GetCgroupPath(resource string) (string, error)

Expand Down
3 changes: 2 additions & 1 deletion container/docker/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/manager/watcher"

docker "github.com/docker/engine-api/client"
"github.com/golang/glog"
Expand Down Expand Up @@ -198,6 +199,6 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics c
ignoreMetrics: ignoreMetrics,
}

container.RegisterContainerHandlerFactory(f)
container.RegisterContainerHandlerFactory(f, []watcher.ContainerWatchSource{watcher.Raw})
return nil
}
9 changes: 0 additions & 9 deletions container/docker/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,15 +331,6 @@ func (self *dockerContainerHandler) ListProcesses(listType container.ListType) (
return containerlibcontainer.GetProcesses(self.cgroupManager)
}

func (self *dockerContainerHandler) WatchSubcontainers(events chan container.SubcontainerEvent) error {
return fmt.Errorf("watch is unimplemented in the Docker container driver")
}

func (self *dockerContainerHandler) StopWatchingSubcontainers() error {
// No-op for Docker driver.
return nil
}

func (self *dockerContainerHandler) Exists() bool {
return common.CgroupExists(self.cgroupPaths)
}
24 changes: 15 additions & 9 deletions container/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"fmt"
"sync"

"github.com/google/cadvisor/manager/watcher"

"github.com/golang/glog"
)

Expand Down Expand Up @@ -67,17 +69,19 @@ func (ms MetricSet) Add(mk MetricKind) {
// TODO(vmarmol): Consider not making this global.
// Global list of factories.
var (
factories []ContainerHandlerFactory
factories = map[watcher.ContainerWatchSource][]ContainerHandlerFactory{}
factoriesLock sync.RWMutex
)

// Register a ContainerHandlerFactory. These should be registered from least general to most general
// as they will be asked in order whether they can handle a particular container.
func RegisterContainerHandlerFactory(factory ContainerHandlerFactory) {
func RegisterContainerHandlerFactory(factory ContainerHandlerFactory, watchTypes []watcher.ContainerWatchSource) {
factoriesLock.Lock()
defer factoriesLock.Unlock()

factories = append(factories, factory)
for _, watchType := range watchTypes {
factories[watchType] = append(factories[watchType], factory)
}
}

// Returns whether there are any container handler factories registered.
Expand All @@ -89,12 +93,12 @@ func HasFactories() bool {
}

// Create a new ContainerHandler for the specified container.
func NewContainerHandler(name string, inHostNamespace bool) (ContainerHandler, bool, error) {
func NewContainerHandler(name string, watchType watcher.ContainerWatchSource, inHostNamespace bool) (ContainerHandler, bool, error) {
factoriesLock.RLock()
defer factoriesLock.RUnlock()

// Create the ContainerHandler with the first factory that supports it.
for _, factory := range factories {
for _, factory := range factories[watchType] {
canHandle, canAccept, err := factory.CanHandleAndAccept(name)
if err != nil {
glog.V(4).Infof("Error trying to work out if we can handle %s: %v", name, err)
Expand All @@ -120,7 +124,7 @@ func ClearContainerHandlerFactories() {
factoriesLock.Lock()
defer factoriesLock.Unlock()

factories = make([]ContainerHandlerFactory, 0, 4)
factories = map[watcher.ContainerWatchSource][]ContainerHandlerFactory{}
}

func DebugInfo() map[string][]string {
Expand All @@ -129,9 +133,11 @@ func DebugInfo() map[string][]string {

// Get debug information for all factories.
out := make(map[string][]string)
for _, factory := range factories {
for k, v := range factory.DebugInfo() {
out[k] = v
for _, factoriesSlice := range factories {
for _, factory := range factoriesSlice {
for k, v := range factory.DebugInfo() {
out[k] = v
}
}
}
return out
Expand Down
24 changes: 13 additions & 11 deletions container/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package container
import (
"testing"

"github.com/google/cadvisor/manager/watcher"

"github.com/stretchr/testify/mock"
)

Expand Down Expand Up @@ -57,7 +59,7 @@ func TestNewContainerHandler_FirstMatches(t *testing.T) {
CanHandleValue: true,
CanAcceptValue: true,
}
RegisterContainerHandlerFactory(allwaysYes)
RegisterContainerHandlerFactory(allwaysYes, []watcher.ContainerWatchSource{watcher.Raw})

// The yes factory should be asked to create the ContainerHandler.
mockContainer, err := mockFactory.NewContainerHandler(testContainerName, true)
Expand All @@ -66,7 +68,7 @@ func TestNewContainerHandler_FirstMatches(t *testing.T) {
}
allwaysYes.On("NewContainerHandler", testContainerName).Return(mockContainer, nil)

cont, _, err := NewContainerHandler(testContainerName, true)
cont, _, err := NewContainerHandler(testContainerName, watcher.Raw, true)
if err != nil {
t.Error(err)
}
Expand All @@ -84,13 +86,13 @@ func TestNewContainerHandler_SecondMatches(t *testing.T) {
CanHandleValue: false,
CanAcceptValue: true,
}
RegisterContainerHandlerFactory(allwaysNo)
RegisterContainerHandlerFactory(allwaysNo, []watcher.ContainerWatchSource{watcher.Raw})
allwaysYes := &mockContainerHandlerFactory{
Name: "yes",
CanHandleValue: true,
CanAcceptValue: true,
}
RegisterContainerHandlerFactory(allwaysYes)
RegisterContainerHandlerFactory(allwaysYes, []watcher.ContainerWatchSource{watcher.Raw})

// The yes factory should be asked to create the ContainerHandler.
mockContainer, err := mockFactory.NewContainerHandler(testContainerName, true)
Expand All @@ -99,7 +101,7 @@ func TestNewContainerHandler_SecondMatches(t *testing.T) {
}
allwaysYes.On("NewContainerHandler", testContainerName).Return(mockContainer, nil)

cont, _, err := NewContainerHandler(testContainerName, true)
cont, _, err := NewContainerHandler(testContainerName, watcher.Raw, true)
if err != nil {
t.Error(err)
}
Expand All @@ -117,15 +119,15 @@ func TestNewContainerHandler_NoneMatch(t *testing.T) {
CanHandleValue: false,
CanAcceptValue: true,
}
RegisterContainerHandlerFactory(allwaysNo1)
RegisterContainerHandlerFactory(allwaysNo1, []watcher.ContainerWatchSource{watcher.Raw})
allwaysNo2 := &mockContainerHandlerFactory{
Name: "no",
CanHandleValue: false,
CanAcceptValue: true,
}
RegisterContainerHandlerFactory(allwaysNo2)
RegisterContainerHandlerFactory(allwaysNo2, []watcher.ContainerWatchSource{watcher.Raw})

_, _, err := NewContainerHandler(testContainerName, true)
_, _, err := NewContainerHandler(testContainerName, watcher.Raw, true)
if err == nil {
t.Error("Expected NewContainerHandler to fail")
}
Expand All @@ -140,15 +142,15 @@ func TestNewContainerHandler_Accept(t *testing.T) {
CanHandleValue: false,
CanAcceptValue: true,
}
RegisterContainerHandlerFactory(cannotHandle)
RegisterContainerHandlerFactory(cannotHandle, []watcher.ContainerWatchSource{watcher.Raw})
cannotAccept := &mockContainerHandlerFactory{
Name: "no",
CanHandleValue: true,
CanAcceptValue: false,
}
RegisterContainerHandlerFactory(cannotAccept)
RegisterContainerHandlerFactory(cannotAccept, []watcher.ContainerWatchSource{watcher.Raw})

_, accept, err := NewContainerHandler(testContainerName, true)
_, accept, err := NewContainerHandler(testContainerName, watcher.Raw, true)
if err != nil {
t.Error("Expected NewContainerHandler to succeed")
}
Expand Down
15 changes: 5 additions & 10 deletions container/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,6 @@ func (self *MockContainerHandler) ListProcesses(listType ListType) ([]int, error
return args.Get(0).([]int), args.Error(1)
}

func (self *MockContainerHandler) WatchSubcontainers(events chan SubcontainerEvent) error {
args := self.Called(events)
return args.Error(0)
}

func (self *MockContainerHandler) StopWatchingSubcontainers() error {
args := self.Called()
return args.Error(0)
}

func (self *MockContainerHandler) Exists() bool {
args := self.Called()
return args.Get(0).(bool)
Expand All @@ -102,6 +92,11 @@ func (self *MockContainerHandler) GetContainerLabels() map[string]string {
return args.Get(0).(map[string]string)
}

func (self *MockContainerHandler) String() string {
args := self.Called()
return args.Get(0).(string)
}

type FactoryForMockContainerHandler struct {
Name string
PrepareContainerHandlerFunc func(name string, handler *MockContainerHandler)
Expand Down
3 changes: 2 additions & 1 deletion container/raw/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/google/cadvisor/container/libcontainer"
"github.com/google/cadvisor/fs"
info "github.com/google/cadvisor/info/v1"
watch "github.com/google/cadvisor/manager/watcher"

"github.com/golang/glog"
)
Expand Down Expand Up @@ -90,6 +91,6 @@ func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, igno
watcher: watcher,
ignoreMetrics: ignoreMetrics,
}
container.RegisterContainerHandlerFactory(factory)
container.RegisterContainerHandlerFactory(factory, []watch.ContainerWatchSource{watch.Raw})
return nil
}
Loading

0 comments on commit e026324

Please sign in to comment.