Compare commits

...
51 Commits
Author SHA1 Message Date
Adam Harrison 6c0075ab82 Add release v1.4.6 2016-03-23 17:37:21 +00:00
Matthias Radestock ae0a4fef50 Merge pull request #2092 from weaveworks/issues/2083-error-not-panic
Change invariant fail on Merge() from panic to error

Fixes #2083.
2016-03-23 16:38:52 +00:00
Matthias Radestock 8360024e06 Merge pull request #2088 from weaveworks/issues/2087-leave-direct-targets
Don't delete targets that seem invalid if they are 'direct' targets

Fixes #2087.
2016-03-23 16:22:08 +00:00
Bryan Boreham 2e4d56efd6 Suspend connecting to targets that seem invalid, if they are 'direct' targets.
Introduce TargetSuspended state to reflect this.
2016-03-23 15:36:55 +00:00
Bryan Boreham 6bc199a8bc Change invariant fail on Merge() from panic to error 2016-03-23 15:26:26 +00:00
Matthias Radestock 537868008f make linter happy 2016-03-22 16:28:25 +00:00
Matthias Radestock 1664fce9d1 Merge pull request #2081 from weaveworks/issues/2023-override-stale-dns
Override stale dns entries received via gossip

Fixes #1867 and #2023.
2016-03-22 13:47:17 +00:00
Bryan Boreham c2cf825cdf Smoke test for stale DNS entries 2016-03-22 12:57:07 +00:00
Bryan Boreham 38a79b7f59 Pick entry with newer tombstone to merge 2016-03-22 12:57:07 +00:00
Bryan Boreham 010766fe9e Check entries claiming to originate from us against our current data, and override if necessary 2016-03-22 12:57:07 +00:00
Matthias Radestock 6b33f4215b Merge branch 'latest_release_doc_updates' into 1.4 2016-03-21 15:53:18 +00:00
Matthias Radestock cc43782d87 Merge pull request #2080 from weaveworks/issues/2061-correct-weave-status
Correct IPAM state docs

Fixes #2061.
2016-03-21 15:49:03 +00:00
Adam Harrison c2eb900dd3 Correct IPAM state docs 2016-03-21 15:33:37 +00:00
Bryan Boreham 001322751f Don't hold Nameserver lock over call out via isKnownPeer 2016-03-21 11:52:13 +00:00
Bryan Boreham b1ec2b788a Bump template name so it will fetch latest Docker 2016-03-19 14:12:17 +00:00
Matthias Radestock f42e275884 broadcast ipam ring update after rmpeer
So that other peers notice the change more promptly.

Fixes #2068.
2016-03-19 13:57:20 +00:00
Matthias Radestock 5dfd104728 reduce docker event subscription retry max interval 2016-03-18 19:29:21 +00:00
Bryan Boreham 9c096526b8 Merge pull request #2049 from weaveworks/issues/2016-retry-docker-event-subscription
Retry docker event subscription
2016-03-16 14:38:27 +00:00
Adam Harrison 922f465ecb Reset retry interval if we spent long enough processing events 2016-03-16 13:41:18 +00:00
Adam Harrison 08e9db900a Retry docker event subscription 2016-03-16 09:23:32 +00:00
Adam Harrison 30b9d33276 Adjust tests to accomodate docker/docker#14012 2016-03-02 11:59:10 +00:00
Bryan Boreham be3f88656b Add release v1.4.5 2016-02-29 22:28:58 +00:00
David Wragg 27367ab292 Process DiscardingFlowOp correctly in FastDatapath send()
The nil FlowOp check in collectFlowOps was not addressed with the
introduction of DiscardingFlowOp.  This meant that DiscardingFlowOps
produced in the router core would get handled by fastdp as if they were
foreign FlowOps, preventing flow creation and so leading to unwarranted
ODP misses.

