Moved updater into server
While we're only reacting to containers going away, it's more convenient to bundle the docker events watcher into the server. I've added a flag to switch it on; and switched it on by default in the container. I also implemented `Zone.DeleteRecordsFor(ident)`, which removes all records for a particular container. One minor change to the structure of the code is that the Zone is now constructed *outside* the server, and given to it and the updater.
This commit is contained in:
1 parent
0fb4bce24d
commit
0749460652
9 files changed
+102
-72
No files matched your search
+1
-1
@@ -2,4 +2,4 @@ FROM scratch
|
||||
# EXPOSE 53/udp
|
||||
WORKDIR /home/weave
|
||||
ADD ./weavedns /home/weave/
|
||||
ENTRYPOINT ["/home/weave/weavedns", "-wait", "5", "-iface", "ethwe"]
|
||||
ENTRYPOINT ["/home/weave/weavedns", "-wait", "5", "-iface", "ethwe", "--watch", "--api", "unix:///var/run/docker.sock"]
|
||||
+4
-13
@@ -1,28 +1,19 @@
|
||||
.DEFAULT: all
|
||||
|
||||
all: server-image updater-image
|
||||
all: server-image
|
||||
|
||||
weavedns: ../server/*.go ../main.go
|
||||
go get -tags netgo ../ && go build -tags netgo -ldflags '-linkmode external -extldflags "-static"' -o $@ -v ../
|
||||
|
||||
updater: ../updater/main.go
|
||||
go get -tags netgo ../updater/ && go build -tags netgo -ldflags '-linkmode external -extldflags "-static"' -o $@ -v ../updater/
|
||||
.PHONY: server-image
|
||||
|
||||
.PHONY: server-image updater-image
|
||||
|
||||
updater-image: /var/tmp/updater.tar
|
||||
server-image: /var/tmp/weavedns.tar
|
||||
|
||||
/var/tmp/weavedns.tar: Dockerfile weavedns
|
||||
sudo -E docker build -t zettio/weavedns .
|
||||
sudo -E docker save zettio/weavedns > $@
|
||||
|
||||
/var/tmp/updater.tar: ../updater/Dockerfile updater
|
||||
sudo -E docker build -t zettio/updater ../updater/
|
||||
sudo -E docker save zettio/updater > $@
|
||||
|
||||
clean:
|
||||
-sudo docker rmi zettio/weavedns
|
||||
-sudo docker rmi zettio/updater
|
||||
rm -f weavedns updater
|
||||
rm -f /var/tmp/{updater,weavedns}.tar
|
||||
rm -f weavedns
|
||||
rm -f /var/tmp/weavedns.tar
|
||||
@@ -9,18 +9,31 @@ import (
|
||||
func main() {
|
||||
var (
|
||||
ifaceName string
|
||||
apiPath string
|
||||
dnsPort int
|
||||
httpPort int
|
||||
wait int
|
||||
watch bool
|
||||
)
|
||||
|
||||
flag.StringVar(&ifaceName, "iface", "", "name of interface to use for multicast")
|
||||
flag.StringVar(&apiPath, "api", "unix:///var/run/docker.sock", "Path to Docker API socket")
|
||||
flag.IntVar(&wait, "wait", 0, "number of seconds to wait for interface to be created and come up (defaults to 0)")
|
||||
flag.IntVar(&dnsPort, "dnsport", 53, "port to listen to dns requests (defaults to 53)")
|
||||
flag.IntVar(&httpPort, "httpport", 6785, "port to listen to HTTP requests (defaults to 6785)")
|
||||
flag.BoolVar(&watch, "watch", false, "watch the docker socket for container events")
|
||||
flag.Parse()
|
||||
|
||||
err := weavedns.StartServer(ifaceName, dnsPort, httpPort, wait)
|
||||
var zone = new(weavedns.ZoneDb)
|
||||
|
||||
if watch {
|
||||
err := weavedns.StartUpdater(apiPath, zone)
|
||||
if err != nil {
|
||||
log.Fatal("Unable to start watcher", err)
|
||||
}
|
||||
}
|
||||
|
||||
err := weavedns.StartServer(zone, ifaceName, dnsPort, httpPort, wait)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to start server: %s", err)
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ import (
|
||||
type MDNSServer struct {
|
||||
localAddrs []net.Addr
|
||||
sendconn *net.UDPConn
|
||||
zone *ZoneDb
|
||||
zone Zone
|
||||
}
|
||||
|
||||
func NewMDNSServer(zone *ZoneDb) (*MDNSServer, error) {
|
||||
func NewMDNSServer(zone Zone) (*MDNSServer, error) {
|
||||
//log.Println("minimalServer sending:", buf)
|
||||
// This is a bit of a kludge - per the RFC we should send responses from 5353, but that doesn't seem to work
|
||||
sendconn, err := net.ListenUDP("udp4", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
|
||||
|
||||
+1
-2
@@ -100,9 +100,8 @@ func notUsHandler() dns.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func StartServer(ifaceName string, dnsPort int, httpPort int, wait int) error {
|
||||
func StartServer(zone Zone, ifaceName string, dnsPort int, httpPort int, wait int) error {
|
||||
|
||||
var zone = new(ZoneDb)
|
||||
go ListenHttp(zone, httpPort)
|
||||
|
||||
var iface *net.Interface = nil
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package weavedns
|
||||
|
||||
import (
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
"log"
|
||||
)
|
||||
|
||||
func StartUpdater(apiPath string, zone Zone) error {
|
||||
client, err := docker.NewClient(apiPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to connect to Docker API on %s: %s", apiPath, err)
|
||||
}
|
||||
|
||||
events := make(chan *docker.APIEvents)
|
||||
client.AddEventListener(events)
|
||||
|
||||
log.Printf("Using Docker API on %s", apiPath)
|
||||
|
||||
go func() {
|
||||
for event := range events {
|
||||
handleEvent(zone, event, client)
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleEvent(zone Zone, event *docker.APIEvents, client *docker.Client) error {
|
||||
switch event.Status {
|
||||
case "die":
|
||||
id := event.ID
|
||||
zone.DeleteRecordsFor(id)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
type Zone interface {
|
||||
AddRecord(string, string, net.IP, net.IP, *net.IPNet) error
|
||||
DeleteRecord(ident string, weave_ip net.IP) error
|
||||
DeleteRecordsFor(ident string) error
|
||||
MatchLocal(string) (net.IP, error)
|
||||
}
|
||||
|
||||
@@ -99,3 +100,18 @@ func (zone *ZoneDb) DeleteRecord(ident string, weave_ip net.IP) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (zone *ZoneDb) DeleteRecordsFor(ident string) error {
|
||||
zone.mx.Lock()
|
||||
defer zone.mx.Unlock()
|
||||
w := 0 // write index
|
||||
|
||||
for _, r := range zone.recs {
|
||||
if r.Ident != ident {
|
||||
zone.recs[w] = r
|
||||
w++
|
||||
}
|
||||
}
|
||||
zone.recs = zone.recs[:w]
|
||||
return nil
|
||||
}
|
||||
@@ -48,4 +48,34 @@ func TestZone(t *testing.T) {
|
||||
if _, ok := err.(LookupError); !ok {
|
||||
t.Fatal("Unexpected result when deleting record", success_test_name, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDeleteFor(t *testing.T) {
|
||||
var (
|
||||
id = "foobar"
|
||||
name = "foo.weave."
|
||||
addr1 = "10.1.2.3/24"
|
||||
addr2 = "10.2.7.8/24"
|
||||
docker_ip = "172.16.0.4"
|
||||
)
|
||||
zone := new(ZoneDb)
|
||||
ip := net.ParseIP(docker_ip)
|
||||
for _, addr := range []string{addr1, addr2} {
|
||||
weave_ip, subnet, _ := net.ParseCIDR(addr)
|
||||
err := zone.AddRecord(id, name, ip, weave_ip, subnet)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
_, err := zone.MatchLocal(name)
|
||||
if err != nil {
|
||||
t.Fatal("Did not get result for lookup")
|
||||
}
|
||||
err = zone.DeleteRecordsFor(id)
|
||||
_, err = zone.MatchLocal(name)
|
||||
if _, ok := err.(LookupError); !ok {
|
||||
t.Fatal("Expected no results after deleting records for ident")
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var (
|
||||
updatePath string
|
||||
apiPath string
|
||||
)
|
||||
flag.StringVar(&updatePath, "endpoint", "", "Endpoint to which to send updates")
|
||||
flag.StringVar(&apiPath, "api", "unix:///var/run/docker.sock", "Path to Docker API socket")
|
||||
flag.Parse()
|
||||
|
||||
// TODO: check status on endpoint
|
||||
|
||||
client, err := docker.NewClient(apiPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to connect to Docker API on %s: %s", apiPath, err)
|
||||
}
|
||||
|
||||
events := make(chan *docker.APIEvents)
|
||||
done := make(chan bool)
|
||||
client.AddEventListener(events)
|
||||
|
||||
log.Printf("Using Docker API on %s", apiPath)
|
||||
log.Printf("Posting updates to ", updatePath)
|
||||
|
||||
go func() {
|
||||
for event := range events {
|
||||
handleEvent(event, client, updatePath)
|
||||
}
|
||||
done <- true
|
||||
}()
|
||||
<-done
|
||||
}
|
||||
|
||||
func handleEvent(event *docker.APIEvents, client *docker.Client, endpoint string) error {
|
||||
switch event.Status {
|
||||
case "die":
|
||||
id := event.ID
|
||||
url := fmt.Sprintf("%s/name/%s", endpoint, id)
|
||||
client := &http.Client{}
|
||||
req, _ := http.NewRequest("DELETE", url, nil)
|
||||
client.Do(req)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user