Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab5f4410b6 | ||
|
|
3abb657777 | ||
|
|
4dd63d8f72 | ||
|
|
79dc464b83 | ||
|
|
3dbd5b11d8 | ||
|
|
0ab5c65185 | ||
|
|
e57ccdc858 | ||
|
|
a73a65b48a | ||
|
|
7c4af88911 | ||
|
|
0aca173e96 | ||
|
|
e95e3cc29d | ||
|
|
67e9310cc1 | ||
|
|
861bf953bf | ||
|
|
06eaac8690 | ||
|
|
6b9e8816d1 | ||
|
|
08e043fea7 | ||
|
|
54ba1009d3 | ||
|
|
8742957f75 | ||
|
|
ace372cfc6 | ||
|
|
27c5f5f49f | ||
|
|
ec5a1a3977 | ||
|
|
77c7963bde | ||
|
|
b80c1343c3 | ||
|
|
e5c5fbcea3 | ||
|
|
fc7d04ce73 | ||
|
|
35f57b3ed2 | ||
|
|
ed9ade05ea | ||
|
|
f485b729bc | ||
|
|
64f7953423 | ||
|
|
fc1d837501 | ||
|
|
9800c43bfa | ||
|
|
b3cda39b0b | ||
|
|
ccae8d42fd | ||
|
|
38f78286c7 | ||
|
|
2bbe6a2ad8 | ||
|
|
f64f63f675 | ||
|
|
f0fb44f6d4 | ||
|
|
fa972615e6 | ||
|
|
f7cb2ef25d | ||
|
|
949f8bb2e7 | ||
|
|
5eaff802d4 | ||
|
|
a6336149f8 | ||
|
|
ca6bce3820 | ||
|
|
9b4f2297b0 | ||
|
|
a31b2876d0 | ||
|
|
b697b6e57b | ||
|
|
4792fe6391 | ||
|
|
7408f72de2 | ||
|
|
3a029686e3 | ||
|
|
9fa7b3956d | ||
|
|
b888ace508 | ||
|
|
2e54efe34d |
No files matched your search
@@ -39,6 +39,7 @@ prog/weavehosts/weavehosts
|
|||||||
prog/weaveproxy/weaveproxy
|
prog/weaveproxy/weaveproxy
|
||||||
prog/sigproxy/sigproxy
|
prog/sigproxy/sigproxy
|
||||||
prog/weavewait/weavewait
|
prog/weavewait/weavewait
|
||||||
|
prog/weavewait/weavewait_noop
|
||||||
prog/netcheck/netcheck
|
prog/netcheck/netcheck
|
||||||
prog/docker_tls_args/docker_tls_args
|
prog/docker_tls_args/docker_tls_args
|
||||||
testing/cover/cover
|
testing/cover/cover
|
||||||
@@ -52,6 +53,7 @@ prog/weaveexec/weave
|
|||||||
prog/weaveexec/weavehosts
|
prog/weaveexec/weavehosts
|
||||||
prog/weaveexec/weaveproxy
|
prog/weaveexec/weaveproxy
|
||||||
prog/weaveexec/weavewait
|
prog/weaveexec/weavewait
|
||||||
|
prog/weaveexec/weavewait_noop
|
||||||
prog/weaveexec/sigproxy
|
prog/weaveexec/sigproxy
|
||||||
prog/weaveexec/netcheck
|
prog/weaveexec/netcheck
|
||||||
prog/weaveexec/docker_tls_args
|
prog/weaveexec/docker_tls_args
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
## Release 1.2.1
|
||||||
|
|
||||||
|
This release contains a number of bug fixes and minor
|
||||||
|
enhancements. More details in the
|
||||||
|
[change log](https://github.com/weaveworks/weave/issues?q=milestone%3A1.2.1).
|
||||||
|
|
||||||
|
The release is fully compatible with 1.2.0 versions, so existing
|
||||||
|
clusters can be upgraded incrementally.
|
||||||
|
|
||||||
## Release 1.2.0
|
## Release 1.2.0
|
||||||
|
|
||||||
**Highlights**
|
**Highlights**
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ WEAVER_EXE=prog/weaver/weaver
|
|||||||
WEAVEPROXY_EXE=prog/weaveproxy/weaveproxy
|
WEAVEPROXY_EXE=prog/weaveproxy/weaveproxy
|
||||||
SIGPROXY_EXE=prog/sigproxy/sigproxy
|
SIGPROXY_EXE=prog/sigproxy/sigproxy
|
||||||
WEAVEWAIT_EXE=prog/weavewait/weavewait
|
WEAVEWAIT_EXE=prog/weavewait/weavewait
|
||||||
|
WEAVEWAIT_NOOP_EXE=prog/weavewait/weavewait_noop
|
||||||
NETCHECK_EXE=prog/netcheck/netcheck
|
NETCHECK_EXE=prog/netcheck/netcheck
|
||||||
DOCKERTLSARGS_EXE=prog/docker_tls_args/docker_tls_args
|
DOCKERTLSARGS_EXE=prog/docker_tls_args/docker_tls_args
|
||||||
RUNNER_EXE=testing/runner/runner
|
RUNNER_EXE=testing/runner/runner
|
||||||
|
|
||||||
EXES=$(WEAVER_EXE) $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(NETCHECK_EXE) $(DOCKERTLSARGS_EXE) $(RUNNER_EXE)
|
EXES=$(WEAVER_EXE) $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(WEAVEWAIT_NOOP_EXE) $(NETCHECK_EXE) $(DOCKERTLSARGS_EXE) $(RUNNER_EXE)
|
||||||
|
|
||||||
WEAVER_UPTODATE=.weaver.uptodate
|
WEAVER_UPTODATE=.weaver.uptodate
|
||||||
WEAVEEXEC_UPTODATE=.weaveexec.uptodate
|
WEAVEEXEC_UPTODATE=.weaveexec.uptodate
|
||||||
@@ -76,7 +77,7 @@ $(NETCHECK_EXE): prog/netcheck/netcheck.go
|
|||||||
# Sigproxy and weavewait need separate rules as they fail the netgo check in
|
# Sigproxy and weavewait need separate rules as they fail the netgo check in
|
||||||
# the main build stanza due to not importing net package
|
# the main build stanza due to not importing net package
|
||||||
$(SIGPROXY_EXE): prog/sigproxy/main.go
|
$(SIGPROXY_EXE): prog/sigproxy/main.go
|
||||||
$(WEAVEWAIT_EXE): prog/weavewait/main.go net/*.go
|
$(WEAVEWAIT_EXE): prog/weavewait/*.go net/*.go
|
||||||
$(RUNNER_EXE): testing/runner/runner.go
|
$(RUNNER_EXE): testing/runner/runner.go
|
||||||
$(DOCKERTLSARGS_EXE): prog/docker_tls_args/*.go
|
$(DOCKERTLSARGS_EXE): prog/docker_tls_args/*.go
|
||||||
|
|
||||||
@@ -84,15 +85,20 @@ $(WEAVEWAIT_EXE) $(SIGPROXY_EXE) $(RUNNER_EXE) $(DOCKERTLSARGS_EXE):
|
|||||||
go get -tags netgo ./$(@D)
|
go get -tags netgo ./$(@D)
|
||||||
go build $(BUILD_FLAGS) -o $@ ./$(@D)
|
go build $(BUILD_FLAGS) -o $@ ./$(@D)
|
||||||
|
|
||||||
|
$(WEAVEWAIT_NOOP_EXE): prog/weavewait/*.go
|
||||||
|
go get -tags netgo ./$(@D)
|
||||||
|
go build $(BUILD_FLAGS) -tags noop -o $@ ./$(@D)
|
||||||
|
|
||||||
$(WEAVER_UPTODATE): prog/weaver/Dockerfile $(WEAVER_EXE)
|
$(WEAVER_UPTODATE): prog/weaver/Dockerfile $(WEAVER_EXE)
|
||||||
$(SUDO) docker build -t $(WEAVER_IMAGE) prog/weaver
|
$(SUDO) docker build -t $(WEAVER_IMAGE) prog/weaver
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
$(WEAVEEXEC_UPTODATE): prog/weaveexec/Dockerfile $(DOCKER_DISTRIB) weave $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(NETCHECK_EXE) $(DOCKERTLSARGS_EXE)
|
$(WEAVEEXEC_UPTODATE): prog/weaveexec/Dockerfile $(DOCKER_DISTRIB) weave $(SIGPROXY_EXE) $(WEAVEPROXY_EXE) $(WEAVEWAIT_EXE) $(WEAVEWAIT_NOOP_EXE) $(NETCHECK_EXE) $(DOCKERTLSARGS_EXE)
|
||||||
cp weave prog/weaveexec/weave
|
cp weave prog/weaveexec/weave
|
||||||
cp $(SIGPROXY_EXE) prog/weaveexec/sigproxy
|
cp $(SIGPROXY_EXE) prog/weaveexec/sigproxy
|
||||||
cp $(WEAVEPROXY_EXE) prog/weaveexec/weaveproxy
|
cp $(WEAVEPROXY_EXE) prog/weaveexec/weaveproxy
|
||||||
cp $(WEAVEWAIT_EXE) prog/weaveexec/weavewait
|
cp $(WEAVEWAIT_EXE) prog/weaveexec/weavewait
|
||||||
|
cp $(WEAVEWAIT_NOOP_EXE) prog/weaveexec/weavewait_noop
|
||||||
cp $(NETCHECK_EXE) prog/weaveexec/netcheck
|
cp $(NETCHECK_EXE) prog/weaveexec/netcheck
|
||||||
cp $(DOCKERTLSARGS_EXE) prog/weaveexec/docker_tls_args
|
cp $(DOCKERTLSARGS_EXE) prog/weaveexec/docker_tls_args
|
||||||
cp $(DOCKER_DISTRIB) prog/weaveexec/docker.tgz
|
cp $(DOCKER_DISTRIB) prog/weaveexec/docker.tgz
|
||||||
|
|||||||
+40
-12
@@ -55,19 +55,21 @@ type Allocator struct {
|
|||||||
paxos *paxos.Node
|
paxos *paxos.Node
|
||||||
paxosTicker *time.Ticker
|
paxosTicker *time.Ticker
|
||||||
shuttingDown bool // to avoid doing any requests while trying to shut down
|
shuttingDown bool // to avoid doing any requests while trying to shut down
|
||||||
|
isKnownPeer func(router.PeerName) bool
|
||||||
now func() time.Time
|
now func() time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAllocator creates and initialises a new Allocator
|
// NewAllocator creates and initialises a new Allocator
|
||||||
func NewAllocator(ourName router.PeerName, ourUID router.PeerUID, ourNickname string, universe address.Range, quorum uint) *Allocator {
|
func NewAllocator(ourName router.PeerName, ourUID router.PeerUID, ourNickname string, universe address.Range, quorum uint, isKnownPeer func(name router.PeerName) bool) *Allocator {
|
||||||
return &Allocator{
|
return &Allocator{
|
||||||
ourName: ourName,
|
ourName: ourName,
|
||||||
universe: universe,
|
universe: universe,
|
||||||
ring: ring.New(universe.Start, universe.End, ourName),
|
ring: ring.New(universe.Start, universe.End, ourName),
|
||||||
owned: make(map[string][]address.Address),
|
owned: make(map[string][]address.Address),
|
||||||
paxos: paxos.NewNode(ourName, ourUID, quorum),
|
paxos: paxos.NewNode(ourName, ourUID, quorum),
|
||||||
nicknames: map[router.PeerName]string{ourName: ourNickname},
|
nicknames: map[router.PeerName]string{ourName: ourNickname},
|
||||||
now: time.Now,
|
isKnownPeer: isKnownPeer,
|
||||||
|
now: time.Now,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,6 +276,33 @@ func (alloc *Allocator) Free(ident string, addrToFree address.Address) error {
|
|||||||
return <-errChan
|
return <-errChan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (alloc *Allocator) pickPeerFromNicknames(isValid func(router.PeerName) bool) router.PeerName {
|
||||||
|
for name := range alloc.nicknames {
|
||||||
|
if name != alloc.ourName && isValid(name) {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return router.UnknownPeerName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (alloc *Allocator) pickPeerForTransfer() router.PeerName {
|
||||||
|
// first try alive peers that actively participate in IPAM (i.e. have entries)
|
||||||
|
if heir := alloc.ring.PickPeerForTransfer(alloc.isKnownPeer); heir != router.UnknownPeerName {
|
||||||
|
return heir
|
||||||
|
}
|
||||||
|
// next try alive peers that have IPAM enabled but have no entries
|
||||||
|
if heir := alloc.pickPeerFromNicknames(alloc.isKnownPeer); heir != router.UnknownPeerName {
|
||||||
|
return heir
|
||||||
|
}
|
||||||
|
// next try disappeared peers that still have entries
|
||||||
|
t := func(router.PeerName) bool { return true }
|
||||||
|
if heir := alloc.ring.PickPeerForTransfer(t); heir != router.UnknownPeerName {
|
||||||
|
return heir
|
||||||
|
}
|
||||||
|
// finally, disappeared peers that that passively participated in IPAM
|
||||||
|
return alloc.pickPeerFromNicknames(t)
|
||||||
|
}
|
||||||
|
|
||||||
// Shutdown (Sync)
|
// Shutdown (Sync)
|
||||||
func (alloc *Allocator) Shutdown() {
|
func (alloc *Allocator) Shutdown() {
|
||||||
alloc.infof("Shutdown")
|
alloc.infof("Shutdown")
|
||||||
@@ -282,7 +311,7 @@ func (alloc *Allocator) Shutdown() {
|
|||||||
alloc.shuttingDown = true
|
alloc.shuttingDown = true
|
||||||
alloc.cancelOps(&alloc.pendingClaims)
|
alloc.cancelOps(&alloc.pendingClaims)
|
||||||
alloc.cancelOps(&alloc.pendingAllocates)
|
alloc.cancelOps(&alloc.pendingAllocates)
|
||||||
if heir := alloc.ring.PickPeerForTransfer(); heir != router.UnknownPeerName {
|
if heir := alloc.pickPeerForTransfer(); heir != router.UnknownPeerName {
|
||||||
alloc.ring.Transfer(alloc.ourName, heir)
|
alloc.ring.Transfer(alloc.ourName, heir)
|
||||||
alloc.space.Clear()
|
alloc.space.Clear()
|
||||||
alloc.gossip.GossipBroadcast(alloc.Gossip())
|
alloc.gossip.GossipBroadcast(alloc.Gossip())
|
||||||
@@ -310,7 +339,6 @@ func (alloc *Allocator) AdminTakeoverRanges(peerNameOrNickname string) error {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(alloc.nicknames, peername)
|
|
||||||
newRanges, err := alloc.ring.Transfer(peername, alloc.ourName)
|
newRanges, err := alloc.ring.Transfer(peername, alloc.ourName)
|
||||||
alloc.space.AddRanges(newRanges)
|
alloc.space.AddRanges(newRanges)
|
||||||
resultChan <- err
|
resultChan <- err
|
||||||
@@ -332,11 +360,11 @@ func (alloc *Allocator) lookupPeername(name string) (router.PeerName, error) {
|
|||||||
return router.PeerNameFromString(name)
|
return router.PeerNameFromString(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restrict the peers in "nicknames" to those in the ring and our own
|
// Restrict the peers in "nicknames" to those in the ring plus peers known to the router
|
||||||
func (alloc *Allocator) pruneNicknames() {
|
func (alloc *Allocator) pruneNicknames() {
|
||||||
ringPeers := alloc.ring.PeerNames()
|
ringPeers := alloc.ring.PeerNames()
|
||||||
for name := range alloc.nicknames {
|
for name := range alloc.nicknames {
|
||||||
if _, ok := ringPeers[name]; !ok && name != alloc.ourName {
|
if _, ok := ringPeers[name]; !ok && !alloc.isKnownPeer(name) {
|
||||||
delete(alloc.nicknames, name)
|
delete(alloc.nicknames, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -470,9 +470,9 @@ func (r *Ring) ChoosePeersToAskForSpace(start, end address.Address) []router.Pee
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Ring) PickPeerForTransfer() router.PeerName {
|
func (r *Ring) PickPeerForTransfer(isValid func(router.PeerName) bool) router.PeerName {
|
||||||
for _, entry := range r.Entries {
|
for _, entry := range r.Entries {
|
||||||
if entry.Peer != r.Peer {
|
if entry.Peer != r.Peer && isValid(entry.Peer) {
|
||||||
return entry.Peer
|
return entry.Peer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ func makeAllocator(name string, cidrStr string, quorum uint) (*Allocator, addres
|
|||||||
}
|
}
|
||||||
|
|
||||||
alloc := NewAllocator(peername, router.PeerUID(rand.Int63()),
|
alloc := NewAllocator(peername, router.PeerUID(rand.Int63()),
|
||||||
"nick-"+name, cidr.Range(), quorum)
|
"nick-"+name, cidr.Range(), quorum, func(router.PeerName) bool { return true })
|
||||||
|
|
||||||
return alloc, cidr.HostRange()
|
return alloc, cidr.HostRange()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -216,7 +216,7 @@ func (h *handler) handleRecursive(w dns.ResponseWriter, req *dns.Msg) {
|
|||||||
reqCopy := req.Copy()
|
reqCopy := req.Copy()
|
||||||
reqCopy.Id = dns.Id()
|
reqCopy.Id = dns.Id()
|
||||||
response, _, err := h.client.Exchange(reqCopy, fmt.Sprintf("%s:%s", server, h.upstream.Port))
|
response, _, err := h.client.Exchange(reqCopy, fmt.Sprintf("%s:%s", server, h.upstream.Port))
|
||||||
if err != nil || response == nil {
|
if (err != nil && err != dns.ErrTruncated) || response == nil {
|
||||||
h.ns.debugf("error trying %s: %v", server, err)
|
h.ns.debugf("error trying %s: %v", server, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,17 +42,17 @@ func TestTruncation(t *testing.T) {
|
|||||||
nameserver.AddEntry("foo.weave.local.", "", router.UnknownPeerName, i)
|
nameserver.AddEntry("foo.weave.local.", "", router.UnknownPeerName, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
doRequest := func(client *dns.Client, request *dns.Msg, port int) *dns.Msg {
|
doRequest := func(client *dns.Client, request *dns.Msg, port int, expectedErr error) *dns.Msg {
|
||||||
request.SetQuestion("foo.weave.local.", dns.TypeA)
|
request.SetQuestion("foo.weave.local.", dns.TypeA)
|
||||||
response, _, err := client.Exchange(request, fmt.Sprintf("127.0.0.1:%d", port))
|
response, _, err := client.Exchange(request, fmt.Sprintf("127.0.0.1:%d", port))
|
||||||
require.Nil(t, err)
|
require.Equal(t, expectedErr, err)
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
// do a udp query, ensure we get a truncated response
|
// do a udp query, ensure we get a truncated response
|
||||||
{
|
{
|
||||||
udpClient := dns.Client{Net: "udp", UDPSize: minUDPSize}
|
udpClient := dns.Client{Net: "udp", UDPSize: minUDPSize}
|
||||||
response := doRequest(&udpClient, &dns.Msg{}, udpPort)
|
response := doRequest(&udpClient, &dns.Msg{}, udpPort, dns.ErrTruncated)
|
||||||
require.True(t, response.MsgHdr.Truncated)
|
require.True(t, response.MsgHdr.Truncated)
|
||||||
require.True(t, len(response.Answer) < 100)
|
require.True(t, len(response.Answer) < 100)
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ func TestTruncation(t *testing.T) {
|
|||||||
udpClient := dns.Client{Net: "udp", UDPSize: 65535}
|
udpClient := dns.Client{Net: "udp", UDPSize: 65535}
|
||||||
request := &dns.Msg{}
|
request := &dns.Msg{}
|
||||||
request.SetEdns0(65535, false)
|
request.SetEdns0(65535, false)
|
||||||
response := doRequest(&udpClient, request, udpPort)
|
response := doRequest(&udpClient, request, udpPort, nil)
|
||||||
require.False(t, response.MsgHdr.Truncated)
|
require.False(t, response.MsgHdr.Truncated)
|
||||||
require.Equal(t, len(response.Answer), 100)
|
require.Equal(t, len(response.Answer), 100)
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ func TestTruncation(t *testing.T) {
|
|||||||
// do a tcp query, ensure we don't get a truncated response
|
// do a tcp query, ensure we don't get a truncated response
|
||||||
{
|
{
|
||||||
tcpClient := dns.Client{Net: "tcp"}
|
tcpClient := dns.Client{Net: "tcp"}
|
||||||
response := doRequest(&tcpClient, &dns.Msg{}, tcpPort)
|
response := doRequest(&tcpClient, &dns.Msg{}, tcpPort, nil)
|
||||||
require.False(t, response.MsgHdr.Truncated)
|
require.False(t, response.MsgHdr.Truncated)
|
||||||
require.Equal(t, len(response.Answer), 100)
|
require.Equal(t, len(response.Answer), 100)
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-12
@@ -18,7 +18,8 @@ type Entry struct {
|
|||||||
ContainerID string
|
ContainerID string
|
||||||
Origin router.PeerName
|
Origin router.PeerName
|
||||||
Addr address.Address
|
Addr address.Address
|
||||||
Hostname string
|
Hostname string // as supplied
|
||||||
|
lHostname string // lowercased (not exported, so not encoded by gob)
|
||||||
Version int
|
Version int
|
||||||
Tombstone int64 // timestamp of when it was deleted
|
Tombstone int64 // timestamp of when it was deleted
|
||||||
}
|
}
|
||||||
@@ -69,7 +70,7 @@ func (e1 *Entry) less(e2 *Entry) bool {
|
|||||||
|
|
||||||
func (e1 *Entry) insensitiveLess(e2 *Entry) bool {
|
func (e1 *Entry) insensitiveLess(e2 *Entry) bool {
|
||||||
// Entries are kept sorted by Hostname, Origin, ContainerID then address
|
// Entries are kept sorted by Hostname, Origin, ContainerID then address
|
||||||
e1Hostname, e2Hostname := strings.ToLower(e1.Hostname), strings.ToLower(e2.Hostname)
|
e1Hostname, e2Hostname := e1.lHostname, e2.lHostname
|
||||||
switch {
|
switch {
|
||||||
case e1Hostname != e2Hostname:
|
case e1Hostname != e2Hostname:
|
||||||
return e1Hostname < e2Hostname
|
return e1Hostname < e2Hostname
|
||||||
@@ -100,6 +101,10 @@ func (e1 *Entry) String() string {
|
|||||||
return fmt.Sprintf("%s -> %s", e1.Hostname, e1.Addr.String())
|
return fmt.Sprintf("%s -> %s", e1.Hostname, e1.Addr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e1 *Entry) addLowercase() {
|
||||||
|
e1.lHostname = strings.ToLower(e1.Hostname)
|
||||||
|
}
|
||||||
|
|
||||||
func check(es SortableEntries) error {
|
func check(es SortableEntries) error {
|
||||||
if !sort.IsSorted(es) {
|
if !sort.IsSorted(es) {
|
||||||
return fmt.Errorf("Not sorted!")
|
return fmt.Errorf("Not sorted!")
|
||||||
@@ -126,7 +131,8 @@ func (es *Entries) checkAndPanic() *Entries {
|
|||||||
func (es *Entries) add(hostname, containerid string, origin router.PeerName, addr address.Address) Entry {
|
func (es *Entries) add(hostname, containerid string, origin router.PeerName, addr address.Address) Entry {
|
||||||
defer es.checkAndPanic().checkAndPanic()
|
defer es.checkAndPanic().checkAndPanic()
|
||||||
|
|
||||||
entry := Entry{Hostname: hostname, Origin: origin, ContainerID: containerid, Addr: addr}
|
entry := Entry{Hostname: hostname, lHostname: strings.ToLower(hostname),
|
||||||
|
Origin: origin, ContainerID: containerid, Addr: addr}
|
||||||
i := sort.Search(len(*es), func(i int) bool {
|
i := sort.Search(len(*es), func(i int) bool {
|
||||||
return !(*es)[i].insensitiveLess(&entry)
|
return !(*es)[i].insensitiveLess(&entry)
|
||||||
})
|
})
|
||||||
@@ -145,6 +151,7 @@ func (es *Entries) add(hostname, containerid string, origin router.PeerName, add
|
|||||||
|
|
||||||
func (es *Entries) merge(incoming Entries) Entries {
|
func (es *Entries) merge(incoming Entries) Entries {
|
||||||
defer es.checkAndPanic().checkAndPanic()
|
defer es.checkAndPanic().checkAndPanic()
|
||||||
|
incoming.checkAndPanic()
|
||||||
|
|
||||||
newEntries := Entries{}
|
newEntries := Entries{}
|
||||||
i := 0
|
i := 0
|
||||||
@@ -203,23 +210,23 @@ func (es Entries) lookup(hostname string) Entries {
|
|||||||
|
|
||||||
lowerHostname := strings.ToLower(hostname)
|
lowerHostname := strings.ToLower(hostname)
|
||||||
i := sort.Search(len(es), func(i int) bool {
|
i := sort.Search(len(es), func(i int) bool {
|
||||||
return strings.ToLower(es[i].Hostname) >= lowerHostname
|
return es[i].lHostname >= lowerHostname
|
||||||
})
|
})
|
||||||
if i >= len(es) || strings.ToLower(es[i].Hostname) != lowerHostname {
|
if i >= len(es) || es[i].lHostname != lowerHostname {
|
||||||
return Entries{}
|
return Entries{}
|
||||||
}
|
}
|
||||||
|
|
||||||
j := sort.Search(len(es)-i, func(j int) bool {
|
j := sort.Search(len(es)-i, func(j int) bool {
|
||||||
return strings.ToLower(es[i+j].Hostname) > lowerHostname
|
return es[i+j].lHostname > lowerHostname
|
||||||
})
|
})
|
||||||
|
|
||||||
return es[i : i+j]
|
return es[i : i+j]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *Entries) first(f func(*Entry) bool) (*Entry, error) {
|
func (es Entries) first(f func(*Entry) bool) (*Entry, error) {
|
||||||
es.checkAndPanic()
|
es.checkAndPanic()
|
||||||
|
|
||||||
for _, e := range *es {
|
for _, e := range es {
|
||||||
if f(&e) {
|
if f(&e) {
|
||||||
return &e, nil
|
return &e, nil
|
||||||
}
|
}
|
||||||
@@ -227,14 +234,18 @@ func (es *Entries) first(f func(*Entry) bool) (*Entry, error) {
|
|||||||
return nil, fmt.Errorf("Not found")
|
return nil, fmt.Errorf("Not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (es Entries) addLowercase() {
|
||||||
|
for i := range es {
|
||||||
|
es[i].addLowercase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type GossipData struct {
|
type GossipData struct {
|
||||||
Timestamp int64
|
Timestamp int64
|
||||||
Entries
|
Entries
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GossipData) Merge(o router.GossipData) {
|
func (g *GossipData) Merge(o router.GossipData) {
|
||||||
checkAndPanic(CaseSensitive(g.Entries))
|
|
||||||
defer func() { checkAndPanic(CaseSensitive(g.Entries)) }()
|
|
||||||
other := o.(*GossipData)
|
other := o.(*GossipData)
|
||||||
g.Entries.merge(other.Entries)
|
g.Entries.merge(other.Entries)
|
||||||
if g.Timestamp < other.Timestamp {
|
if g.Timestamp < other.Timestamp {
|
||||||
@@ -242,10 +253,23 @@ func (g *GossipData) Merge(o router.GossipData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *GossipData) Decode(msg []byte) error {
|
||||||
|
if err := gob.NewDecoder(bytes.NewReader(msg)).Decode(g); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
g.Entries.addLowercase() // lowercase strings not sent on the wire
|
||||||
|
sort.Sort(CaseInsensitive(g.Entries))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (g *GossipData) Encode() [][]byte {
|
func (g *GossipData) Encode() [][]byte {
|
||||||
checkAndPanic(CaseSensitive(g.Entries))
|
// Make a copy so we can sort: all outgoing data is sent in case-sensitive order
|
||||||
|
g2 := GossipData{Timestamp: g.Timestamp, Entries: make(Entries, len(g.Entries))}
|
||||||
|
copy(g2.Entries, g.Entries)
|
||||||
|
sort.Sort(CaseSensitive(g2.Entries))
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
if err := gob.NewEncoder(buf).Encode(g); err != nil {
|
if err := gob.NewEncoder(buf).Encode(g2); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return [][]byte{buf.Bytes()}
|
return [][]byte{buf.Bytes()}
|
||||||
|
|||||||
+47
-56
@@ -9,6 +9,19 @@ import (
|
|||||||
"github.com/weaveworks/weave/router"
|
"github.com/weaveworks/weave/router"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func l(es Entries) Entries {
|
||||||
|
es.addLowercase()
|
||||||
|
return es
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeEntries(values string) Entries {
|
||||||
|
entries := make(Entries, len(values))
|
||||||
|
for i, c := range values {
|
||||||
|
entries[i] = Entry{Hostname: string(c)}
|
||||||
|
}
|
||||||
|
return l(entries)
|
||||||
|
}
|
||||||
|
|
||||||
func TestAdd(t *testing.T) {
|
func TestAdd(t *testing.T) {
|
||||||
oldNow := now
|
oldNow := now
|
||||||
defer func() { now = oldNow }()
|
defer func() { now = oldNow }()
|
||||||
@@ -16,68 +29,46 @@ func TestAdd(t *testing.T) {
|
|||||||
|
|
||||||
entries := Entries{}
|
entries := Entries{}
|
||||||
entries.add("A", "", router.UnknownPeerName, address.Address(0))
|
entries.add("A", "", router.UnknownPeerName, address.Address(0))
|
||||||
expected := Entries{
|
expected := l(Entries{
|
||||||
Entry{Hostname: "A", Origin: router.UnknownPeerName, Addr: address.Address(0)},
|
Entry{Hostname: "A", Origin: router.UnknownPeerName, Addr: address.Address(0)},
|
||||||
}
|
})
|
||||||
require.Equal(t, entries, expected)
|
require.Equal(t, entries, expected)
|
||||||
|
|
||||||
entries.tombstone(router.UnknownPeerName, func(e *Entry) bool { return e.Hostname == "A" })
|
entries.tombstone(router.UnknownPeerName, func(e *Entry) bool { return e.Hostname == "A" })
|
||||||
expected = Entries{
|
expected = l(Entries{
|
||||||
Entry{Hostname: "A", Origin: router.UnknownPeerName, Addr: address.Address(0), Version: 1, Tombstone: 1234},
|
Entry{Hostname: "A", Origin: router.UnknownPeerName, Addr: address.Address(0), Version: 1, Tombstone: 1234},
|
||||||
}
|
})
|
||||||
require.Equal(t, entries, expected)
|
require.Equal(t, entries, expected)
|
||||||
|
|
||||||
entries.add("A", "", router.UnknownPeerName, address.Address(0))
|
entries.add("A", "", router.UnknownPeerName, address.Address(0))
|
||||||
expected = Entries{
|
expected = l(Entries{
|
||||||
Entry{Hostname: "A", Origin: router.UnknownPeerName, Addr: address.Address(0), Version: 2},
|
Entry{Hostname: "A", Origin: router.UnknownPeerName, Addr: address.Address(0), Version: 2},
|
||||||
}
|
})
|
||||||
require.Equal(t, entries, expected)
|
require.Equal(t, entries, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMerge(t *testing.T) {
|
func TestMerge(t *testing.T) {
|
||||||
e1 := Entries{
|
e1 := makeEntries("ACDF")
|
||||||
Entry{Hostname: "A"},
|
e2 := makeEntries("BEF")
|
||||||
Entry{Hostname: "C"},
|
|
||||||
Entry{Hostname: "D"},
|
|
||||||
Entry{Hostname: "F"},
|
|
||||||
}
|
|
||||||
|
|
||||||
e2 := Entries{
|
|
||||||
Entry{Hostname: "B"},
|
|
||||||
Entry{Hostname: "E"},
|
|
||||||
Entry{Hostname: "F"},
|
|
||||||
}
|
|
||||||
|
|
||||||
diff := e1.merge(e2)
|
diff := e1.merge(e2)
|
||||||
expectedDiff := Entries{
|
|
||||||
Entry{Hostname: "B"},
|
|
||||||
Entry{Hostname: "E"},
|
|
||||||
}
|
|
||||||
require.Equal(t, expectedDiff, diff)
|
|
||||||
|
|
||||||
expected := Entries{
|
require.Equal(t, makeEntries("BE"), diff)
|
||||||
Entry{Hostname: "A"},
|
require.Equal(t, makeEntries("ABCDEF"), e1)
|
||||||
Entry{Hostname: "B"},
|
|
||||||
Entry{Hostname: "C"},
|
|
||||||
Entry{Hostname: "D"},
|
|
||||||
Entry{Hostname: "E"},
|
|
||||||
Entry{Hostname: "F"},
|
|
||||||
}
|
|
||||||
require.Equal(t, expected, e1)
|
|
||||||
|
|
||||||
diff = e1.merge(e1)
|
diff = e1.merge(e1)
|
||||||
require.Equal(t, Entries{}, diff)
|
require.Equal(t, Entries{}, diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOldMerge(t *testing.T) {
|
func TestOldMerge(t *testing.T) {
|
||||||
e1 := Entries{Entry{Hostname: "A", Version: 0}}
|
e1 := l(Entries{Entry{Hostname: "A", Version: 0}})
|
||||||
diff := e1.merge(Entries{Entry{Hostname: "A", Version: 1}})
|
diff := e1.merge(l(Entries{Entry{Hostname: "A", Version: 1}}))
|
||||||
require.Equal(t, Entries{Entry{Hostname: "A", Version: 1}}, diff)
|
require.Equal(t, l(Entries{Entry{Hostname: "A", Version: 1}}), diff)
|
||||||
require.Equal(t, Entries{Entry{Hostname: "A", Version: 1}}, e1)
|
require.Equal(t, l(Entries{Entry{Hostname: "A", Version: 1}}), e1)
|
||||||
|
|
||||||
diff = e1.merge(Entries{Entry{Hostname: "A", Version: 0}})
|
diff = e1.merge(l(Entries{Entry{Hostname: "A", Version: 0}}))
|
||||||
require.Equal(t, Entries{}, diff)
|
require.Equal(t, Entries{}, diff)
|
||||||
require.Equal(t, Entries{Entry{Hostname: "A", Version: 1}}, e1)
|
require.Equal(t, l(Entries{Entry{Hostname: "A", Version: 1}}), e1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTombstone(t *testing.T) {
|
func TestTombstone(t *testing.T) {
|
||||||
@@ -85,48 +76,48 @@ func TestTombstone(t *testing.T) {
|
|||||||
defer func() { now = oldNow }()
|
defer func() { now = oldNow }()
|
||||||
now = func() int64 { return 1234 }
|
now = func() int64 { return 1234 }
|
||||||
|
|
||||||
es := Entries{
|
es := makeEntries("AB")
|
||||||
Entry{Hostname: "A"},
|
|
||||||
Entry{Hostname: "B"},
|
|
||||||
}
|
|
||||||
|
|
||||||
es.tombstone(router.UnknownPeerName, func(e *Entry) bool {
|
es.tombstone(router.UnknownPeerName, func(e *Entry) bool {
|
||||||
return e.Hostname == "B"
|
return e.Hostname == "B"
|
||||||
})
|
})
|
||||||
expected := Entries{
|
expected := l(Entries{
|
||||||
Entry{Hostname: "A"},
|
Entry{Hostname: "A"},
|
||||||
Entry{Hostname: "B", Version: 1, Tombstone: 1234},
|
Entry{Hostname: "B", Version: 1, Tombstone: 1234},
|
||||||
}
|
})
|
||||||
require.Equal(t, expected, es)
|
require.Equal(t, expected, es)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDelete(t *testing.T) {
|
func TestDelete(t *testing.T) {
|
||||||
es := Entries{
|
es := makeEntries("AB")
|
||||||
Entry{Hostname: "A"},
|
|
||||||
Entry{Hostname: "B"},
|
|
||||||
}
|
|
||||||
|
|
||||||
es.filter(func(e *Entry) bool {
|
es.filter(func(e *Entry) bool {
|
||||||
return e.Hostname != "A"
|
return e.Hostname != "A"
|
||||||
})
|
})
|
||||||
expected := Entries{
|
require.Equal(t, makeEntries("B"), es)
|
||||||
Entry{Hostname: "B"},
|
|
||||||
}
|
|
||||||
require.Equal(t, expected, es)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLookup(t *testing.T) {
|
func TestLookup(t *testing.T) {
|
||||||
es := Entries{
|
es := l(Entries{
|
||||||
Entry{Hostname: "A"},
|
Entry{Hostname: "A"},
|
||||||
Entry{Hostname: "B", ContainerID: "bar"},
|
Entry{Hostname: "B", ContainerID: "bar"},
|
||||||
Entry{Hostname: "B", ContainerID: "foo"},
|
Entry{Hostname: "B", ContainerID: "foo"},
|
||||||
Entry{Hostname: "C"},
|
Entry{Hostname: "C"},
|
||||||
}
|
})
|
||||||
|
|
||||||
have := es.lookup("B")
|
have := es.lookup("B")
|
||||||
want := Entries{
|
want := l(Entries{
|
||||||
Entry{Hostname: "B", ContainerID: "bar"},
|
Entry{Hostname: "B", ContainerID: "bar"},
|
||||||
Entry{Hostname: "B", ContainerID: "foo"},
|
Entry{Hostname: "B", ContainerID: "foo"},
|
||||||
}
|
})
|
||||||
require.Equal(t, have, want)
|
require.Equal(t, have, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGossipDataMerge(t *testing.T) {
|
||||||
|
g1 := GossipData{Entries: makeEntries("AcDf")}
|
||||||
|
g2 := GossipData{Entries: makeEntries("BEf")}
|
||||||
|
|
||||||
|
g1.Merge(&g2)
|
||||||
|
|
||||||
|
require.Equal(t, GossipData{Entries: makeEntries("ABcDEf")}, g1)
|
||||||
|
}
|
||||||
@@ -35,6 +35,11 @@ func (n *Nameserver) HandleHTTP(router *mux.Router, dockerCli *docker.Client) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !dns.IsSubDomain(n.domain, hostname) {
|
||||||
|
n.infof("Ignoring registration %s %s %s (not a subdomain of %s)", hostname, ipStr, container, n.domain)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if err := n.AddEntry(hostname, container, n.ourName, ip); err != nil {
|
if err := n.AddEntry(hostname, container, n.ourName, ip); err != nil {
|
||||||
n.badRequest(w, fmt.Errorf("Unable to add entry: %v", err))
|
n.badRequest(w, fmt.Errorf("Unable to add entry: %v", err))
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
package nameserver
|
package nameserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/gob"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -196,7 +193,6 @@ func (n *Nameserver) Gossip() router.GossipData {
|
|||||||
Timestamp: now(),
|
Timestamp: now(),
|
||||||
}
|
}
|
||||||
copy(gossip.Entries, n.entries)
|
copy(gossip.Entries, n.entries)
|
||||||
sort.Sort(CaseSensitive(gossip.Entries))
|
|
||||||
return gossip
|
return gossip
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,16 +202,13 @@ func (n *Nameserver) OnGossipUnicast(sender router.PeerName, msg []byte) error {
|
|||||||
|
|
||||||
func (n *Nameserver) receiveGossip(msg []byte) (router.GossipData, router.GossipData, error) {
|
func (n *Nameserver) receiveGossip(msg []byte) (router.GossipData, router.GossipData, error) {
|
||||||
var gossip GossipData
|
var gossip GossipData
|
||||||
if err := gob.NewDecoder(bytes.NewReader(msg)).Decode(&gossip); err != nil {
|
if err := gossip.Decode(msg); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if delta := gossip.Timestamp - now(); delta > gossipWindow || delta < -gossipWindow {
|
if delta := gossip.Timestamp - now(); delta > gossipWindow || delta < -gossipWindow {
|
||||||
return nil, nil, fmt.Errorf("clock skew of %d detected", delta)
|
return nil, nil, fmt.Errorf("clock skew of %d detected", delta)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(CaseInsensitive(gossip.Entries))
|
|
||||||
|
|
||||||
n.Lock()
|
n.Lock()
|
||||||
defer n.Unlock()
|
defer n.Unlock()
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ func (m mapping) Addrs() []address.Address {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNameservers(t *testing.T) {
|
func TestNameservers(t *testing.T) {
|
||||||
wt.RunWithTimeout(t, time.Minute, func() {
|
wt.RunWithTimeout(t, 2*time.Minute, func() {
|
||||||
testNameservers(t)
|
testNameservers(t)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -81,8 +81,12 @@ func testNameservers(t *testing.T) {
|
|||||||
//common.SetLogLevel("debug")
|
//common.SetLogLevel("debug")
|
||||||
|
|
||||||
lookupTimeout := 10 // ms
|
lookupTimeout := 10 // ms
|
||||||
nameservers, grouter := makeNetwork(50)
|
nameservers, grouter := makeNetwork(30)
|
||||||
defer stopNetwork(nameservers, grouter)
|
defer stopNetwork(nameservers, grouter)
|
||||||
|
// This subset will sometimes lose touch with some of the others
|
||||||
|
badNameservers := nameservers[25:]
|
||||||
|
// This subset will remain well-connected, and we will deal mainly with them
|
||||||
|
nameservers = nameservers[:25]
|
||||||
nameserversByName := map[router.PeerName]*Nameserver{}
|
nameserversByName := map[router.PeerName]*Nameserver{}
|
||||||
for _, n := range nameservers {
|
for _, n := range nameservers {
|
||||||
nameserversByName[n.ourName] = n
|
nameserversByName[n.ourName] = n
|
||||||
@@ -106,7 +110,13 @@ func testNameservers(t *testing.T) {
|
|||||||
addMapping := func() {
|
addMapping := func() {
|
||||||
nameserver := nameservers[rand.Intn(len(nameservers))]
|
nameserver := nameservers[rand.Intn(len(nameservers))]
|
||||||
addr := address.Address(rand.Int31())
|
addr := address.Address(rand.Int31())
|
||||||
hostname := fmt.Sprintf("hostname%d", rand.Int63())
|
// Create a hostname which has some upper and lowercase letters,
|
||||||
|
// and a unique number so we don't have to check if we allocated it already
|
||||||
|
randomBits := rand.Int63()
|
||||||
|
firstLetter := 'H' + (randomBits&1)*32
|
||||||
|
secondLetter := 'O' + (randomBits&2)*16
|
||||||
|
randomBits = randomBits >> 2
|
||||||
|
hostname := fmt.Sprintf("%c%cstname%d", firstLetter, secondLetter, randomBits)
|
||||||
mapping := mapping{hostname, []pair{{nameserver.ourName, addr}}}
|
mapping := mapping{hostname, []pair{{nameserver.ourName, addr}}}
|
||||||
mappings = append(mappings, mapping)
|
mappings = append(mappings, mapping)
|
||||||
|
|
||||||
@@ -129,6 +139,12 @@ func testNameservers(t *testing.T) {
|
|||||||
check(nameserver, mapping)
|
check(nameserver, mapping)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loseConnection := func() {
|
||||||
|
nameserver1 := badNameservers[rand.Intn(len(badNameservers))]
|
||||||
|
nameserver2 := nameservers[rand.Intn(len(nameservers))]
|
||||||
|
nameserver1.PeerGone(&router.Peer{Name: nameserver2.ourName})
|
||||||
|
}
|
||||||
|
|
||||||
deleteMapping := func() {
|
deleteMapping := func() {
|
||||||
if len(mappings) <= 0 {
|
if len(mappings) <= 0 {
|
||||||
return
|
return
|
||||||
@@ -179,7 +195,7 @@ func testNameservers(t *testing.T) {
|
|||||||
require.Equal(t, mapping.hostname, hostname)
|
require.Equal(t, mapping.hostname, hostname)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 800; i++ {
|
||||||
r := rand.Float32()
|
r := rand.Float32()
|
||||||
switch {
|
switch {
|
||||||
case r < 0.1:
|
case r < 0.1:
|
||||||
@@ -191,7 +207,10 @@ func testNameservers(t *testing.T) {
|
|||||||
case 0.2 <= r && r < 0.3:
|
case 0.2 <= r && r < 0.3:
|
||||||
deleteMapping()
|
deleteMapping()
|
||||||
|
|
||||||
case 0.3 <= r && r < 0.9:
|
case 0.3 <= r && r < 0.35:
|
||||||
|
loseConnection()
|
||||||
|
|
||||||
|
case 0.35 <= r && r < 0.9:
|
||||||
doLookup()
|
doLookup()
|
||||||
|
|
||||||
case 0.9 <= r:
|
case 0.9 <= r:
|
||||||
@@ -241,14 +260,14 @@ func TestTombstoneDeletion(t *testing.T) {
|
|||||||
err = nameserver.Delete("hostname", "containerid", "", address.Address(0))
|
err = nameserver.Delete("hostname", "containerid", "", address.Address(0))
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Equal(t, []address.Address{}, nameserver.Lookup("hostname"))
|
require.Equal(t, []address.Address{}, nameserver.Lookup("hostname"))
|
||||||
require.Equal(t, Entries{{
|
require.Equal(t, l(Entries{Entry{
|
||||||
ContainerID: "containerid",
|
ContainerID: "containerid",
|
||||||
Origin: peername,
|
Origin: peername,
|
||||||
Addr: address.Address(0),
|
Addr: address.Address(0),
|
||||||
Hostname: "hostname",
|
Hostname: "hostname",
|
||||||
Version: 1,
|
Version: 1,
|
||||||
Tombstone: 1234,
|
Tombstone: 1234,
|
||||||
}}, nameserver.entries)
|
}}), nameserver.entries)
|
||||||
|
|
||||||
now = func() int64 { return 1234 + int64(tombstoneTimeout/time.Second) + 1 }
|
now = func() int64 { return 1234 + int64(tombstoneTimeout/time.Second) + 1 }
|
||||||
nameserver.deleteTombstones()
|
nameserver.deleteTombstones()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ LABEL works.weave.role=system
|
|||||||
|
|
||||||
WORKDIR /home/weave
|
WORKDIR /home/weave
|
||||||
VOLUME /w
|
VOLUME /w
|
||||||
|
VOLUME /w-noop
|
||||||
ENTRYPOINT ["/home/weave/sigproxy", "/home/weave/weave"]
|
ENTRYPOINT ["/home/weave/sigproxy", "/home/weave/weave"]
|
||||||
|
|
||||||
RUN apk add --update \
|
RUN apk add --update \
|
||||||
@@ -20,4 +21,5 @@ RUN apk add --update \
|
|||||||
ADD ./weave ./sigproxy ./weaveproxy /home/weave/
|
ADD ./weave ./sigproxy ./weaveproxy /home/weave/
|
||||||
ADD ./netcheck ./docker_tls_args /usr/bin/
|
ADD ./netcheck ./docker_tls_args /usr/bin/
|
||||||
ADD ./weavewait /w/w
|
ADD ./weavewait /w/w
|
||||||
|
ADD ./weavewait_noop /w-noop/w
|
||||||
ADD ./docker.tgz /
|
ADD ./docker.tgz /
|
||||||
+8
-4
@@ -13,7 +13,6 @@ import (
|
|||||||
"github.com/davecheney/profile"
|
"github.com/davecheney/profile"
|
||||||
"github.com/docker/docker/pkg/mflag"
|
"github.com/docker/docker/pkg/mflag"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/weaveworks/go-odp/odp"
|
|
||||||
|
|
||||||
. "github.com/weaveworks/weave/common"
|
. "github.com/weaveworks/weave/common"
|
||||||
"github.com/weaveworks/weave/common/docker"
|
"github.com/weaveworks/weave/common/docker"
|
||||||
@@ -119,8 +118,12 @@ func main() {
|
|||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
|
|
||||||
case createDatapath:
|
case createDatapath:
|
||||||
err := weave.CreateDatapath(datapathName)
|
err, odp_supported := weave.CreateDatapath(datapathName)
|
||||||
if odp.IsKernelLacksODPError(err) {
|
if !odp_supported {
|
||||||
|
if err != nil {
|
||||||
|
Log.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
// When the kernel lacks ODP support, exit
|
// When the kernel lacks ODP support, exit
|
||||||
// with a special status to distinguish it for
|
// with a special status to distinguish it for
|
||||||
// the weave script.
|
// the weave script.
|
||||||
@@ -368,7 +371,8 @@ func createAllocator(router *weave.Router, ipRangeStr string, defaultSubnetStr s
|
|||||||
Log.Fatalf("IP address allocation default subnet %s does not overlap with allocation range %s", defaultSubnet, ipRange)
|
Log.Fatalf("IP address allocation default subnet %s does not overlap with allocation range %s", defaultSubnet, ipRange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
allocator := ipam.NewAllocator(router.Ourself.Peer.Name, router.Ourself.Peer.UID, router.Ourself.Peer.NickName, ipRange.Range(), quorum)
|
isKnownPeer := func(name weave.PeerName) bool { return router.Peers.Fetch(name) != nil }
|
||||||
|
allocator := ipam.NewAllocator(router.Ourself.Peer.Name, router.Ourself.Peer.UID, router.Ourself.Peer.NickName, ipRange.Range(), quorum, isKnownPeer)
|
||||||
|
|
||||||
allocator.SetInterfaces(router.NewGossip("IPallocation", allocator))
|
allocator.SetInterfaces(router.NewGossip("IPallocation", allocator))
|
||||||
allocator.Start()
|
allocator.Start()
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// +build !noop
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
weavenet "github.com/weaveworks/weave/net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func checkNetwork() error {
|
||||||
|
_, err := weavenet.EnsureInterfaceAndMcastRoute("ethwe")
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -6,8 +6,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
weavenet "github.com/weaveworks/weave/net"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -19,8 +17,7 @@ func main() {
|
|||||||
args = os.Args[1:]
|
args = os.Args[1:]
|
||||||
)
|
)
|
||||||
|
|
||||||
_, err := weavenet.EnsureInterfaceAndMcastRoute("ethwe")
|
checkErr(checkNetwork())
|
||||||
checkErr(err)
|
|
||||||
|
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
checkErr(ErrNoCommandSpecified)
|
checkErr(ErrNoCommandSpecified)
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// +build noop
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
func checkNetwork() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ var (
|
|||||||
containerIDRegexp = regexp.MustCompile("^(/v[0-9\\.]*)?/containers/([^/]*)/.*")
|
containerIDRegexp = regexp.MustCompile("^(/v[0-9\\.]*)?/containers/([^/]*)/.*")
|
||||||
weaveWaitEntrypoint = []string{"/w/w"}
|
weaveWaitEntrypoint = []string{"/w/w"}
|
||||||
weaveEntrypoint = "/home/weave/weaver"
|
weaveEntrypoint = "/home/weave/weaver"
|
||||||
|
weaveContainerName = "/weave"
|
||||||
)
|
)
|
||||||
|
|
||||||
func callWeave(args ...string) ([]byte, []byte, error) {
|
func callWeave(args ...string) ([]byte, []byte, error) {
|
||||||
@@ -154,3 +155,25 @@ func weaveContainerIPs(containerID string) (mac string, ips []net.IP, nets []*ne
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addVolume(hostConfig jsonObject, source, target, mode string) error {
|
||||||
|
configBinds, err := hostConfig.StringArray("Binds")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var binds []string
|
||||||
|
for _, bind := range configBinds {
|
||||||
|
s := strings.Split(bind, ":")
|
||||||
|
if len(s) >= 2 && s[1] == target {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
binds = append(binds, bind)
|
||||||
|
}
|
||||||
|
bind := source + ":" + target
|
||||||
|
if mode != "" {
|
||||||
|
bind += ":" + mode
|
||||||
|
}
|
||||||
|
hostConfig["Binds"] = append(binds, bind)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -53,7 +53,7 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error {
|
|||||||
Log.Infof("Leaving container alone because %s", err)
|
Log.Infof("Leaving container alone because %s", err)
|
||||||
} else {
|
} else {
|
||||||
Log.Infof("Creating container with WEAVE_CIDR \"%s\"", strings.Join(cidrs, " "))
|
Log.Infof("Creating container with WEAVE_CIDR \"%s\"", strings.Join(cidrs, " "))
|
||||||
if err := i.proxy.addWeaveWaitVolume(hostConfig); err != nil {
|
if err := addVolume(hostConfig, i.proxy.weaveWaitVolume, "/w", "ro"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := i.setWeaveWaitEntrypoint(container); err != nil {
|
if err := i.setWeaveWaitEntrypoint(container); err != nil {
|
||||||
|
|||||||
@@ -22,30 +22,9 @@ func (i *inspectContainerInterceptor) InterceptResponse(r *http.Response) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := updateContainerNetworkSettings(container); err != nil {
|
if err := i.proxy.updateContainerNetworkSettings(container); err != nil {
|
||||||
Log.Warningf("Inspecting container %s failed: %s", container["Id"], err)
|
Log.Warningf("Inspecting container %s failed: %s", container["Id"], err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return marshalResponseBody(r, container)
|
return marshalResponseBody(r, container)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateContainerNetworkSettings(container jsonObject) error {
|
|
||||||
containerID, err := container.String("Id")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
mac, ips, nets, err := weaveContainerIPs(containerID)
|
|
||||||
if err != nil || len(ips) == 0 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
networkSettings, err := container.Object("NetworkSettings")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
networkSettings["MacAddress"] = mac
|
|
||||||
networkSettings["IPAddress"] = ips[0].String()
|
|
||||||
networkSettings["IPPrefixLen"], _ = nets[0].Mask.Size()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -27,7 +27,7 @@ func (i *inspectExecInterceptor) InterceptResponse(r *http.Response) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := updateContainerNetworkSettings(container); err != nil {
|
if err := i.proxy.updateContainerNetworkSettings(container); err != nil {
|
||||||
Log.Warningf("Inspecting exec %s failed: %s", exec["Id"], err)
|
Log.Warningf("Inspecting exec %s failed: %s", exec["Id"], err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+62
-28
@@ -70,6 +70,7 @@ type Proxy struct {
|
|||||||
dockerBridgeIP string
|
dockerBridgeIP string
|
||||||
hostnameMatchRegexp *regexp.Regexp
|
hostnameMatchRegexp *regexp.Regexp
|
||||||
weaveWaitVolume string
|
weaveWaitVolume string
|
||||||
|
weaveWaitNoopVolume string
|
||||||
normalisedAddrs []string
|
normalisedAddrs []string
|
||||||
waiters map[*http.Request]*wait
|
waiters map[*http.Request]*wait
|
||||||
}
|
}
|
||||||
@@ -106,7 +107,7 @@ func NewProxy(c Config) (*Proxy, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = p.findWeaveWaitVolume(); err != nil {
|
if err = p.findWeaveWaitVolumes(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,23 +136,31 @@ func (proxy *Proxy) Dial() (net.Conn, error) {
|
|||||||
return net.Dial("unix", dockerSock)
|
return net.Dial("unix", dockerSock)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (proxy *Proxy) findWeaveWaitVolume() error {
|
func (proxy *Proxy) findWeaveWaitVolumes() error {
|
||||||
|
var err error
|
||||||
|
if proxy.weaveWaitVolume, err = proxy.findVolume("/w"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
proxy.weaveWaitNoopVolume, err = proxy.findVolume("/w-noop")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (proxy *Proxy) findVolume(v string) (string, error) {
|
||||||
container, err := proxy.client.InspectContainer("weaveproxy")
|
container, err := proxy.client.InspectContainer("weaveproxy")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Could not find the weavewait volume: %s", err)
|
return "", fmt.Errorf("Could not find the weavewait volume: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if container.Volumes == nil {
|
if container.Volumes == nil {
|
||||||
return fmt.Errorf("Could not find the weavewait volume")
|
return "", fmt.Errorf("Could not find the weavewait volume")
|
||||||
}
|
}
|
||||||
|
|
||||||
volume, ok := container.Volumes["/w"]
|
volume, ok := container.Volumes[v]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Could not find the weavewait volume")
|
return "", fmt.Errorf("Could not find the weavewait volume")
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy.weaveWaitVolume = volume
|
return volume, nil
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (proxy *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -315,7 +324,8 @@ func containerShouldAttach(container *docker.Container) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func containerIsWeaveRouter(container *docker.Container) bool {
|
func containerIsWeaveRouter(container *docker.Container) bool {
|
||||||
return len(container.Config.Entrypoint) > 0 && container.Config.Entrypoint[0] == weaveEntrypoint
|
return container.Name == weaveContainerName &&
|
||||||
|
len(container.Config.Entrypoint) > 0 && container.Config.Entrypoint[0] == weaveEntrypoint
|
||||||
}
|
}
|
||||||
|
|
||||||
func (proxy *Proxy) createWait(r *http.Request, ident string) {
|
func (proxy *Proxy) createWait(r *http.Request, ident string) {
|
||||||
@@ -357,6 +367,24 @@ func (proxy *Proxy) waitForStart(r *http.Request) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If some other operation is waiting for a container to start, join in the wait
|
||||||
|
func (proxy *Proxy) waitForStartByIdent(ident string) error {
|
||||||
|
var ch chan error
|
||||||
|
proxy.Lock()
|
||||||
|
for _, wait := range proxy.waiters {
|
||||||
|
if ident == wait.ident && !wait.done {
|
||||||
|
ch = wait.ch
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
proxy.Unlock()
|
||||||
|
if ch != nil {
|
||||||
|
Log.Debugf("Wait for start of container %s", ident)
|
||||||
|
return <-ch
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (proxy *Proxy) ContainerDied(ident string) {
|
func (proxy *Proxy) ContainerDied(ident string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,7 +434,7 @@ func (proxy *Proxy) attachRouter(container *docker.Container) error {
|
|||||||
|
|
||||||
func (proxy *Proxy) weaveCIDRs(networkMode string, env []string) ([]string, error) {
|
func (proxy *Proxy) weaveCIDRs(networkMode string, env []string) ([]string, error) {
|
||||||
if networkMode == "host" || strings.HasPrefix(networkMode, "container:") {
|
if networkMode == "host" || strings.HasPrefix(networkMode, "container:") {
|
||||||
return nil, fmt.Errorf("the container was created with the '--net=%s'", networkMode)
|
return nil, fmt.Errorf("the container has '--net=%s'", networkMode)
|
||||||
}
|
}
|
||||||
for _, e := range env {
|
for _, e := range env {
|
||||||
if strings.HasPrefix(e, "WEAVE_CIDR=") {
|
if strings.HasPrefix(e, "WEAVE_CIDR=") {
|
||||||
@@ -422,24 +450,6 @@ func (proxy *Proxy) weaveCIDRs(networkMode string, env []string) ([]string, erro
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (proxy *Proxy) addWeaveWaitVolume(hostConfig jsonObject) error {
|
|
||||||
configBinds, err := hostConfig.StringArray("Binds")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var binds []string
|
|
||||||
for _, bind := range configBinds {
|
|
||||||
s := strings.Split(bind, ":")
|
|
||||||
if len(s) >= 2 && s[1] == "/w" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
binds = append(binds, bind)
|
|
||||||
}
|
|
||||||
hostConfig["Binds"] = append(binds, fmt.Sprintf("%s:/w:ro", proxy.weaveWaitVolume))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (proxy *Proxy) setWeaveDNS(hostConfig jsonObject, hostname, dnsDomain string) error {
|
func (proxy *Proxy) setWeaveDNS(hostConfig jsonObject, hostname, dnsDomain string) error {
|
||||||
dns, err := hostConfig.StringArray("Dns")
|
dns, err := hostConfig.StringArray("Dns")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -494,3 +504,27 @@ func (proxy *Proxy) getDNSDomain() (domain string) {
|
|||||||
|
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (proxy *Proxy) updateContainerNetworkSettings(container jsonObject) error {
|
||||||
|
containerID, err := container.String("Id")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := proxy.waitForStartByIdent(containerID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mac, ips, nets, err := weaveContainerIPs(containerID)
|
||||||
|
if err != nil || len(ips) == 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
networkSettings, err := container.Object("NetworkSettings")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
networkSettings["MacAddress"] = mac
|
||||||
|
networkSettings["IPAddress"] = ips[0].String()
|
||||||
|
networkSettings["IPPrefixLen"], _ = nets[0].Mask.Size()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package proxy
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type startContainerInterceptor struct{ proxy *Proxy }
|
type startContainerInterceptor struct{ proxy *Proxy }
|
||||||
@@ -31,11 +32,23 @@ func (i *startContainerInterceptor) InterceptRequest(r *http.Request) error {
|
|||||||
hostConfig = params
|
hostConfig = params
|
||||||
}
|
}
|
||||||
if hostConfig != nil {
|
if hostConfig != nil {
|
||||||
i.proxy.addWeaveWaitVolume(hostConfig)
|
networkMode, err := jsonObject(hostConfig).String("NetworkMode")
|
||||||
if dnsDomain := i.proxy.getDNSDomain(); dnsDomain != "" {
|
if err != nil {
|
||||||
if err := i.proxy.setWeaveDNS(hostConfig, container.Config.Hostname, dnsDomain); err != nil {
|
return err
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(networkMode, "container:") || networkMode == "host" {
|
||||||
|
if err := addVolume(hostConfig, i.proxy.weaveWaitNoopVolume, "/w", "ro"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if err := addVolume(hostConfig, i.proxy.weaveWaitVolume, "/w", "ro"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if dnsDomain := i.proxy.getDNSDomain(); dnsDomain != "" {
|
||||||
|
if err := i.proxy.setWeaveDNS(hostConfig, container.Config.Hostname, dnsDomain); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note we marshal the original top-level dictionary to avoid disturbing anything else
|
// Note we marshal the original top-level dictionary to avoid disturbing anything else
|
||||||
|
|||||||
+38
-5
@@ -1,25 +1,58 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/weaveworks/go-odp/odp"
|
"github.com/weaveworks/go-odp/odp"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ODP admin functionality
|
// ODP admin functionality
|
||||||
|
|
||||||
func CreateDatapath(dpname string) error {
|
func CreateDatapath(dpname string) (err error, supported bool) {
|
||||||
dpif, err := odp.NewDpif()
|
dpif, err := odp.NewDpif()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
if odp.IsKernelLacksODPError(err) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return err, true
|
||||||
}
|
}
|
||||||
|
|
||||||
defer dpif.Close()
|
defer dpif.Close()
|
||||||
|
|
||||||
_, err = dpif.CreateDatapath(dpname)
|
dp, err := dpif.CreateDatapath(dpname)
|
||||||
if err != nil && !odp.IsDatapathNameAlreadyExistsError(err) {
|
if err != nil && !odp.IsDatapathNameAlreadyExistsError(err) {
|
||||||
return err
|
return err, true
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
// Pick an ephemeral port number to use in probing for vxlan
|
||||||
|
// support.
|
||||||
|
udpconn, err := net.ListenUDP("udp4", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// we leave the UDP socket open, so creating a vxlan vport on
|
||||||
|
// the same port number should fail. But that's fine: It's
|
||||||
|
// still sufficient to probe for support.
|
||||||
|
portno := uint16(udpconn.LocalAddr().(*net.UDPAddr).Port)
|
||||||
|
vpid, err := dp.CreateVport(odp.NewVxlanVportSpec(
|
||||||
|
fmt.Sprintf("vxlan-%d", portno), portno))
|
||||||
|
if nlerr, ok := err.(odp.NetlinkError); ok {
|
||||||
|
if syscall.Errno(nlerr) == syscall.EAFNOSUPPORT {
|
||||||
|
dp.Delete()
|
||||||
|
return fmt.Errorf("kernel does not have Open vSwitch VXLAN support"), false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
dp.DeleteVport(vpid)
|
||||||
|
}
|
||||||
|
|
||||||
|
udpconn.Close()
|
||||||
|
return nil, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteDatapath(dpname string) error {
|
func DeleteDatapath(dpname string) error {
|
||||||
|
|||||||
@@ -327,8 +327,6 @@ func (peers *Peers) ApplyUpdate(update []byte) (PeerNameSet, PeerNameSet, error)
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ourVersion := peers.ourself.Version
|
|
||||||
|
|
||||||
// By this point, we know the update doesn't refer to any peers we
|
// By this point, we know the update doesn't refer to any peers we
|
||||||
// have no knowledge of. We can now apply the update. Start by
|
// have no knowledge of. We can now apply the update. Start by
|
||||||
// adding in any new peers.
|
// adding in any new peers.
|
||||||
@@ -349,13 +347,6 @@ func (peers *Peers) ApplyUpdate(update []byte) (PeerNameSet, PeerNameSet, error)
|
|||||||
updateNames[peer.Name] = void
|
updateNames[peer.Name] = void
|
||||||
}
|
}
|
||||||
|
|
||||||
if peers.ourself.Version != ourVersion {
|
|
||||||
// Our short id changed, i.e. due to a short ID
|
|
||||||
// change. So we need to include ourself in the
|
|
||||||
// update
|
|
||||||
newUpdate[peers.ourself.Name] = void
|
|
||||||
}
|
|
||||||
|
|
||||||
return updateNames, newUpdate, nil
|
return updateNames, newUpdate, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,3 +69,17 @@
|
|||||||
s.parentNode.insertBefore(wf, s);
|
s.parentNode.insertBefore(wf, s);
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
piAId = '124932';
|
||||||
|
piCId = '85570';
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
function async_load(){
|
||||||
|
var s = document.createElement('script'); s.type = 'text/javascript';
|
||||||
|
s.src = ('https:' == document.location.protocol ? 'https://pi' : 'http://cdn') + '.pardot.com/pd.js';
|
||||||
|
var c = document.getElementsByTagName('script')[0]; c.parentNode.insertBefore(s, c);
|
||||||
|
}
|
||||||
|
if(window.attachEvent) { window.attachEvent('onload', async_load); }
|
||||||
|
else { window.addEventListener('load', async_load, false); }
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
+9
-1
@@ -219,7 +219,7 @@ NB: By default docker permits communication between containers on the
|
|||||||
same host, via their docker-assigned IP addresses. For complete
|
same host, via their docker-assigned IP addresses. For complete
|
||||||
isolation between application containers, that feature needs to be
|
isolation between application containers, that feature needs to be
|
||||||
disabled by
|
disabled by
|
||||||
[setting `--icc=false`](https://docs.docker.com/articles/networking/#between-containers)
|
[setting `--icc=false`](https://docs.docker.com/engine/userguide/networking/default_network/container-communication/#communication-between-containers)
|
||||||
in the docker daemon configuration. Furthermore, containers should be
|
in the docker daemon configuration. Furthermore, containers should be
|
||||||
prevented from capturing and injecting raw network packets - this can
|
prevented from capturing and injecting raw network packets - this can
|
||||||
be accomplished by starting them with the `--cap-drop net_raw` option.
|
be accomplished by starting them with the `--cap-drop net_raw` option.
|
||||||
@@ -307,6 +307,14 @@ supplying a password will [cause weave to fall back to a slower
|
|||||||
method](#fast-data-path) for transporting data between
|
method](#fast-data-path) for transporting data between
|
||||||
peers.
|
peers.
|
||||||
|
|
||||||
|
Be aware that:
|
||||||
|
|
||||||
|
* Containers will be able to access the router REST API if you have
|
||||||
|
disabled fast datapath. You can prevent this by setting
|
||||||
|
[`--icc=false`](https://docs.docker.com/engine/userguide/networking/default_network/container-communication/#communication-between-containers)
|
||||||
|
* Containers are able to access the router control and data plane
|
||||||
|
ports, but you can mitigate this by enabling encryption
|
||||||
|
|
||||||
### <a name="host-network-integration"></a>Host network integration
|
### <a name="host-network-integration"></a>Host network integration
|
||||||
|
|
||||||
Weave application networks can be integrated with a host's network,
|
Weave application networks can be integrated with a host's network,
|
||||||
|
|||||||
+18
-16
@@ -105,21 +105,11 @@ range. This can be overridden with the `--ipalloc-range` option, e.g.
|
|||||||
|
|
||||||
and must be the same on every host.
|
and must be the same on every host.
|
||||||
|
|
||||||
> The specified range is for *exclusive* use by the IP allocator. In
|
|
||||||
> particular, when starting containers with manually assigned IP
|
|
||||||
> addresses, these must be outside the IP allocator's range. If, in
|
|
||||||
> our example, you subsequently executed `docker run -e
|
|
||||||
> WEAVE_CIDR=10.2.3.1/24 -ti ubuntu`, the IP allocator might assign
|
|
||||||
> the same address to another container, which will break IP routing
|
|
||||||
> for the containers sharing an address.
|
|
||||||
|
|
||||||
The range parameter is written in
|
The range parameter is written in
|
||||||
[CIDR notation](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) -
|
[CIDR notation](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) -
|
||||||
in this example "/16" means the first 16 bits of the address form the
|
in this example "/16" means the first 16 bits of the address form the
|
||||||
network address and the allocator is to allocate container addresses
|
network address and the allocator is to allocate container addresses
|
||||||
that all start 10.2. The ".0" and ".-1" addresses in a subnet are not
|
that all start 10.2.
|
||||||
used, as required by
|
|
||||||
[RFC 1122](https://tools.ietf.org/html/rfc1122#page-29).
|
|
||||||
|
|
||||||
Weave shares the IP address range across all peers, dynamically
|
Weave shares the IP address range across all peers, dynamically
|
||||||
according to their needs. If a group of peers becomes isolated from
|
according to their needs. If a group of peers becomes isolated from
|
||||||
@@ -129,11 +119,16 @@ to the rest of the network without any conflicts arising.
|
|||||||
|
|
||||||
## <a name="subnets"></a>Automatic allocation across multiple subnets
|
## <a name="subnets"></a>Automatic allocation across multiple subnets
|
||||||
|
|
||||||
When
|
IP subnets are used to define or restrict routing. By default, weave
|
||||||
[running containers on different subnets](features.html#application-isolation),
|
puts all containers in a subnet that spans the entire allocation
|
||||||
you may wish to request the allocation of an address from a particular
|
range, so every weave-attached container can talk to every other
|
||||||
subnet. This is done by specifying the subnet with `net:<subnet>`, in
|
weave-attached container.
|
||||||
CIDR notation, e.g.
|
|
||||||
|
If you want some [isolation](features.html#application-isolation), you
|
||||||
|
can choose to run containers on different subnets. To request the
|
||||||
|
allocation of an address from a particular subnet, set the
|
||||||
|
`WEAVE_CIDR` environment variable to `net:<subnet>` when creating the
|
||||||
|
container, e.g.
|
||||||
|
|
||||||
host1$ docker run -e WEAVE_CIDR=net:10.2.7.0/24 -ti ubuntu
|
host1$ docker run -e WEAVE_CIDR=net:10.2.7.0/24 -ti ubuntu
|
||||||
|
|
||||||
@@ -143,6 +138,9 @@ for instance:
|
|||||||
|
|
||||||
host1$ docker run -e WEAVE_CIDR="net:10.2.7.0/24 net:10.2.8.0/24 ip:10.3.9.1/24" -ti ubuntu
|
host1$ docker run -e WEAVE_CIDR="net:10.2.7.0/24 net:10.2.8.0/24 ip:10.3.9.1/24" -ti ubuntu
|
||||||
|
|
||||||
|
(Note the ".0" and ".-1" addresses in a subnet are not used, as required by
|
||||||
|
[RFC 1122](https://tools.ietf.org/html/rfc1122#page-29)).
|
||||||
|
|
||||||
When working with multiple subnets in this way, it is usually
|
When working with multiple subnets in this way, it is usually
|
||||||
desirable to constrain the default subnet - i.e. the one chosen by the
|
desirable to constrain the default subnet - i.e. the one chosen by the
|
||||||
allocator when no subnet is supplied - so that it does not overlap
|
allocator when no subnet is supplied - so that it does not overlap
|
||||||
@@ -227,3 +225,7 @@ guide](troubleshooting.html#weave-status) for full details.
|
|||||||
|
|
||||||
The 'Service: ipam' section displays the consensus state as well as
|
The 'Service: ipam' section displays the consensus state as well as
|
||||||
the total allocation range and default subnet.
|
the total allocation range and default subnet.
|
||||||
|
|
||||||
|
Note that the 'Range' is written using interval notation - '[' means
|
||||||
|
the start of the range is included and ')' means the end of the range
|
||||||
|
is not included.
|
||||||
+4
-4
@@ -57,13 +57,13 @@ All docker commands can be run via the proxy, so it is safe to adjust
|
|||||||
your `DOCKER_HOST` to point at the proxy. Weave provides a convenient
|
your `DOCKER_HOST` to point at the proxy. Weave provides a convenient
|
||||||
command for this:
|
command for this:
|
||||||
|
|
||||||
host1$ eval "$(weave env)"
|
host1$ eval $(weave env)
|
||||||
host1$ docker ps
|
host1$ docker ps
|
||||||
...
|
...
|
||||||
|
|
||||||
The prior settings can be restored with
|
The prior settings can be restored with
|
||||||
|
|
||||||
host1$ eval "$(weave env --restore)"
|
host1$ eval $(weave env --restore)
|
||||||
|
|
||||||
Alternatively, the proxy host can be set on a per-command basis with
|
Alternatively, the proxy host can be set on a per-command basis with
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ ultimately be handed over to weaveDNS for registration.
|
|||||||
For instance, we can launch the proxy using all three flags
|
For instance, we can launch the proxy using all three flags
|
||||||
|
|
||||||
host1$ weave launch-router && weave launch-proxy --hostname-from-label hostname-label --hostname-match '^aws-[0-9]+-(.*)$' --hostname-replacement 'my-app-$1'
|
host1$ weave launch-router && weave launch-proxy --hostname-from-label hostname-label --hostname-match '^aws-[0-9]+-(.*)$' --hostname-replacement 'my-app-$1'
|
||||||
host1$ eval "$(weave env)"
|
host1$ eval $(weave env)
|
||||||
|
|
||||||
Note how regexp substitution groups should be prepended with a dollar sign
|
Note how regexp substitution groups should be prepended with a dollar sign
|
||||||
(e.g. `$1`). For further details on the regular expression syntax please see
|
(e.g. `$1`). For further details on the regular expression syntax please see
|
||||||
@@ -264,7 +264,7 @@ with
|
|||||||
|
|
||||||
$ mkdir -pv ~/.docker
|
$ mkdir -pv ~/.docker
|
||||||
$ cp -v {ca,cert,key}.pem ~/.docker
|
$ cp -v {ca,cert,key}.pem ~/.docker
|
||||||
$ eval "$(weave env)"
|
$ eval $(weave env)
|
||||||
$ export DOCKER_TLS_VERIFY=1
|
$ export DOCKER_TLS_VERIFY=1
|
||||||
$ docker version
|
$ docker version
|
||||||
...
|
...
|
||||||
|
|||||||
Executable
+22
@@ -0,0 +1,22 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
. ./config.sh
|
||||||
|
|
||||||
|
start_suite "Rolling restart with reset"
|
||||||
|
|
||||||
|
weave_on $HOST1 launch-router
|
||||||
|
weave_on $HOST2 launch-router $HOST1
|
||||||
|
|
||||||
|
start_container $HOST1 --name=c1
|
||||||
|
start_container $HOST2 --name=c2
|
||||||
|
|
||||||
|
# Now reset the routers so they should give their space away, and restart
|
||||||
|
weave_on $HOST1 reset
|
||||||
|
weave_on $HOST1 launch-router $HOST2
|
||||||
|
weave_on $HOST2 reset
|
||||||
|
weave_on $HOST2 launch-router $HOST1
|
||||||
|
|
||||||
|
# And try to start a container
|
||||||
|
assert_raises "timeout 10 cat <( start_container $HOST1 )"
|
||||||
|
|
||||||
|
end_suite
|
||||||
@@ -21,6 +21,13 @@ start_container_with_dns $HOST1 $C1/24 --name=c1 $STATICS_ARGS
|
|||||||
|
|
||||||
assert_dns_record $HOST1 c1 $NAME $C2
|
assert_dns_record $HOST1 c1 $NAME $C2
|
||||||
|
|
||||||
|
# Check that 'weave expose -h' names are added to DNS
|
||||||
|
weave_on $HOST1 expose
|
||||||
|
EXPOSE=$(weave_on $HOST1 expose -h testexpose1.weave.local)
|
||||||
|
weave_on $HOST1 expose -h testexpose2.weave.local
|
||||||
|
assert_dns_record $HOST1 c1 testexpose1.weave.local $EXPOSE
|
||||||
|
assert_dns_record $HOST1 c1 testexpose2.weave.local
|
||||||
|
|
||||||
# check we respect the --add-host arguments
|
# check we respect the --add-host arguments
|
||||||
for C in c1 c2 ; do
|
for C in c1 c2 ; do
|
||||||
assert_dns_a_record $HOST1 $C $STATIC1_NAME $STATIC1
|
assert_dns_a_record $HOST1 $C $STATIC1_NAME $STATIC1
|
||||||
|
|||||||
@@ -7,10 +7,22 @@ C2=10.2.0.34
|
|||||||
NAME=seetwo.weave.local
|
NAME=seetwo.weave.local
|
||||||
|
|
||||||
check_attached() {
|
check_attached() {
|
||||||
assert_raises "proxy exec_on $HOST1 c2 $CHECK_ETHWE_UP"
|
assert_raises "exec_on $HOST1 c2 $CHECK_ETHWE_UP"
|
||||||
assert_dns_record $HOST1 c1 $NAME $C2
|
assert_dns_record $HOST1 c1 $NAME $C2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wait_for_proxy() {
|
||||||
|
for i in $(seq 1 120); do
|
||||||
|
echo "Waiting for proxy to start"
|
||||||
|
if proxy docker_on $1 info > /dev/null 2>&1 ; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
echo "Timed out waiting for proxy to start" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
start_suite "Proxy restart reattaches networking to containers"
|
start_suite "Proxy restart reattaches networking to containers"
|
||||||
|
|
||||||
WEAVE_DOCKER_ARGS=--restart=always WEAVEPROXY_DOCKER_ARGS=--restart=always weave_on $HOST1 launch
|
WEAVE_DOCKER_ARGS=--restart=always WEAVEPROXY_DOCKER_ARGS=--restart=always weave_on $HOST1 launch
|
||||||
@@ -32,13 +44,13 @@ check_attached
|
|||||||
|
|
||||||
# Restart docker itself, using different commands for systemd- and upstart-managed.
|
# Restart docker itself, using different commands for systemd- and upstart-managed.
|
||||||
run_on $HOST1 sh -c "command -v systemctl >/dev/null && sudo systemctl restart docker || sudo service docker restart"
|
run_on $HOST1 sh -c "command -v systemctl >/dev/null && sudo systemctl restart docker || sudo service docker restart"
|
||||||
sleep 10
|
wait_for_proxy $HOST1
|
||||||
check_attached
|
check_attached
|
||||||
|
|
||||||
# Restarting proxy shouldn't kill unattachable containers
|
# Restarting proxy shouldn't kill unattachable containers
|
||||||
proxy_start_container $HOST1 -di --name=c3 --restart=always # Use ipam, so it won't be attachable w/o weave
|
proxy_start_container $HOST1 -di --name=c3 --restart=always # Use ipam, so it won't be attachable w/o weave
|
||||||
weave_on $HOST1 stop
|
weave_on $HOST1 stop
|
||||||
weave_on $HOST1 launch-proxy
|
weave_on $HOST1 launch-proxy
|
||||||
assert_raises "proxy exec_on $HOST1 c3 $CHECK_ETHWE_UP"
|
assert_raises "exec_on $HOST1 c3 $CHECK_ETHWE_UP"
|
||||||
|
|
||||||
end_suite
|
end_suite
|
||||||
@@ -9,8 +9,8 @@ docker_bridge_ip=$(weave_on $HOST1 docker-bridge-ip)
|
|||||||
proxy_start_container $HOST1 --name=c1
|
proxy_start_container $HOST1 --name=c1
|
||||||
|
|
||||||
check_hostconfig() {
|
check_hostconfig() {
|
||||||
docker_on $HOST1 attach c2 >/dev/null 2>&1 || true # Wait for container to exit
|
docker_on $HOST1 attach $1 >/dev/null 2>&1 || true # Wait for container to exit
|
||||||
assert "docker_on $HOST1 inspect -f '{{.HostConfig.Dns}} {{.HostConfig.NetworkMode}} {{.State.Running}} {{.State.ExitCode}}' $1" "[$docker_bridge_ip] $2 false 0"
|
assert "docker_on $HOST1 inspect -f '{{.HostConfig.Dns}} {{.HostConfig.NetworkMode}} {{.State.Running}} {{.State.ExitCode}}' $1" "[$3] $2 false 0"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Start c2 with a sneaky HostConfig
|
# Start c2 with a sneaky HostConfig
|
||||||
@@ -26,7 +26,7 @@ check_hostconfig c5 container:c1
|
|||||||
# Start c3 with HostConfig having empty binds and null dns/networking settings
|
# Start c3 with HostConfig having empty binds and null dns/networking settings
|
||||||
proxy docker_on $HOST1 create --name=c3 -v /tmp:/hosttmp $SMALL_IMAGE $CHECK_ETHWE_UP
|
proxy docker_on $HOST1 create --name=c3 -v /tmp:/hosttmp $SMALL_IMAGE $CHECK_ETHWE_UP
|
||||||
proxy docker_api_on $HOST1 POST /containers/c3/start '{"Binds":[],"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,"Devices":null,"NetworkMode":""}'
|
proxy docker_api_on $HOST1 POST /containers/c3/start '{"Binds":[],"Dns":null,"DnsSearch":null,"ExtraHosts":null,"VolumesFrom":null,"Devices":null,"NetworkMode":""}'
|
||||||
check_hostconfig c3 default
|
check_hostconfig c3 default $docker_bridge_ip
|
||||||
|
|
||||||
# Start c4 with an 'null' HostConfig and check this doesn't remove previous parameters
|
# Start c4 with an 'null' HostConfig and check this doesn't remove previous parameters
|
||||||
proxy docker_on $HOST1 create --name=c4 --memory-swap -1 $SMALL_IMAGE echo foo
|
proxy docker_on $HOST1 create --name=c4 --memory-swap -1 $SMALL_IMAGE echo foo
|
||||||
@@ -42,6 +42,17 @@ check_hostconfig c6 container:c1
|
|||||||
proxy docker_on $HOST1 create --name=c7 --memory-swap -1 $SMALL_IMAGE $CHECK_ETHWE_UP
|
proxy docker_on $HOST1 create --name=c7 --memory-swap -1 $SMALL_IMAGE $CHECK_ETHWE_UP
|
||||||
proxy docker_api_on $HOST1 POST /containers/c7/start '{"HostConfig":{}}'
|
proxy docker_api_on $HOST1 POST /containers/c7/start '{"HostConfig":{}}'
|
||||||
assert "docker_on $HOST1 inspect -f '{{.HostConfig.MemorySwap}}' c7" "0"
|
assert "docker_on $HOST1 inspect -f '{{.HostConfig.MemorySwap}}' c7" "0"
|
||||||
check_hostconfig c7 default
|
check_hostconfig c7 default $docker_bridge_ip
|
||||||
|
|
||||||
|
# Start c8 in host network mode
|
||||||
|
proxy docker_on $HOST1 create --name=c8 $SMALL_IMAGE $CHECK_ETHWE_MISSING
|
||||||
|
proxy docker_api_on $HOST1 POST /containers/c8/start '{"HostConfig": {"NetworkMode": "host"}}'
|
||||||
|
check_hostconfig c8 host
|
||||||
|
|
||||||
|
# Start c10 in network of host container
|
||||||
|
proxy_start_container $HOST1 --name=c9 --net=host
|
||||||
|
proxy docker_on $HOST1 create --name=c10 $SMALL_IMAGE $CHECK_ETHWE_MISSING
|
||||||
|
proxy docker_api_on $HOST1 POST /containers/c10/start '{"HostConfig": {"NetworkMode": "container:c9"}}'
|
||||||
|
check_hostconfig c10 container:c9
|
||||||
|
|
||||||
end_suite
|
end_suite
|
||||||
@@ -40,6 +40,7 @@ TEST_IMAGES="$SMALL_IMAGE $DNS_IMAGE"
|
|||||||
|
|
||||||
PING="ping -nq -W 1 -c 1"
|
PING="ping -nq -W 1 -c 1"
|
||||||
CHECK_ETHWE_UP="grep ^1$ /sys/class/net/ethwe/carrier"
|
CHECK_ETHWE_UP="grep ^1$ /sys/class/net/ethwe/carrier"
|
||||||
|
CHECK_ETHWE_MISSING="test ! -d /sys/class/net/ethwe"
|
||||||
|
|
||||||
DOCKER_PORT=2375
|
DOCKER_PORT=2375
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ type TestRouterClient struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (grouter *TestRouter) run(sender router.PeerName, gossiper router.Gossiper, gossipChan chan interface{}) {
|
func (grouter *TestRouter) run(sender router.PeerName, gossiper router.Gossiper, gossipChan chan interface{}) {
|
||||||
gossipTimer := time.Tick(10 * time.Second)
|
gossipTimer := time.Tick(2 * time.Second)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case gossip := <-gossipChan:
|
case gossip := <-gossipChan:
|
||||||
|
|||||||
+1
-1
@@ -60,6 +60,6 @@ export DEBIAN_FRONTEND=noninteractive
|
|||||||
/etc/init.d/puppet stop
|
/etc/init.d/puppet stop
|
||||||
apt-get -qq remove puppet chef
|
apt-get -qq remove puppet chef
|
||||||
apt-get -qq autoremove
|
apt-get -qq autoremove
|
||||||
killall -9 chef-client
|
killall -9 chef-client 2>/dev/null || true
|
||||||
SCRIPT
|
SCRIPT
|
||||||
end
|
end
|
||||||
@@ -420,6 +420,10 @@ create_bridge() {
|
|||||||
run_iptables -t filter -I FORWARD -i $DOCKER_BRIDGE -o $BRIDGE -j DROP
|
run_iptables -t filter -I FORWARD -i $DOCKER_BRIDGE -o $BRIDGE -j DROP
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# let DNS traffic to weaveDNS, since otherwise it might get blocked by the likes of UFW
|
||||||
|
add_iptables_rule filter INPUT -i $DOCKER_BRIDGE -p udp --dport 53 -j ACCEPT
|
||||||
|
add_iptables_rule filter INPUT -i $DOCKER_BRIDGE -p tcp --dport 53 -j ACCEPT
|
||||||
|
|
||||||
# Work around the situation where there are no rules allowing traffic
|
# Work around the situation where there are no rules allowing traffic
|
||||||
# across our bridge. E.g. ufw
|
# across our bridge. E.g. ufw
|
||||||
add_iptables_rule filter FORWARD -i $BRIDGE -o $BRIDGE -j ACCEPT
|
add_iptables_rule filter FORWARD -i $BRIDGE -o $BRIDGE -j ACCEPT
|
||||||
@@ -525,6 +529,8 @@ destroy_bridge() {
|
|||||||
run_iptables -t filter -D FORWARD -i $DOCKER_BRIDGE -o $BRIDGE -j DROP 2>/dev/null || true
|
run_iptables -t filter -D FORWARD -i $DOCKER_BRIDGE -o $BRIDGE -j DROP 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
run_iptables -t filter -D INPUT -i $DOCKER_BRIDGE -p udp --dport 53 -j ACCEPT >/dev/null 2>&1 || true
|
||||||
|
run_iptables -t filter -D INPUT -i $DOCKER_BRIDGE -p tcp --dport 53 -j ACCEPT >/dev/null 2>&1 || true
|
||||||
run_iptables -t filter -D FORWARD -i $BRIDGE -o $BRIDGE -j ACCEPT 2>/dev/null || true
|
run_iptables -t filter -D FORWARD -i $BRIDGE -o $BRIDGE -j ACCEPT 2>/dev/null || true
|
||||||
run_iptables -t nat -F WEAVE >/dev/null 2>&1 || true
|
run_iptables -t nat -F WEAVE >/dev/null 2>&1 || true
|
||||||
run_iptables -t nat -D POSTROUTING -j WEAVE >/dev/null 2>&1 || true
|
run_iptables -t nat -D POSTROUTING -j WEAVE >/dev/null 2>&1 || true
|
||||||
@@ -1475,7 +1481,7 @@ launch_router() {
|
|||||||
$(router_opts_$BRIDGE_TYPE) \
|
$(router_opts_$BRIDGE_TYPE) \
|
||||||
--ipalloc-range "$IPRANGE" \
|
--ipalloc-range "$IPRANGE" \
|
||||||
--dns-effective-listen-address $DOCKER_BRIDGE_IP \
|
--dns-effective-listen-address $DOCKER_BRIDGE_IP \
|
||||||
${NETHOST_OPT:+$DNS_ROUTER_OPTS} $NO_DNS_OPT \
|
${NETHOST_OPT:+$DNS_ROUTER_OPTS --http-addr 127.0.0.1:$HTTP_PORT} $NO_DNS_OPT \
|
||||||
--docker-api "unix:///var/run/docker.sock" "$@")
|
--docker-api "unix:///var/run/docker.sock" "$@")
|
||||||
with_container_netns_or_die $CONTAINER_NAME setup_router_iface_$BRIDGE_TYPE
|
with_container_netns_or_die $CONTAINER_NAME setup_router_iface_$BRIDGE_TYPE
|
||||||
attach_router
|
attach_router
|
||||||
@@ -1896,9 +1902,9 @@ EOF
|
|||||||
arp_update $BRIDGE $CIDR
|
arp_update $BRIDGE $CIDR
|
||||||
add_iptables_rule nat WEAVE -d $CIDR ! -s $CIDR -j MASQUERADE
|
add_iptables_rule nat WEAVE -d $CIDR ! -s $CIDR -j MASQUERADE
|
||||||
add_iptables_rule nat WEAVE -s $CIDR ! -d $CIDR -j MASQUERADE
|
add_iptables_rule nat WEAVE -s $CIDR ! -d $CIDR -j MASQUERADE
|
||||||
if [ -n "$FQDN" ] ; then
|
fi
|
||||||
when_weave_running put_dns_fqdn_no_check_alive weave:expose $FQDN $CIDR
|
if [ -n "$FQDN" ] ; then
|
||||||
fi
|
when_weave_running put_dns_fqdn_no_check_alive weave:expose $FQDN $CIDR
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
show_addrs $ALL_CIDRS
|
show_addrs $ALL_CIDRS
|
||||||
@@ -1927,8 +1933,8 @@ EOF
|
|||||||
;;
|
;;
|
||||||
stop)
|
stop)
|
||||||
[ $# -eq 0 ] || usage
|
[ $# -eq 0 ] || usage
|
||||||
stop_proxy
|
|
||||||
stop_router
|
stop_router
|
||||||
|
stop_proxy
|
||||||
;;
|
;;
|
||||||
stop-router)
|
stop-router)
|
||||||
[ $# -eq 0 ] || usage
|
[ $# -eq 0 ] || usage
|
||||||
|
|||||||
Reference in new issue
Block a user