Files
weave/plugin/watcher.go
T

90 lines
2.0 KiB
Go

package plugin
import (
"fmt"
"strings"
"github.com/fsouza/go-dockerclient"
. "github.com/weaveworks/weave/common"
)
const (
WeaveDNSContainer = "weavedns"
WeaveDomain = "weave.local"
)
type watcher struct {
dockerer
networks map[string]bool
events chan *docker.APIEvents
}
type Watcher interface {
}
func NewWatcher(client *docker.Client) (Watcher, error) {
w := &watcher{
dockerer: dockerer{
client: client,
},
networks: make(map[string]bool),
events: make(chan *docker.APIEvents),
}
err := client.AddEventListener(w.events)
if err != nil {
return nil, err
}
go func() {
for event := range w.events {
switch event.Status {
case "start":
w.ContainerStart(event.ID)
case "die":
w.ContainerDied(event.ID)
}
}
}()
return w, nil
}
func (w *watcher) ContainerStart(id string) {
Log.Debugf("Container started %s", id)
info, err := w.InspectContainer(id)
if err != nil {
Log.Warningf("error inspecting container: %s", err)
return
}
// FIXME: check that it's on our network; but, the docker client lib doesn't know about .NetworkID
if isSubdomain(info.Config.Domainname, WeaveDomain) {
// one of ours
ip := info.NetworkSettings.IPAddress
fqdn := fmt.Sprintf("%s.%s", info.Config.Hostname, info.Config.Domainname)
if err := w.registerWithDNS(id, fqdn, ip); err != nil {
Log.Warningf("unable to register with weaveDNS: %s", err)
}
}
}
func (w *watcher) ContainerDied(id string) {
Log.Debugf("Container died %s", id)
info, err := w.InspectContainer(id)
if err != nil {
Log.Warningf("error inspecting container: %s", err)
return
}
if isSubdomain(info.Config.Domainname, WeaveDomain) {
ip := info.NetworkSettings.IPAddress
if err := w.deregisterWithDNS(id, ip); err != nil {
Log.Warningf("unable to deregister with weaveDNS: %s", err)
}
}
}
// Cheap and cheerful way to check x is, or is a subdomain, of
// y. Neither are expected to start with a '.'.
func isSubdomain(x string, y string) bool {
return x == y || strings.HasSuffix(x, "."+y)
}