To fix this, collectFlowOps cannot simply eliminate FlowOps for which
Discards() is true, because it's true for odpFlowKeyFlowOp.  So the
Discards() case has to be handled in FastDatapath send().
2016-02-29 13:27:15 -08:00
Matthias Radestock 20620f0002 Merge branch 'latest_release_doc_updates' into 1.4 2016-02-29 19:13:00 +00:00
Matthias Radestock 8d79e33ba1 remove stale ToC entry
This was missed in 8b061fd55
2016-02-29 19:12:00 +00:00
Bryan Boreham ce4857f5dc Merge pull request #2001 from weaveworks/issues/1996-try-all-pending-allocations
Try all pending allocations - LGTM.  Fixes #1996
2016-02-29 08:20:49 -08:00
Adam Harrison bceabe32a2 Try all pending allocations
We can have outstanding allocations for different ranges owned by
different peers, so we should not short circuit after the first space
request.
2016-02-25 14:56:33 +00:00
Matthias Radestock 6a9f9f66dc don't check for 'Restarting' when attaching on startup
It is overkill.
2016-02-23 13:20:22 +00:00
Adam Harrison 639e0e82c9 Merge pull request #1989 from weaveworks/1977-restarting-not-running
treat 'restarting' as 'not running'
2016-02-23 10:49:31 +00:00
Adam Harrison 4b0a6e1433 Merge pull request #1983 from weaveworks/1929-auto-detect-odp-on-relaunch
don't complain on relaunch when ODP is not supported
2016-02-23 10:46:36 +00:00
Matthias Radestock cb6db91b09 Merge branch 'latest_release_doc_updates' into 1.4 2016-02-23 10:16:08 +00:00
Matthias Radestock 6a02e2dc17 explain TCP/UDP connections, heartbeats, back-off
Fixes #1969
2016-02-23 09:54:15 +00:00
Ilya Dmitrichenko b377207faf Merge branch 'latest_release_doc_updates' into 1.4 2016-02-22 14:16:02 +00:00
Ilya Dmitrichenko 24ebb7cc7c Add missing dependency for latest gsutil 2016-02-22 14:11:36 +00:00
Ilya Dmitrichenko b5518db03c Add missing argument to tar 2016-02-22 14:02:39 +00:00
Ilya Dmitrichenko 2aa4e6a83a Use "official" gsutil installation instructions 2016-02-22 13:58:42 +00:00
Ilya Dmitrichenko 7c655cc3ba Fix false-positive docs uploads 2016-02-22 13:56:49 +00:00
Matthias Radestock 75cda01167 Merge branch 'latest_release_doc_updates' into 1.4 2016-02-22 13:55:18 +00:00
Matthias Radestock 4f0f3cf98d warn against using the plugin in combination with --net=weave
and expand the basic proxy usage docs slightly.
2016-02-22 13:53:39 +00:00
Matthias Radestock e014140134 Merge branch 'latest_release_doc_updates' into 1.4 2016-02-22 13:36:33 +00:00
Matthias Radestock c8ae128e59 for Travis, this no longer is a go project
Travis insists that one picks a project language. There is no go left
in the steps executed by travis. Instead we have Python, Ruby and
shell. Let's pick the first...

Picking Python makes travis unhappy with "Can not perform a '--user'
install. User site-packages are not visible in this
virtualenv". Dropping the '--user' flag fixes that.

(cherry picked from commit 1d8d098450)
2016-02-22 13:29:33 +00:00
Matthias Radestock 12d848162d shrink Travis usage
There is no point running builds, tests, lints on Travis, since we
already do that on Circle.

The only thing we aren't doing (and can't do) on Circle is doc
publishing, so now Travis does just that.

(cherry picked from commit 1038cbd1a3)
2016-02-22 13:29:33 +00:00
Matthias Radestock b12096bd6c tweak 2016-02-22 13:23:29 +00:00
Matthias Radestock 1430982166 Merge branch 'latest_release_doc_updates' into 1.4 2016-02-22 13:13:13 +00:00
Matthias Radestock 2a83aad1d6 warn against using plugin and proxy simultaneously
and give a complete example.

Partially addresses #1988.
2016-02-22 13:11:02 +00:00
Matthias Radestock 4a7157959a don't attempt to attach 'restarting' containers
this is an optimisation... there is no point attempting to attach a
'restarting' container - it will fail.

When the container *actually* restarts we'll get a 'Start' event, and
attach at that point.

Also, there is no point checking for 'Paused' since 'Paused' ->
'Running'.
2016-02-20 11:00:04 +00:00
Matthias Radestock e52abafc48 treat restarting containers as "not running"
thus preventing stale DNS & IPAM entries.

Fixes #1977
2016-02-20 10:59:47 +00:00
Matthias Radestock ee531b8023 don't complain on relaunch when ODP is not supported
...and WEAVE_NO_FASTDP isn't set.

Fixes #1929.
2016-02-18 22:00:08 +00:00
Matthias Radestock 5e761a62b0 Merge pull request #1985 from weaveworks/issues/1984-discovery
Add two functions required by ipamapi "contract"

