Track endpoints so we can register the right address with DNS
This commit is contained in:
1 parent
5eb99fe5ef
commit
a22b88ed89
2 files changed
+42
-37
No files matched your search
+27
-9
@@ -2,6 +2,7 @@ package plugin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/libnetwork/drivers/remote/api"
|
||||
"github.com/docker/libnetwork/types"
|
||||
@@ -22,6 +23,8 @@ const (
|
||||
type driver struct {
|
||||
version string
|
||||
nameserver string
|
||||
sync.RWMutex
|
||||
endpoints map[string]struct{}
|
||||
}
|
||||
|
||||
func New(version string, nameserver string) (skel.Driver, error) {
|
||||
@@ -30,15 +33,17 @@ func New(version string, nameserver string) (skel.Driver, error) {
|
||||
return nil, errorf("could not connect to docker: %s", err)
|
||||
}
|
||||
|
||||
_, err = NewWatcher(client)
|
||||
driver := &driver{
|
||||
nameserver: nameserver,
|
||||
version: version,
|
||||
endpoints: make(map[string]struct{}),
|
||||
}
|
||||
|
||||
_, err = NewWatcher(client, driver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &driver{
|
||||
nameserver: nameserver,
|
||||
version: version,
|
||||
}, nil
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
func errorf(format string, a ...interface{}) error {
|
||||
@@ -76,18 +81,31 @@ func (driver *driver) CreateEndpoint(create *api.CreateEndpointRequest) (*api.Cr
|
||||
if create.Interface == nil {
|
||||
return nil, fmt.Errorf("Not supported: creating an interface from within CreateEndpoint")
|
||||
}
|
||||
driver.Lock()
|
||||
driver.endpoints[endID] = struct{}{}
|
||||
driver.Unlock()
|
||||
resp := &api.CreateEndpointResponse{}
|
||||
|
||||
Log.Infof("Create endpoint %s %+v", endID, resp)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (driver *driver) DeleteEndpoint(delete *api.DeleteEndpointRequest) error {
|
||||
Log.Debugf("Delete endpoint request: %+v", delete)
|
||||
Log.Infof("Delete endpoint %s", delete.EndpointID)
|
||||
func (driver *driver) DeleteEndpoint(deleteReq *api.DeleteEndpointRequest) error {
|
||||
Log.Debugf("Delete endpoint request: %+v", deleteReq)
|
||||
Log.Infof("Delete endpoint %s", deleteReq.EndpointID)
|
||||
driver.Lock()
|
||||
delete(driver.endpoints, deleteReq.EndpointID)
|
||||
driver.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (driver *driver) HasEndpoint(endpointID string) bool {
|
||||
driver.Lock()
|
||||
_, found := driver.endpoints[endpointID]
|
||||
driver.Unlock()
|
||||
return found
|
||||
}
|
||||
|
||||
func (driver *driver) EndpointInfo(req *api.EndpointInfoRequest) (*api.EndpointInfoResponse, error) {
|
||||
Log.Debugf("Endpoint info request: %+v", req)
|
||||
Log.Infof("Endpoint info %s", req.EndpointID)
|
||||
|
||||
+15
-28
@@ -2,7 +2,6 @@ package plugin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
weaveapi "github.com/weaveworks/weave/api"
|
||||
. "github.com/weaveworks/weave/common"
|
||||
@@ -16,13 +15,14 @@ const (
|
||||
type watcher struct {
|
||||
client *docker.Client
|
||||
weave *weaveapi.Client
|
||||
driver *driver
|
||||
}
|
||||
|
||||
type Watcher interface {
|
||||
}
|
||||
|
||||
func NewWatcher(client *docker.Client) (Watcher, error) {
|
||||
w := &watcher{client: client}
|
||||
func NewWatcher(client *docker.Client, driver *driver) (Watcher, error) {
|
||||
w := &watcher{client: client, driver: driver}
|
||||
err := client.AddObserver(w)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -50,34 +50,21 @@ func (w *watcher) ContainerStarted(id string) {
|
||||
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) && w.haveWeaveClient() {
|
||||
// one of ours
|
||||
ip := info.NetworkSettings.IPAddress
|
||||
fqdn := fmt.Sprintf("%s.%s", info.Config.Hostname, info.Config.Domainname)
|
||||
if err := w.weave.RegisterWithDNS(id, fqdn, ip); err != nil {
|
||||
Log.Warningf("unable to register with weaveDNS: %s", err)
|
||||
if !w.haveWeaveClient() {
|
||||
return
|
||||
}
|
||||
// check that it's on our network, via the endpointID
|
||||
for _, net := range info.NetworkSettings.Networks {
|
||||
if w.driver.HasEndpoint(net.EndpointID) {
|
||||
fqdn := fmt.Sprintf("%s.%s", info.Config.Hostname, info.Config.Domainname)
|
||||
if err := w.weave.RegisterWithDNS(id, fqdn, net.IPAddress); 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.client.InspectContainer(id)
|
||||
if err != nil {
|
||||
Log.Warningf("error inspecting container: %s", err)
|
||||
return
|
||||
}
|
||||
if isSubdomain(info.Config.Domainname, WeaveDomain) && w.haveWeaveClient() {
|
||||
ip := info.NetworkSettings.IPAddress
|
||||
if err := w.weave.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)
|
||||
// don't need to do this as WeaveDNS removes names on container died anyway
|
||||
// (note by the time we get this event we can't see the EndpointID)
|
||||
}
|
||||
Reference in new issue
Block a user