83 lines
1.9 KiB
Go
83 lines
1.9 KiB
Go
package docker
|
|
|
|
import (
|
|
"github.com/fsouza/go-dockerclient"
|
|
. "github.com/weaveworks/weave/common"
|
|
)
|
|
|
|
// An observer for container events
|
|
type ContainerObserver interface {
|
|
ContainerStarted(ident string)
|
|
ContainerDied(ident string)
|
|
}
|
|
|
|
type Client struct {
|
|
*docker.Client
|
|
}
|
|
|
|
// NewClient creates a new Docker client and checks we can talk to Docker
|
|
func NewClient(apiPath string) (*Client, error) {
|
|
dc, err := docker.NewClient(apiPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
client := &Client{dc}
|
|
|
|
return client, client.checkWorking(apiPath)
|
|
}
|
|
|
|
func NewVersionedClient(apiPath string, apiVersionString string) (*Client, error) {
|
|
dc, err := docker.NewVersionedClient(apiPath, apiVersionString)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
client := &Client{dc}
|
|
|
|
return client, client.checkWorking(apiPath)
|
|
}
|
|
|
|
func (c *Client) checkWorking(apiPath string) error {
|
|
env, err := c.Version()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
Log.Infof("[docker] Using Docker API on %s: %v", apiPath, env)
|
|
return nil
|
|
}
|
|
|
|
// AddObserver adds an observer for docker events
|
|
func (c *Client) AddObserver(ob ContainerObserver) error {
|
|
events := make(chan *docker.APIEvents)
|
|
if err := c.AddEventListener(events); err != nil {
|
|
Log.Errorf("[docker] Unable to add listener to Docker API: %s", err)
|
|
return err
|
|
}
|
|
|
|
go func() {
|
|
for event := range events {
|
|
switch event.Status {
|
|
case "start":
|
|
id := event.ID
|
|
ob.ContainerStarted(id)
|
|
case "die":
|
|
id := event.ID
|
|
ob.ContainerDied(id)
|
|
}
|
|
}
|
|
}()
|
|
return nil
|
|
}
|
|
|
|
// IsContainerNotRunning returns true if we have checked with Docker that the ID is not running
|
|
func (c *Client) IsContainerNotRunning(idStr string) bool {
|
|
container, err := c.InspectContainer(idStr)
|
|
if err == nil {
|
|
return !container.State.Running
|
|
}
|
|
if _, notThere := err.(*docker.NoSuchContainer); notThere {
|
|
return true
|
|
}
|
|
Log.Errorf("[docker] Could not check container status: %s", err)
|
|
return false
|
|
}
|