Fixes #1984
2016-02-18 21:55:53 +00:00
Bryan Boreham b442567406 Add two functions required by ipamapi "contract" but not actually used 2016-02-18 15:29:10 +00:00
Matthias Radestock 17d53af2a2 improve logging of dns entry creation
- log inside the lock, so we get proper serialisation
- include the container name, so we can identify the specific entry
2016-02-16 14:04:34 +00:00
24 changed files with 291 additions and 100 deletions

No files matched your search

+5 -20
View File
@@ -1,28 +1,13 @@
language: go
language: python
sudo: false
go:
- 1.4
env:
- PATH="${PATH}:${HOME}/.local/bin"
addons:
apt:
packages:
- libpcap-dev
- PATH="${PATH}:${HOME}/gsutil"
install:
- go clean -i net
- go install -tags netgo std
- go get github.com/golang/lint/golint
- pip install --user --upgrade gsutil
- pip install pyopenssl
- curl --silent --location https://storage.googleapis.com/pub/gsutil.tar.gz | tar xz -C $HOME
- bin/setup-ci-secrets $encrypted_5ba036e89377_key $encrypted_5ba036e89377_iv
- make travis
- go get ./...
script:
- make tests
after_success:
- go get github.com/mattn/goveralls
- test "${TRAVIS_PULL_REQUEST}" = "false" && site/build-and-publish.sh
- 'test "${TRAVIS_PULL_REQUEST}" = "true" || site/build-and-publish.sh'
+36
View File
@@ -1,3 +1,39 @@
## Release 1.4.6
Fixes some issues encountered by our users.
* Restarting a peer could leave stale entries in WeaveDNS
#1867/#2023/#2081
* Weave proxy occasionally failing to attach any new containers
#2016/#2049
Other fixes:
* Resolved a crash when a restarting peer re-connected to a peer that
had not received the latest IPAM data #2083/#2092
* Make IP address space available immediately after a dead peer is
removed #2068
## Release 1.4.5
Higher performance for multicast and broadcast traffic when using
Weave's Fast Datapath
* The flow rule to deliver broadcast and multicast packets in-kernel
was not created correctly, hence every such packet caused a
context-switch to the software router #2003/#2008
Other fixes:
* Remove DNS entries for containers that are being restarted by Docker
but are not live yet #1977/#1989
* Don't let one failing allocation attempt prevent others from
succeeding; they could be in different subnets which are more
available #1996/#2001
* Don't complain on second router launch on kernels that lack support
for Fast Datapath #1929/#1983
* Fix build broken by change in libnetwork IPAM API #1984/#1985
## Release 1.4.4
Fixing a rather serious issue that slipped through our preparations
+33 -15
View File
@@ -4,12 +4,18 @@ import (
"errors"
"fmt"
"strings"
"time"
docker "github.com/fsouza/go-dockerclient"
. "github.com/weaveworks/weave/common"
)
const (
InitialInterval = 1 * time.Second
MaxInterval = 20 * time.Second
)
// An observer for container events
type ContainerObserver interface {
ContainerStarted(ident string)
@@ -72,21 +78,33 @@ func (c *Client) Info() string {
// AddObserver adds an observer for docker events
func (c *Client) AddObserver(ob ContainerObserver) error {
events := make(chan *docker.APIEvents)
if err := c.AddEventListener(events); err != nil {
Log.Errorf("[docker] Unable to add listener to Docker API: %s", err)
return err
}
go func() {
for event := range events {
switch event.Status {
case "start":
id := event.ID
ob.ContainerStarted(id)
case "die":
id := event.ID
ob.ContainerDied(id)
retryInterval := InitialInterval
for {
events := make(chan *docker.APIEvents)
if err := c.AddEventListener(events); err != nil {
Log.Errorf("[docker] Unable to add listener to Docker API: %s - retrying in %ds", err, retryInterval/time.Second)
} else {
start := time.Now()
for event := range events {
switch event.Status {
case "start":
id := event.ID
ob.ContainerStarted(id)
case "die":
id := event.ID
ob.ContainerDied(id)
}
}
if time.Since(start) > retryInterval {
retryInterval = InitialInterval
}
Log.Errorf("[docker] Event listener channel closed - retrying subscription in %ds", retryInterval/time.Second)
}
time.Sleep(retryInterval)
retryInterval = retryInterval * 3 / 2
if retryInterval > MaxInterval {
retryInterval = MaxInterval
}
}
}()
@@ -97,7 +115,7 @@ func (c *Client) AddObserver(ob ContainerObserver) error {
func (c *Client) IsContainerNotRunning(idStr string) bool {
container, err := c.InspectContainer(idStr)
if err == nil {
return !container.State.Running
return !container.State.Running || container.State.Restarting
}
if _, notThere := err.(*docker.NoSuchContainer); notThere {
return true
+15 -18
View File
@@ -140,29 +140,23 @@ func (alloc *Allocator) cancelOpsFor(ops *[]operation, ident string) bool {
return found
}
// Try all pending operations
func (alloc *Allocator) tryPendingOps() {
// The slightly different semantics requires us to operate on 'claims' and
// 'allocates' separately:
// Claims must be tried before Allocates
for i := 0; i < len(alloc.pendingClaims); {
op := alloc.pendingClaims[i]
// Try all operations in a queue
func (alloc *Allocator) tryOps(ops *[]operation) {
for i := 0; i < len(*ops); {
op := (*ops)[i]
if !op.Try(alloc) {
i++
continue
}
alloc.pendingClaims = append(alloc.pendingClaims[:i], alloc.pendingClaims[i+1:]...)
*ops = append((*ops)[:i], (*ops)[i+1:]...)
}
}
// When the first Allocate fails, bail - no need to
// send too many begs for space.
for i := 0; i < len(alloc.pendingAllocates); {
op := alloc.pendingAllocates[i]
if !op.Try(alloc) {
break
}
alloc.pendingAllocates = append(alloc.pendingAllocates[:i], alloc.pendingAllocates[i+1:]...)
}
// Try all pending operations
func (alloc *Allocator) tryPendingOps() {
// Process existing claims before servicing new allocations
alloc.tryOps(&alloc.pendingClaims)
alloc.tryOps(&alloc.pendingAllocates)
}
func (alloc *Allocator) spaceRequestDenied(sender mesh.PeerName, r address.Range) {
@@ -340,7 +334,10 @@ func (alloc *Allocator) AdminTakeoverRanges(peerNameOrNickname string) error {
}
newRanges, err := alloc.ring.Transfer(peername, alloc.ourName)
alloc.space.AddRanges(newRanges)
if err == nil && len(newRanges) > 0 {
alloc.space.AddRanges(newRanges)
alloc.gossip.GossipBroadcast(alloc.Gossip())
}
resultChan <- err
}
return <-resultChan
+16 -9
View File
@@ -46,33 +46,37 @@ var (
)
func (r *Ring) checkInvariants() error {
if !sort.IsSorted(r.Entries) {
return r.checkEntries(r.Entries)
}
func (r *Ring) checkEntries(entries entries) error {
if !sort.IsSorted(entries) {
return ErrNotSorted
}
// Check no token appears twice
// We know it's sorted...
for i := 1; i < len(r.Entries); i++ {
if r.Entries[i-1].Token == r.Entries[i].Token {
for i := 1; i < len(entries); i++ {
if entries[i-1].Token == entries[i].Token {
return ErrTokenRepeated
}
}
if len(r.Entries) == 0 {
if len(entries) == 0 {
return nil
}
// Check tokens are in range
if r.Entries.entry(0).Token < r.Start {
if entries.entry(0).Token < r.Start {
return ErrTokenOutOfRange
}
if r.Entries.entry(-1).Token >= r.End {
if entries.entry(-1).Token >= r.End {
return ErrTokenOutOfRange
}
// Check all the freespaces are in range
for i, entry := range r.Entries {
next := r.Entries.entry(i + 1)
for i, entry := range entries {
next := entries.entry(i + 1)
distance := r.distance(entry.Token, next.Token)
if entry.Free > distance {
@@ -181,7 +185,6 @@ func (r *Ring) GrantRangeToHost(start, end address.Address, peer mesh.PeerName)
// Merge the given ring into this ring and return any new ranges added
func (r *Ring) Merge(gossip Ring) error {
r.assertInvariants()
defer r.assertInvariants()
defer r.updateExportedVariables()
// Don't panic when checking the gossiped in ring.
@@ -267,6 +270,10 @@ func (r *Ring) Merge(gossip Ring) error {
previousOwner = nil
}
if err := r.checkEntries(result); err != nil {
return fmt.Errorf("Merge of incoming data causes: %s", err)
}
if len(r.Seeds) == 0 {
r.Seeds = gossip.Seeds
}
+10 -2
View File
@@ -32,6 +32,7 @@ const (
TargetWaiting TargetState = iota // we are waiting to connect there
TargetAttempting // we are attempting to connect there
TargetConnected // we are connected to there
TargetSuspended // not currently attempting to connect here
)
// Information about an address where we may find a peer
@@ -266,16 +267,23 @@ func (cm *ConnectionMaker) connectToTargets(validTarget map[string]struct{}, dir
now := time.Now() // make sure we catch items just added
after := MaxDuration
for address, target := range cm.targets {
if target.state != TargetWaiting {
if target.state != TargetWaiting && target.state != TargetSuspended {
continue
}
if _, valid := validTarget[address]; !valid {
delete(cm.targets, address)
// Not valid: suspend reconnects if direct peer,
// otherwise forget this target entirely
if _, direct := directTarget[address]; direct {
target.state = TargetSuspended
} else {
delete(cm.targets, address)
}
continue
}
if target.tryAfter.IsZero() {
continue
}
target.state = TargetWaiting
switch duration := target.tryAfter.Sub(now); {
case duration <= 0:
target.state = TargetAttempting
+1
View File
@@ -181,6 +181,7 @@ func NewLocalConnectionStatusSlice(cm *ConnectionMaker) []LocalConnectionStatus
add("retrying", target.lastError.Error())
}
case TargetConnected:
case TargetSuspended:
}
}
resultChan <- slice
+20 -2
View File
@@ -93,6 +93,9 @@ func (e1 *Entry) merge(e2 *Entry) bool {
e1.Version = e2.Version
e1.Tombstone = e2.Tombstone
return true
} else if e2.Version == e1.Version && e2.Tombstone > e1.Tombstone {
e1.Tombstone = e2.Tombstone
return true
}
return false
}
@@ -105,6 +108,11 @@ func (e1 *Entry) addLowercase() {
e1.lHostname = strings.ToLower(e1.Hostname)
}
func (e1 *Entry) tombstone() {
e1.Version++
e1.Tombstone = now()
}
func check(es SortableEntries) error {
if !sort.IsSorted(es) {
return fmt.Errorf("Not sorted!")
@@ -182,8 +190,7 @@ func (es *Entries) tombstone(ourname mesh.PeerName, f func(*Entry) bool) Entries
tombstoned := Entries{}
for i, e := range *es {
if f(&e) && e.Origin == ourname {
e.Version++
e.Tombstone = now()
e.tombstone()
(*es)[i] = e
tombstoned = append(tombstoned, e)
}
@@ -191,6 +198,7 @@ func (es *Entries) tombstone(ourname mesh.PeerName, f func(*Entry) bool) Entries
return tombstoned
}
// note f() may only modify entries such that they remain in order defined by less()
func (es *Entries) filter(f func(*Entry) bool) {
defer es.checkAndPanic().checkAndPanic()
@@ -205,6 +213,16 @@ func (es *Entries) filter(f func(*Entry) bool) {
*es = (*es)[:i]
}
func (es Entries) findEqual(e *Entry) (*Entry, bool) {
i := sort.Search(len(es), func(i int) bool {
return !es[i].insensitiveLess(e)
})
if i < len(es) && es[i].equal(*e) {
return &es[i], true
}
return nil, false
}
func (es Entries) lookup(hostname string) Entries {
es.checkAndPanic()
+15
View File
@@ -86,6 +86,21 @@ func TestTombstone(t *testing.T) {
Entry{Hostname: "B", Version: 1, Tombstone: 1234},
})
require.Equal(t, expected, es)
// Now try a merge including two entries which differ only in tombstone
e2 := make(Entries, len(es))
copy(e2, es)
e2[1].Tombstone = 5555
diff := es.merge(e2)
expected2 := l(Entries{
Entry{Hostname: "A"},
Entry{Hostname: "B", Version: 1, Tombstone: 5555},
})
require.Equal(t, expected2, es)
expectedDiff := l(Entries{Entry{Hostname: "B", Version: 1, Tombstone: 5555}})
require.Equal(t, expectedDiff, diff)
}
func TestDelete(t *testing.T) {
+22 -2
View File
@@ -84,8 +84,8 @@ func (n *Nameserver) broadcastEntries(es ...Entry) error {
}
func (n *Nameserver) AddEntry(hostname, containerid string, origin mesh.PeerName, addr address.Address) error {
n.infof("adding entry %s -> %s", hostname, addr.String())
n.Lock()
n.infof("adding entry for %s: %s -> %s", containerid, hostname, addr.String())
entry := n.entries.add(hostname, containerid, origin, addr)
n.Unlock()
return n.broadcastEntries(entry)
@@ -203,11 +203,31 @@ func (n *Nameserver) receiveGossip(msg []byte) (mesh.GossipData, mesh.GossipData
return nil, nil, fmt.Errorf("clock skew of %d detected", delta)
}
// Filter to remove entries from unknown peers, done before we take
// the nameserver lock, so we don't have to worry what isKnownPeer locks.
gossip.Entries.filter(func(e *Entry) bool {
return n.isKnownPeer(e.Origin)
})
n.Lock()
defer n.Unlock()
// Check entries claiming to originate from us against our current data
gossip.Entries.filter(func(e *Entry) bool {
return n.isKnownPeer(e.Origin)
if e.Origin == n.ourName {
if ourEntry, ok := n.entries.findEqual(e); ok {
if ourEntry.Version < e.Version ||
(ourEntry.Version == e.Version && ourEntry.Tombstone != e.Tombstone) {
// Take our version of the data, but make the version higher than the incoming
nextVersion := e.Version + 1
*e = *ourEntry
e.Version = nextVersion
}
} else { // We have no entry matching the one that came in with us as Origin
e.tombstone()
}
}
return true
})
newEntries := n.entries.merge(gossip.Entries)
+11
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"net"
"github.com/docker/libnetwork/discoverapi"
"github.com/docker/libnetwork/ipamapi"
"github.com/docker/libnetwork/netlabel"
godocker "github.com/fsouza/go-dockerclient"
@@ -67,3 +68,13 @@ func (i *ipam) ReleaseAddress(poolID string, address net.IP) error {
Log.Debugln("ReleaseAddress", poolID, address)
return i.weave.ReleaseIP(address.String())
}
// Functions required by ipamapi "contract" but not actually used.
func (i *ipam) DiscoverNew(discoverapi.DiscoveryType, interface{}) error {
return nil
}
func (i *ipam) DiscoverDelete(discoverapi.DiscoveryType, interface{}) error {
return nil
}
+2 -1
View File
@@ -132,7 +132,8 @@ func (proxy *Proxy) AttachExistingContainers() {
}
continue
}
if containerShouldAttach(container) && (container.State.Running || container.State.Paused) {
// The 'Running' check is purely an optimisation.
if containerShouldAttach(container) && container.State.Running {
proxy.attach(container, false)
}
}
+8 -4
View File
@@ -775,10 +775,10 @@ func (fwd *fastDatapathForwarder) Forward(key ForwardPacketKey) FlowOp {
defer fwd.lock.RUnlock()
if fwd.remoteAddr == nil {
// Returning nil would discard the packet, but also
// result in a flow rule, which we would have to
// invalidate when we learn the remote IP. So for
// now, just prevent flows.
// Returning a DiscardingFlowOp would discard the
// packet, but also result in a flow rule, which we
// would have to invalidate when we learn the remote
// IP. So for now, just prevent flows.
return vetoFlowCreationFlowOp{}
}
@@ -1086,6 +1086,10 @@ func (fastdp *FastDatapath) send(fops FlowOp, frame []byte, lock *fastDatapathLo
case vetoFlowCreationFlowOp:
createFlow = false
default:
if xfop.Discards() {
continue
}
// A foreign FlowOp (e.g. a sleeve forwarding
// FlowOp), so send the packet through the
// FlowOp interface, decoding the packet
+1 -4
View File
@@ -84,15 +84,12 @@ func (mfop *MultiFlowOp) Discards() bool {
return true
}
// Flatten out a FlowOp to eliminate any MultiFlowOps
func FlattenFlowOp(fop FlowOp) []FlowOp {
return collectFlowOps(nil, fop)
}
func collectFlowOps(into []FlowOp, fop FlowOp) []FlowOp {
if fop == nil {
return into
}
if mfop, ok := fop.(*MultiFlowOp); ok {
for _, op := range mfop.ops {
into = collectFlowOps(into, op)
+9 -1
View File
@@ -87,7 +87,12 @@ launched via the Docker
[command-line interface](https://docs.docker.com/reference/commandline/cli/)
or
[remote API](https://docs.docker.com/reference/api/docker_remote_api/)
are attached to the weave network before they begin execution.
are attached to the weave network before they begin execution. To use
the proxy, run
$ eval $(weave env)
and then start containers as usual.
Containers started in this way that subsequently restart, either by an
explicit `docker restart` command or by Docker restart policy, are
@@ -100,6 +105,9 @@ named `weave` is created by `weave launch`, which you can use like this:
$ docker run --net=weave -ti ubuntu
> NB: The plugin is an *alternative* to the proxy, hence one should
> *not* run `eval $(weave env)` beforehand.
For more details see the [plugin documentation](plugin.html).
### <a name="addressing"></a>Address allocation
+19 -13
View File
@@ -48,17 +48,6 @@ time, you can give the number of peers like this:
host3$ weave launch --init-peer-count 3 $HOST2
The consensus mechanism used to determine a majority transitions
through three states: 'deferred', 'waiting' and 'achieved':
* 'deferred' - no allocation requests or claims have been made yet;
consensus is deferred until then
* 'waiting' - an attempt to achieve consensus is ongoing, triggered by
an allocation or claim request; allocations will block. This state
persists until a quorum of peers are able to communicate amongst
themselves successfully
* 'achieved' - consensus achieved; allocations proceed normally
### More on `--init-peer-count`
TL;DR: it isn't a problem to over-estimate by a bit, but if you supply
@@ -214,7 +203,7 @@ reports on the current status of the weave router and IP allocator:
...
Service: ipam
Consensus: waiting(quorum: 2, known: 0)
Status: awaiting consensus (quorum: 2, known: 0)
Range: 10.32.0.0-10.47.255.255
DefaultSubnet: 10.32.0.0/12
@@ -225,4 +214,21 @@ The first section covers the router; see the [troubleshooting
guide](troubleshooting.html#weave-status) for full details.
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. Columns are as follows:
* 'Status' - allocator state
* 'idle' - no allocation requests or claims have been made yet;
consensus is deferred until then
* 'awaiting consensus' - an attempt to achieve consensus is
ongoing, triggered by an allocation or claim request;
allocations will block. This state persists until a quorum of
peers are able to communicate amongst themselves successfully
* 'ready' - consensus achieved; allocations proceed normally
* 'waiting for IP range grant from peers' - peer has exhausted its
agreed portion of the range and is waiting to be granted some
more
* 'all IP ranges owned by unreachable peers' - peer has exhausted
its agreed portion of the range but cannot reach anyone to ask
for more
* 'Range' - total allocation range set by `--ipalloc-range`
* 'DefaultSubnet' - default subnet set by `--ipalloc-default-subnet`
+22 -2
View File
@@ -18,13 +18,33 @@ Subsequently you can start containers with, e.g.
on any of the hosts, and they can all communicate with each other.
> WARNING: It is inadvisable to attach containers to the weave network
> using both the Weave Docker Networking Plugin and
> [Weave Docker API Proxy](proxy.html) simultaneously. Such containers
> will end up with two weave network interfaces and two IP addresses,
> which is rarely desirable. To ensure the proxy is not being used,
> *do not run `eval $(weave env)`, or `docker $(weave config) ...`*.
In order to use Weave's [Service Discovery](weavedns.html), you
need to pass the additional arguments `--dns` and `-dns-search`, for
which we provide a helper in the weave script:
$ docker run --net=weave -h foo.weave.local $(weave dns-args) -tdi ubuntu
$ docker run --net=weave -h bar.weave.local $(weave dns-args) -ti ubuntu
# ping foo
Here is a complete example of using the plugin for connectivity
between two containers running on different hosts:
host1$ weave launch
host1$ docker run --net=weave -h foo.weave.local $(weave dns-args) -tdi ubuntu
host2$ weave launch $HOST1
host2$ docker run --net=weave $(weave dns-args) -ti ubuntu
root@cb73d1a8aece:/# ping -c1 -q foo
PING foo (10.32.0.1) 56(84) bytes of data.
--- foo ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.341/1.341/1.341/0.000 ms
## Under the hood
+8 -1
View File
@@ -62,7 +62,7 @@ $ weave status
TrustedSubnets: none
Service: ipam
Consensus: achieved
Status: ready
Range: 10.32.0.0-10.47.255.255
DefaultSubnet: 10.32.0.0/12
@@ -124,6 +124,13 @@ Proxy](proxy.html#troubleshooting).
### <a name="weave-status-connections"></a>List connections
Connections between weave peers carry control traffic over TCP and
data traffic over UDP. For a connection to be fully established, the
TCP connection and UDP data path must be able to transmit information
in both directions. Weave routers check this regularly with
heartbeats. Failed connections are automatically retried, with an
exponential back-off.
Detailed information on the local weave router's connections can be
obtained with `weave status connections`:
-1
View File
@@ -18,7 +18,6 @@ hosts.
* [Adding and removing extra DNS entries](#add-remove)
* [Resolve weaveDNS entries from host](#resolve-weavedns-entries-from-host)
* [Hot-swapping service containers](#hot-swapping)
* [Retaining DNS entries when containers stop](#retain-stopped)
* [Configuring a custom TTL](#ttl)
* [Configuring the domain search path](#domain-search-path)
* [Using a different local domain](#local-domain)
+31
View File
@@ -0,0 +1,31 @@
#! /bin/bash
. ./config.sh
start_suite "Check propagation of DNS entries when gossip is delayed"
weave_on $HOST1 launch-router --no-discovery
weave_on $HOST2 launch-router --no-discovery $HOST1
weave_on $HOST3 launch-router --no-discovery $HOST2
start_container $HOST1 --name=c1
C1=$(container_ip $HOST1 c1)
start_container_with_dns $HOST3 --name=c3
assert_dns_record $HOST3 c3 c1.weave.local $C1
# Stall the propagation of gossip, stop weave and kill the container
run_on $HOST3 "sudo iptables -A INPUT -s $HOST2 -j DROP"
weave_on $HOST1 stop-router
docker_on $HOST1 rm -f c1
weave_on $HOST1 launch-router --no-discovery $HOST3
# Now re-enable gossip
run_on $HOST3 "sudo iptables -D INPUT -s $HOST2 -j DROP"
# Currently failing due to Mesh #28
# assert_no_dns_record $HOST3 c3 c1.weave.local
end_suite
+2 -2
View File
@@ -34,8 +34,8 @@ assert_raises "proxy docker_on $HOST1 ps"
weave_on $HOST1 stop-proxy
# Booting it over tls errors
assert_raises "DOCKER_CLIENT_ARGS='--tls' weave_on $HOST1 launch-proxy" 1
assert_raises "DOCKER_CERT_PATH='./tls' DOCKER_TLS_VERIFY=1 weave_on $HOST1 launch-proxy" 1
assert_raises "! DOCKER_CLIENT_ARGS='--tls' weave_on $HOST1 launch-proxy"
assert_raises "! DOCKER_CERT_PATH='./tls' DOCKER_TLS_VERIFY=1 weave_on $HOST1 launch-proxy"
# Booting it with a specific -H overrides defaults
weave_on $HOST1 launch-proxy -H tcp://0.0.0.0:12345
+1 -1
View File
@@ -6,7 +6,7 @@ start_suite "Proxy failure modes"
# docker run should fail when weave router is not running
weave_on $HOST1 launch-proxy
assert_raises "proxy docker_on $HOST1 run --rm $SMALL_IMAGE true" 1
assert_raises "! proxy docker_on $HOST1 run --rm $SMALL_IMAGE true"
assert_raises "proxy docker_on $HOST1 run --rm $SMALL_IMAGE true 2>&1 1>/dev/null | grep 'Error response from daemon: weave container is not present. Have you launched it?'"
end_suite
+1 -1
View File
@@ -11,7 +11,7 @@ set -e
: ${SSH_KEY_FILE:=$HOME/.ssh/gce_ssh_key}
: ${PROJECT:=positive-cocoa-90213}
: ${IMAGE:=ubuntu-14-04}
: ${TEMPLATE_NAME:=test-template-9}
: ${TEMPLATE_NAME:=test-template-10}
: ${ZONE:=us-central1-a}
: ${NUM_HOSTS:=5}
SUFFIX=""
+3 -1
View File
@@ -536,7 +536,9 @@ create_bridge() {
add_iptables_rule nat POSTROUTING -j WEAVE
else
if [ -n "$LAUNCHING_ROUTER" ] ; then
if [ "$BRIDGE_TYPE" = bridge -a -z "$WEAVE_NO_FASTDP" ] ; then
if [ "$BRIDGE_TYPE" = bridge -a -z "$WEAVE_NO_FASTDP" ] &&
util_op create-datapath $DATAPATH 2>/dev/null &&
util_op delete-datapath $DATAPATH 2>/dev/null ; then
cat <<EOF >&1
WEAVE_NO_FASTDP is not set, but there is already a bridge present of
the wrong type for fast datapath. Please do 'weave reset' to remove