From 5cb2347f7716f89ae83c67acd6f23a34342fa38c Mon Sep 17 00:00:00 2001 From: Alvaro Saurin Date: Fri, 5 Jun 2015 13:03:21 +0200 Subject: [PATCH] Use our own Docker client --- common/docker/client.go | 85 +++++++++++++++++++++++++++++++++++++++ common/updater/updater.go | 47 ---------------------- prog/weavedns/main.go | 13 ++++-- prog/weaver/main.go | 11 +++-- 4 files changed, 102 insertions(+), 54 deletions(-) create mode 100644 common/docker/client.go delete mode 100644 common/updater/updater.go diff --git a/common/docker/client.go b/common/docker/client.go new file mode 100644 index 00000000..93f548a1 --- /dev/null +++ b/common/docker/client.go @@ -0,0 +1,85 @@ +package docker + +import ( + "regexp" + + "github.com/fsouza/go-dockerclient" + . "github.com/weaveworks/weave/common" +) + +// Regexp that matches container IDs +var containerIDregexp = regexp.MustCompile("^[a-f0-9]+$") + +// IsContainerID returns True if the string provided is a valid container id +func IsContainerID(idStr string) bool { + return containerIDregexp.MatchString(idStr) +} + +// An observer for container events +type ContainerObserver interface { + ContainerDied(ident string) error +} + +type Client struct { + *docker.Client +} + +// NewClient creates a new Docker client +func NewClient(apiPath string) (*Client, error) { + dc, err := docker.NewClient(apiPath) + if err != nil { + return nil, err + } + return &Client{dc}, nil +} + +// Start starts the client +func (c *Client) Start(apiPath string) error { + client, err := docker.NewClient(apiPath) + if err != nil { + Error.Printf("[docker] Unable to connect to Docker API on %s: %s", apiPath, err) + return err + } + + env, err := client.Version() + if err != nil { + Error.Printf("[docker] Unable to connect to Docker API on %s: %s", apiPath, err) + return err + } + Info.Printf("[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 { + Error.Printf("[docker] Unable to add listener to Docker API: %s", err) + return err + } + + go func() { + for event := range events { + switch event.Status { + case "die": + id := event.ID + ob.ContainerDied(id) + } + } + }() + return nil +} + +// IsContainerRunning returns true if the container is up and running +func (c *Client) IsContainerRunning(idStr string) (bool, error) { + // check with Docker whether the container is really running + container, err := c.InspectContainer(idStr) + if err != nil { + if _, notThere := err.(*docker.NoSuchContainer); notThere { + return false, nil + } + return false, err + } + + return container.State.Running, nil +} diff --git a/common/updater/updater.go b/common/updater/updater.go deleted file mode 100644 index f46a0dea..00000000 --- a/common/updater/updater.go +++ /dev/null @@ -1,47 +0,0 @@ -package updater - -import ( - "github.com/fsouza/go-dockerclient" - . "github.com/weaveworks/weave/common" -) - -type ContainerObserver interface { - ContainerDied(ident string) error -} - -func checkError(err error, apiPath string) { - if err != nil { - Error.Fatalf("[updater] Unable to connect to Docker API on %s: %s", - apiPath, err) - } -} - -func Start(apiPath string, ob ContainerObserver) error { - client, err := docker.NewClient(apiPath) - checkError(err, apiPath) - - env, err := client.Version() - checkError(err, apiPath) - - events := make(chan *docker.APIEvents) - err = client.AddEventListener(events) - checkError(err, apiPath) - - Info.Printf("[updater] Using Docker API on %s: %v", apiPath, env) - - go func() { - for event := range events { - handleEvent(ob, event, client) - } - }() - return nil -} - -func handleEvent(ob ContainerObserver, event *docker.APIEvents, client *docker.Client) error { - switch event.Status { - case "die": - id := event.ID - ob.ContainerDied(id) - } - return nil -} diff --git a/prog/weavedns/main.go b/prog/weavedns/main.go index 9b6ab270..81bc3f7b 100644 --- a/prog/weavedns/main.go +++ b/prog/weavedns/main.go @@ -8,7 +8,7 @@ import ( "github.com/miekg/dns" . "github.com/weaveworks/weave/common" - "github.com/weaveworks/weave/common/updater" + "github.com/weaveworks/weave/common/docker" weavedns "github.com/weaveworks/weave/nameserver" weavenet "github.com/weaveworks/weave/net" ) @@ -18,6 +18,7 @@ var version = "(unreleased version)" func main() { var ( justVersion bool + dockerCli *docker.Client ifaceName string apiPath string domain string @@ -95,14 +96,18 @@ func main() { if err != nil { Error.Fatal("[main] Unable to initialize the Zone database", err) } - err = zone.Start() - if err != nil { + if err := zone.Start(); err != nil { Error.Fatal("[main] Unable to start the Zone database", err) } defer zone.Stop() + dockerCli, err = docker.NewClient(apiPath) + if err != nil { + Error.Fatal("[main] Unable to start docker client", err) + } + if watch { - err := updater.Start(apiPath, zone) + err := dockerCli.AddObserver(zone) if err != nil { Error.Fatal("[main] Unable to start watcher", err) } diff --git a/prog/weaver/main.go b/prog/weaver/main.go index 0ce26cd3..984becb7 100644 --- a/prog/weaver/main.go +++ b/prog/weaver/main.go @@ -15,7 +15,7 @@ import ( "github.com/davecheney/profile" "github.com/gorilla/mux" . "github.com/weaveworks/weave/common" - "github.com/weaveworks/weave/common/updater" + "github.com/weaveworks/weave/common/docker" "github.com/weaveworks/weave/ipam" "github.com/weaveworks/weave/ipam/address" weavenet "github.com/weaveworks/weave/net" @@ -222,10 +222,15 @@ func createAllocator(router *weave.Router, apiPath string, ipRangeStr string, de allocator.SetInterfaces(router.NewGossip("IPallocation", allocator)) allocator.Start() - err := updater.Start(apiPath, allocator) + + dockerCli, err := docker.NewClient(apiPath) if err != nil { - log.Fatal("Unable to start watcher", err) + Error.Fatal("Unable to start docker client", err) } + if err = dockerCli.AddObserver(allocator); err != nil { + Error.Fatal("Unable to start watcher", err) + } + return allocator, defaultSubnet }