Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebfaf11f4a | ||
|
|
1abce148a3 | ||
|
|
264e5c9979 | ||
|
|
a6a1ce5c9e | ||
|
|
5e660311d2 | ||
|
|
4a49ff3083 | ||
|
|
7f92c8c4c6 | ||
|
|
85ac8177ad | ||
|
|
eb5b16614c | ||
|
|
e48ca80dee | ||
|
|
e7c9e22350 | ||
|
|
b8e7d83f19 | ||
|
|
4c304c0013 | ||
|
|
7249350757 | ||
|
|
50a8dc1383 | ||
|
|
71491138aa | ||
|
|
ca87f8ada3 | ||
|
|
835b3f3d67 | ||
|
|
263dffeedc | ||
|
|
e1063944f6 | ||
|
|
2380018457 | ||
|
|
a9db631836 | ||
|
|
b45f138ff1 | ||
|
|
b239694d34 | ||
|
|
0c2774f367 | ||
|
|
ea4647bc74 | ||
|
|
6ec21d3a58 | ||
|
|
44a4a56024 | ||
|
|
2ea027d3a8 | ||
|
|
69b688b357 | ||
|
|
cdeae04238 | ||
|
|
a556deec78 | ||
|
|
06a63db4cf | ||
|
|
06a325a05f | ||
|
|
68e9bbe350 | ||
|
|
3bd9e369cd | ||
|
|
57357a728c | ||
|
|
e263295720 | ||
|
|
0c854f2144 | ||
|
|
bdf4debdfd | ||
|
|
f557835ad0 | ||
|
|
17a7391086 | ||
|
|
e65293eb50 | ||
|
|
caa6c6c931 | ||
|
|
2e825242cd | ||
|
|
027064cbdb | ||
|
|
060f6392c7 | ||
|
|
a466f55d59 | ||
|
|
f686408808 | ||
|
|
b8c57ef10f | ||
|
|
5cc0826ca0 | ||
|
|
e703f2f3f2 | ||
|
|
f544da9e19 | ||
|
|
472eab2acd | ||
|
|
7a5d7fca6c | ||
|
|
589b45dace | ||
|
|
3273d13666 | ||
|
|
5fdbbf3722 | ||
|
|
14350ff463 | ||
|
|
0b49c961a7 | ||
|
|
39b80f26ed | ||
|
|
74b20265e4 | ||
|
|
358fddb958 | ||
|
|
5c8f6175b5 | ||
|
|
83ce5875ee | ||
|
|
f5a30c790e | ||
|
|
34415c3c17 | ||
|
|
6387fa8bc9 | ||
|
|
8ec6b699b1 | ||
|
|
551f164ec3 | ||
|
|
88bf64722f | ||
|
|
d9c998b5c4 | ||
|
|
170e19c283 | ||
|
|
7c47a8ffb7 | ||
|
|
791ab55875 | ||
|
|
bd1a9d020c | ||
|
|
71fd3b6b2b | ||
|
|
f8ac27a6cc | ||
|
|
954cd0b86a | ||
|
|
9dedeadf15 | ||
|
|
6561272f8d | ||
|
|
881e795db5 | ||
|
|
4216231ec7 | ||
|
|
333d5f7511 | ||
|
|
7be7945b29 | ||
|
|
afe882cd94 | ||
|
|
5b8a359475 | ||
|
|
df0af203f8 | ||
|
|
5b2a4ff614 | ||
|
|
ceb5f8c714 | ||
|
|
cc3359dfe5 | ||
|
|
cda6785f1d | ||
|
|
cb030be4ad | ||
|
|
b464ce86f7 | ||
|
|
80b3514e24 | ||
|
|
e33f56f9b0 | ||
|
|
f386548890 | ||
|
|
c80d87554a |
No files matched your search
@@ -76,3 +76,9 @@
|
|||||||
[submodule "vendor/github.com/aws/aws-sdk-go"]
|
[submodule "vendor/github.com/aws/aws-sdk-go"]
|
||||||
path = vendor/github.com/aws/aws-sdk-go
|
path = vendor/github.com/aws/aws-sdk-go
|
||||||
url = https://github.com/aws/aws-sdk-go
|
url = https://github.com/aws/aws-sdk-go
|
||||||
|
[submodule "vendor/golang.org/x/sys"]
|
||||||
|
path = vendor/golang.org/x/sys
|
||||||
|
url = https://go.googlesource.com/sys
|
||||||
|
[submodule "vendor/github.com/weaveworks/docker"]
|
||||||
|
path = vendor/github.com/weaveworks/docker
|
||||||
|
url = https://github.com/weaveworks/docker
|
||||||
@@ -1,3 +1,30 @@
|
|||||||
|
## Release 1.7.2
|
||||||
|
|
||||||
|
Bug fixes and minor improvements
|
||||||
|
|
||||||
|
* Fixed an error where the Docker plugin could fail to attach a
|
||||||
|
container with a `bridge "weave" not present` error #2540/#2541
|
||||||
|
* Fixed `cannot connect to itself` panic on weave launch #2527/#2543
|
||||||
|
* Fixed inferred initial peer count when target peers includes self
|
||||||
|
#2481/#2543
|
||||||
|
* Fixed compilation on Raspberry Pi #2506/#2538
|
||||||
|
|
||||||
|
## Release 1.7.1
|
||||||
|
|
||||||
|
Bug fixes and minor improvements
|
||||||
|
|
||||||
|
* Added utility to recover container addresses without asking Docker #2531
|
||||||
|
* Improved CI #2274
|
||||||
|
|
||||||
|
## Release 1.7.0
|
||||||
|
|
||||||
|
Highlights:
|
||||||
|
|
||||||
|
* weave-kube - Deploy Weave Net to Kubernetes with a single command
|
||||||
|
* weave-npc - Kubernetes network policy controller implementation
|
||||||
|
|
||||||
|
More details in the [change log](https://github.com/weaveworks/weave/issues?q=milestone%3A1.7.0).
|
||||||
|
|
||||||
## Release 1.6.2
|
## Release 1.6.2
|
||||||
|
|
||||||
Bug fixes and minor improvements
|
Bug fixes and minor improvements
|
||||||
|
|||||||
Executable
+43
@@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# We need jq to analyse the PR files JSON, so install that first
|
||||||
|
sudo apt-get -q update && sudo apt-get -q install bc jq
|
||||||
|
|
||||||
|
echo "TEST_AND_PUBLISH=1" > "$STATE"
|
||||||
|
|
||||||
|
if [ -n "$CI_PULL_REQUEST" -a "$CI_PULL_REQUEST" = "$CI_PULL_REQUESTS" ] ; then
|
||||||
|
if PR=$(echo "$CI_PULL_REQUEST" | grep -oP '(?<=^https://github.com/weaveworks/weave/pull/)[0-9]+$') ; then
|
||||||
|
echo "GH_PR=$PR" >> "$STATE"
|
||||||
|
if FILES=$(curl -s https://api.github.com/repos/weaveworks/weave/pulls/$PR/files | jq -r '.[]|.filename') ; then
|
||||||
|
echo "PR touches [$FILES]"
|
||||||
|
if ! echo "$FILES" | grep -v ^site/ ; then
|
||||||
|
echo "PR contains site changes only - skipping tests"
|
||||||
|
echo "TEST_AND_PUBLISH=" >> "$STATE"
|
||||||
|
else
|
||||||
|
echo "PR contains non-site changes - running tests"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Unable to get files for PR $PR" >&2
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Unable to extract PR number from $CI_PULL_REQUEST" >&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
source "$STATE"
|
||||||
|
|
||||||
|
mkdir -p $(dirname $SRCDIR) && cp -r $(pwd)/ $SRCDIR
|
||||||
|
|
||||||
|
if [ -n "$TEST_AND_PUBLISH" ] ; then
|
||||||
|
bin/setup-circleci-secrets "$SECRET_PASSWORD"
|
||||||
|
cd $SRCDIR; git submodule update --init
|
||||||
|
if [ "$CIRCLE_NODE_INDEX" = "0" ] ; then
|
||||||
|
cd $SRCDIR/test; ./gce.sh make_template
|
||||||
|
fi
|
||||||
|
cd $SRCDIR/build
|
||||||
|
../tools/rebuild-image weaveworks/weavebuild . Dockerfile build.sh
|
||||||
|
touch $SRCDIR/.build.uptodate
|
||||||
|
sudo chown -R ubuntu /usr/local/go
|
||||||
|
fi
|
||||||
Executable
+43
@@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
source "$STATE"
|
||||||
|
|
||||||
|
site_changes() {
|
||||||
|
curl -s https://api.github.com/repos/weaveworks/weave/pulls/$1/files |
|
||||||
|
jq -r '.[]|.status + " " + .filename' |
|
||||||
|
grep -oP '^(added|modified|removed) site/.*(?=\.md$)'
|
||||||
|
}
|
||||||
|
|
||||||
|
format_comment() {
|
||||||
|
if [ ! -d .git ] || ! BRANCH=$(git symbolic-ref --short HEAD) || [ -z "$BRANCH" ] ; then
|
||||||
|
echo "Could not determine branch" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "#### Documentation changes:"
|
||||||
|
while read ACTION PAGE; do
|
||||||
|
echo "$ACTION [${PAGE#site/}]($WP_DEV_URL/docs/net/${BRANCH#issues/}/${PAGE#site/}/)"
|
||||||
|
done | sort
|
||||||
|
}
|
||||||
|
|
||||||
|
post_comment() {
|
||||||
|
jq -s -R '. | tostring | { body: . }' |
|
||||||
|
curl -s -d @- \
|
||||||
|
-H "Authorization: Bearer $WP_GH_COMMENT_TOKEN" \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
https://api.github.com/repos/weaveworks/weave/issues/$GH_PR/comments > /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
cd $SRCDIR
|
||||||
|
bin/install-wordepress v1.0.0
|
||||||
|
bin/publish-site "$WP_DEV_URL" "$WP_DEV_USER" "$WP_DEV_PASSWORD"
|
||||||
|
|
||||||
|
if [ -n "$WP_GH_COMMENT_TOKEN" -a -n "$GH_PR" ] ; then
|
||||||
|
echo ">>> Adding doc changelog to GitHub PR $GH_PR"
|
||||||
|
if CHANGES=$(site_changes $GH_PR) && [ -n "$CHANGES" ] ; then
|
||||||
|
echo "$CHANGES" | format_comment | post_comment
|
||||||
|
fi
|
||||||
|
fi
|
||||||
Executable
+16
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
source "$STATE"
|
||||||
|
|
||||||
|
if [ -n "$TEST_AND_PUBLISH" ] ; then
|
||||||
|
docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
|
||||||
|
cd $SRCDIR
|
||||||
|
make clean-bin
|
||||||
|
make publish
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $SRCDIR
|
||||||
|
bin/install-wordepress v1.0.0
|
||||||
|
bin/publish-site "$WP_DEV_URL" "$WP_DEV_USER" "$WP_DEV_PASSWORD"
|
||||||
Executable
+7
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cd $SRCDIR
|
||||||
|
bin/install-wordepress v1.0.0
|
||||||
|
bin/publish-site "$WP_LIVE_URL" "$WP_LIVE_USER" "$WP_LIVE_PASSWORD"
|
||||||
Executable
+13
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
source "$STATE"
|
||||||
|
|
||||||
|
if [ -n "$TEST_AND_PUBLISH" ] ; then
|
||||||
|
if [ "$CIRCLE_NODE_INDEX" = "0" ] ; then
|
||||||
|
go get github.com/mattn/goveralls
|
||||||
|
goveralls -repotoken $COVERALLS_REPO_TOKEN -coverprofile=$SRCDIR/test/profile.cov -service=circleci
|
||||||
|
cd $SRCDIR/test; cp coverage.* $CIRCLE_ARTIFACTS
|
||||||
|
fi
|
||||||
|
fi
|
||||||
Executable
+14
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
source "$STATE"
|
||||||
|
|
||||||
|
if [ -n "$TEST_AND_PUBLISH" ] ; then
|
||||||
|
cd $SRCDIR
|
||||||
|
make testrunner
|
||||||
|
make COVERAGE=true RM= all
|
||||||
|
|
||||||
|
cd $SRCDIR/test
|
||||||
|
./gce.sh setup && eval $(./gce.sh hosts) && ./setup.sh
|
||||||
|
fi
|
||||||
Executable
+12
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
source "$STATE"
|
||||||
|
|
||||||
|
if [ -n "$TEST_AND_PUBLISH" ] ; then
|
||||||
|
cd $SRCDIR/test
|
||||||
|
eval $(./gce.sh hosts)
|
||||||
|
export COVERAGE=true
|
||||||
|
./run_all.sh
|
||||||
|
fi
|
||||||
Executable
+11
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
source "$STATE"
|
||||||
|
|
||||||
|
if [ -n "$TEST_AND_PUBLISH" ] ; then
|
||||||
|
cd $SRCDIR/test
|
||||||
|
./gce.sh destroy
|
||||||
|
test "$CIRCLE_NODE_INDEX" != "0" || (cd $SRCDIR/test; ./gen_coverage_reports.sh)
|
||||||
|
fi
|
||||||
Executable
+11
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
source "$STATE"
|
||||||
|
|
||||||
|
if [ -n "$TEST_AND_PUBLISH" ] ; then
|
||||||
|
cd $SRCDIR
|
||||||
|
make lint
|
||||||
|
COVERDIR=test/coverage make RM= tests
|
||||||
|
fi
|
||||||
Executable
+12
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ $# -ne 1 ] ; then
|
||||||
|
echo USAGE: install-wordepress [COMMIT-ISH] >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
go get github.com/weaveworks/wordepress
|
||||||
|
cd /home/ubuntu/src/github.com/weaveworks/wordepress
|
||||||
|
git checkout $1
|
||||||
|
cd cmd/wordepress
|
||||||
|
go get
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
FROM golang:1.5.2
|
FROM golang:1.5.2
|
||||||
ENV GO15VENDOREXPERIMENT 1
|
ENV GO15VENDOREXPERIMENT 1
|
||||||
RUN apt-get update && apt-get install -y libpcap-dev python-requests time file
|
RUN apt-get update && apt-get install -y libpcap-dev python-requests time file
|
||||||
RUN go get github.com/golang/lint/golint github.com/fzipp/gocyclo github.com/client9/misspell/cmd/misspell
|
RUN go get github.com/fzipp/gocyclo github.com/client9/misspell/cmd/misspell
|
||||||
RUN go clean -i net && go install -tags netgo std
|
RUN go clean -i net && go install -tags netgo std
|
||||||
RUN go install -race -tags netgo std
|
RUN go install -race -tags netgo std
|
||||||
COPY build.sh /
|
COPY build.sh /
|
||||||
|
|||||||
+17
-38
@@ -12,46 +12,31 @@ machine:
|
|||||||
SRCDIR: /home/ubuntu/src/github.com/weaveworks/weave
|
SRCDIR: /home/ubuntu/src/github.com/weaveworks/weave
|
||||||
PATH: $PATH:$HOME/.local/bin
|
PATH: $PATH:$HOME/.local/bin
|
||||||
CLOUDSDK_CORE_DISABLE_PROMPTS: 1
|
CLOUDSDK_CORE_DISABLE_PROMPTS: 1
|
||||||
|
STATE: /home/ubuntu/state.env
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
cache_directories:
|
cache_directories:
|
||||||
- "~/docker"
|
- "~/docker"
|
||||||
post:
|
post:
|
||||||
- "sudo apt-get update && sudo apt-get install bc jq"
|
- bin/circle-dependencies-post
|
||||||
- bin/setup-circleci-secrets "$SECRET_PASSWORD"
|
|
||||||
- "mkdir -p $(dirname $SRCDIR) && cp -r $(pwd)/ $SRCDIR"
|
|
||||||
- "cd $SRCDIR; git submodule update --init"
|
|
||||||
- cd $SRCDIR/test; ./gce.sh make_template:
|
|
||||||
parallel: false
|
|
||||||
- "cd $SRCDIR/build; ../tools/rebuild-image weaveworks/weavebuild . Dockerfile build.sh && touch $SRCDIR/.build.uptodate"
|
|
||||||
- "sudo chown -R ubuntu /usr/local/go"
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
pre:
|
||||||
|
- "$SRCDIR/bin/circle-test-pre":
|
||||||
|
parallel: true
|
||||||
override:
|
override:
|
||||||
- cd $SRCDIR; make lint:
|
- "$SRCDIR/bin/circle-test-unit":
|
||||||
parallel: true
|
parallel: true
|
||||||
- cd $SRCDIR; COVERDIR=test/coverage make RM= tests:
|
- "$SRCDIR/bin/circle-test-smoke":
|
||||||
parallel: true
|
|
||||||
- cd $SRCDIR; make COVERAGE=true RM= exes all:
|
|
||||||
parallel: true
|
|
||||||
- cd $SRCDIR; make testrunner:
|
|
||||||
parallel: true
|
|
||||||
- cd $SRCDIR/test; ./gce.sh setup && eval $(./gce.sh hosts) && ./setup.sh:
|
|
||||||
parallel: true
|
|
||||||
- cd $SRCDIR/test; eval $(./gce.sh hosts); export COVERAGE=true; ./run_all.sh:
|
|
||||||
parallel: true
|
parallel: true
|
||||||
timeout: 300
|
timeout: 300
|
||||||
post:
|
post:
|
||||||
- cd $SRCDIR/test; ./gce.sh destroy:
|
- "$SRCDIR/bin/circle-test-teardown":
|
||||||
parallel: true
|
|
||||||
- test "$CIRCLE_NODE_INDEX" != "0" || (cd $SRCDIR/test; ./gen_coverage_reports.sh):
|
|
||||||
parallel: true
|
parallel: true
|
||||||
|
|
||||||
teardown:
|
teardown:
|
||||||
pre:
|
pre:
|
||||||
- test "$CIRCLE_NODE_INDEX" != "0" || (go get github.com/mattn/goveralls && goveralls -repotoken $COVERALLS_REPO_TOKEN -coverprofile=$SRCDIR/test/profile.cov -service=circleci || true):
|
- "$SRCDIR/bin/circle-teardown-pre":
|
||||||
parallel: true
|
|
||||||
- test "$CIRCLE_NODE_INDEX" != "0" || (cd $SRCDIR/test; cp coverage.* $CIRCLE_ARTIFACTS):
|
|
||||||
parallel: true
|
parallel: true
|
||||||
|
|
||||||
deployment:
|
deployment:
|
||||||
@@ -59,20 +44,14 @@ deployment:
|
|||||||
branch: /[0-9]+\.[0-9]+/
|
branch: /[0-9]+\.[0-9]+/
|
||||||
owner: weaveworks
|
owner: weaveworks
|
||||||
commands:
|
commands:
|
||||||
- go get github.com/weaveworks/wordepress && cd /home/ubuntu/src/github.com/weaveworks/wordepress && git checkout v1.0.0 && cd cmd/wordepress && go get
|
- "$SRCDIR/bin/circle-deploy-release"
|
||||||
- cd $SRCDIR; bin/publish-site "$WP_LIVE_URL" "$WP_LIVE_USER" "$WP_LIVE_PASSWORD"
|
master:
|
||||||
hub:
|
|
||||||
branch: master
|
branch: master
|
||||||
owner: weaveworks
|
owner: weaveworks
|
||||||
commands:
|
commands:
|
||||||
- docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
|
- "$SRCDIR/bin/circle-deploy-master"
|
||||||
- cd $SRCDIR; make clean-bin
|
issues:
|
||||||
- cd $SRCDIR; make exes publish
|
branch: /.*/
|
||||||
# - go get github.com/weaveworks/wordepress && cd /home/ubuntu/src/github.com/weaveworks/wordepress && git checkout v1.0.0 && cd cmd/wordepress && go get
|
owner: weaveworks
|
||||||
# - cd $SRCDIR; bin/publish-site "$WP_DEV_URL" "$WP_DEV_USER" "$WP_DEV_PASSWORD"
|
commands:
|
||||||
# issues:
|
- "$SRCDIR/bin/circle-deploy-issues"
|
||||||
# branch: /.*/
|
|
||||||
# owner: weaveworks
|
|
||||||
# commands:
|
|
||||||
# - go get github.com/weaveworks/wordepress && cd /home/ubuntu/src/github.com/weaveworks/wordepress && git checkout v1.0.0 && cd cmd/wordepress && go get
|
|
||||||
# - cd $SRCDIR; bin/publish-site "$WP_DEV_URL" "$WP_DEV_USER" "$WP_DEV_PASSWORD"
|
|
||||||
@@ -3,7 +3,7 @@ package mflagext
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/mflag"
|
"github.com/weaveworks/docker/pkg/mflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
type listOpts struct {
|
type listOpts struct {
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AllPids(procRoot string) ([]int, error) {
|
||||||
|
fh, err := os.Open(procRoot)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer fh.Close()
|
||||||
|
dirNames, err := fh.Readdirnames(-1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pids := make([]int, len(dirNames))
|
||||||
|
for _, dirName := range dirNames {
|
||||||
|
pid, err := strconv.Atoi(dirName)
|
||||||
|
if err != nil { // Only interested in numeric entries - skip /proc/stat, etc.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pids = append(pids, pid)
|
||||||
|
}
|
||||||
|
return pids, err
|
||||||
|
}
|
||||||
+2
-19
@@ -6,7 +6,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/j-keck/arping"
|
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
"github.com/vishvananda/netns"
|
"github.com/vishvananda/netns"
|
||||||
|
|
||||||
@@ -125,7 +124,7 @@ func ConnectedToBridgePredicate(bridgeName string) (func(link netlink.Link) bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetNetDevsWithPredicate(processID int, predicate func(link netlink.Link) bool) ([]NetDev, error) {
|
func GetNetDevsWithPredicate(processID int, predicate func(link netlink.Link) bool) ([]NetDev, error) {
|
||||||
// Bail out if this container is running in the root namespace
|
// Bail out if this process is running in the root namespace
|
||||||
nsToplevel, err := netns.GetFromPid(1)
|
nsToplevel, err := netns.GetFromPid(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to open root namespace: %s", err)
|
return nil, fmt.Errorf("unable to open root namespace: %s", err)
|
||||||
@@ -133,6 +132,7 @@ func GetNetDevsWithPredicate(processID int, predicate func(link netlink.Link) bo
|
|||||||
defer nsToplevel.Close()
|
defer nsToplevel.Close()
|
||||||
nsContainr, err := netns.GetFromPid(processID)
|
nsContainr, err := netns.GetFromPid(processID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// Unable to find a namespace for this process - just return nothing
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -166,20 +166,3 @@ func GetBridgeNetDev(bridgeName string) (NetDev, error) {
|
|||||||
|
|
||||||
return linkToNetDev(link)
|
return linkToNetDev(link)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do post-attach configuration of all veths we have created
|
|
||||||
func ConfigureARPforVeths(processID int, prefix string) error {
|
|
||||||
_, err := FindNetDevs(processID, func(link netlink.Link) bool {
|
|
||||||
ifName := link.Attrs().Name
|
|
||||||
if strings.HasPrefix(ifName, prefix) {
|
|
||||||
weavenet.ConfigureARPCache(ifName)
|
|
||||||
if addrs, err := netlink.AddrList(link, netlink.FAMILY_V4); err == nil {
|
|
||||||
for _, addr := range addrs {
|
|
||||||
arping.GratuitousArpOverIfaceByName(addr.IPNet.IP, ifName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
+13
-6
@@ -28,7 +28,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Upstream interface {
|
type Upstream interface {
|
||||||
Config() *dns.ClientConfig
|
Config() (*dns.ClientConfig, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUpstream(resolvConf, filterAddress string) Upstream {
|
func NewUpstream(resolvConf, filterAddress string) Upstream {
|
||||||
@@ -48,27 +48,31 @@ type upstream struct {
|
|||||||
lastModified time.Time
|
lastModified time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *upstream) Config() *dns.ClientConfig {
|
func (u *upstream) Config() (*dns.ClientConfig, error) {
|
||||||
u.Lock()
|
u.Lock()
|
||||||
defer u.Unlock()
|
defer u.Unlock()
|
||||||
|
|
||||||
// If we checked less than five seconds ago return what we already have
|
// If we checked less than five seconds ago return what we already have
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
if now.Sub(u.lastStat) < 5*time.Second {
|
if now.Sub(u.lastStat) < 5*time.Second {
|
||||||
return u.cachedConfig
|
return u.cachedConfig, nil
|
||||||
}
|
}
|
||||||
u.lastStat = now
|
u.lastStat = now
|
||||||
|
|
||||||
// Reread file if it has changed
|
// Reread file if it has changed
|
||||||
if fi, err := os.Stat(u.resolvConf); err == nil && fi.ModTime() != u.lastModified {
|
if fi, err := os.Stat(u.resolvConf); err != nil {
|
||||||
|
return u.cachedConfig, err
|
||||||
|
} else if fi.ModTime() != u.lastModified {
|
||||||
if config, err := dns.ClientConfigFromFile(u.resolvConf); err == nil {
|
if config, err := dns.ClientConfigFromFile(u.resolvConf); err == nil {
|
||||||
config.Servers = filter(config.Servers, u.filterAddress)
|
config.Servers = filter(config.Servers, u.filterAddress)
|
||||||
u.lastModified = fi.ModTime()
|
u.lastModified = fi.ModTime()
|
||||||
u.cachedConfig = config
|
u.cachedConfig = config
|
||||||
|
} else {
|
||||||
|
return u.cachedConfig, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return u.cachedConfig
|
return u.cachedConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func filter(ss []string, s string) []string {
|
func filter(ss []string, s string) []string {
|
||||||
@@ -257,7 +261,10 @@ func (h *handler) handleRecursive(w dns.ResponseWriter, req *dns.Msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
upstreamConfig := h.upstream.Config()
|
upstreamConfig, err := h.upstream.Config()
|
||||||
|
if err != nil {
|
||||||
|
h.ns.errorf("unable to read upstream config: %s", err)
|
||||||
|
}
|
||||||
for _, server := range upstreamConfig.Servers {
|
for _, server := range upstreamConfig.Servers {
|
||||||
reqCopy := req.Copy()
|
reqCopy := req.Copy()
|
||||||
reqCopy.Id = dns.Id()
|
reqCopy.Id = dns.Id()
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ type mockUpstream struct {
|
|||||||
config *dns.ClientConfig
|
config *dns.ClientConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mu *mockUpstream) Config() *dns.ClientConfig {
|
func (mu *mockUpstream) Config() (*dns.ClientConfig, error) {
|
||||||
return mu.config
|
return mu.config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startServer(t *testing.T, upstream *dns.ClientConfig) (*DNSServer, *Nameserver, int, int) {
|
func startServer(t *testing.T, upstream *dns.ClientConfig) (*DNSServer, *Nameserver, int, int) {
|
||||||
|
|||||||
@@ -36,9 +36,10 @@ func NewStatus(ns *Nameserver, dnsServer *DNSServer) *Status {
|
|||||||
entry.Tombstone})
|
entry.Tombstone})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
upstreamConfig, _ := dnsServer.upstream.Config()
|
||||||
return &Status{
|
return &Status{
|
||||||
dnsServer.domain,
|
dnsServer.domain,
|
||||||
dnsServer.upstream.Config().Servers,
|
upstreamConfig.Servers,
|
||||||
dnsServer.address,
|
dnsServer.address,
|
||||||
dnsServer.ttl,
|
dnsServer.ttl,
|
||||||
entryStatusSlice}
|
entryStatusSlice}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package net
|
package net
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
@@ -63,3 +66,27 @@ func WithNetNSLinkByPidUnsafe(pid int, ifName string, work func(link netlink.Lin
|
|||||||
|
|
||||||
return WithNetNSLinkUnsafe(ns, ifName, work)
|
return WithNetNSLinkUnsafe(ns, ifName, work)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A safe version of WithNetNS* which creates a process executing
|
||||||
|
// "nsenter --net=<ns-path> weaveutil <cmd> [args]".
|
||||||
|
func WithNetNS(nsPath string, cmd string, args ...string) (string, error) {
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
|
||||||
|
args = append([]string{"--net=" + nsPath, "weaveutil", cmd}, args...)
|
||||||
|
c := exec.Command("nsenter", args...)
|
||||||
|
c.Stdout = &stdout
|
||||||
|
c.Stderr = &stderr
|
||||||
|
if err := c.Run(); err != nil {
|
||||||
|
return "", fmt.Errorf("%s: %s", string(stderr.Bytes()), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(stdout.Bytes()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithNetNSByPid(pid int, cmd string, args ...string) (string, error) {
|
||||||
|
return WithNetNS(NSPathByPid(pid), cmd, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NSPathByPid(pid int) string {
|
||||||
|
return fmt.Sprintf("/proc/%d/ns/net", pid)
|
||||||
|
}
|
||||||
+67
@@ -3,8 +3,10 @@ package net
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/coreos/go-iptables/iptables"
|
||||||
"github.com/j-keck/arping"
|
"github.com/j-keck/arping"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
"github.com/vishvananda/netns"
|
"github.com/vishvananda/netns"
|
||||||
@@ -112,6 +114,11 @@ func interfaceExistsInNamespace(ns netns.NsHandle, ifName string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func AttachContainer(ns netns.NsHandle, id, ifName, bridgeName string, mtu int, withMulticastRoute bool, cidrs []*net.IPNet, keepTXOn bool) error {
|
func AttachContainer(ns netns.NsHandle, id, ifName, bridgeName string, mtu int, withMulticastRoute bool, cidrs []*net.IPNet, keepTXOn bool) error {
|
||||||
|
ipt, err := iptables.New()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if !interfaceExistsInNamespace(ns, ifName) {
|
if !interfaceExistsInNamespace(ns, ifName) {
|
||||||
maxIDLen := IFNAMSIZ - 1 - len(vethPrefix+"pl")
|
maxIDLen := IFNAMSIZ - 1 - len(vethPrefix+"pl")
|
||||||
if len(id) > maxIDLen {
|
if len(id) > maxIDLen {
|
||||||
@@ -129,6 +136,9 @@ func AttachContainer(ns netns.NsHandle, id, ifName, bridgeName string, mtu int,
|
|||||||
if err := ConfigureARPCache(ifName); err != nil {
|
if err := ConfigureARPCache(ifName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := ipt.Append("filter", "INPUT", "-i", ifName, "-d", "224.0.0.0/4", "-j", "DROP"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("error setting up interface: %s", err)
|
return fmt.Errorf("error setting up interface: %s", err)
|
||||||
@@ -145,6 +155,21 @@ func AttachContainer(ns netns.NsHandle, id, ifName, bridgeName string, mtu int,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add multicast ACCEPT rules for new subnets
|
||||||
|
for _, ipnet := range newAddresses {
|
||||||
|
acceptRule := []string{"-i", ifName, "-s", subnet(ipnet), "-d", "224.0.0.0/4", "-j", "ACCEPT"}
|
||||||
|
exists, err := ipt.Exists("filter", "INPUT", acceptRule...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
if err := ipt.Insert("filter", "INPUT", 1, acceptRule...); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := netlink.LinkSetUp(veth); err != nil {
|
if err := netlink.LinkSetUp(veth); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -177,6 +202,11 @@ func AttachContainer(ns netns.NsHandle, id, ifName, bridgeName string, mtu int,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func DetachContainer(ns netns.NsHandle, id, ifName string, cidrs []*net.IPNet) error {
|
func DetachContainer(ns netns.NsHandle, id, ifName string, cidrs []*net.IPNet) error {
|
||||||
|
ipt, err := iptables.New()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return WithNetNSLinkUnsafe(ns, ifName, func(veth netlink.Link) error {
|
return WithNetNSLinkUnsafe(ns, ifName, func(veth netlink.Link) error {
|
||||||
existingAddrs, err := netlink.AddrList(veth, netlink.FAMILY_V4)
|
existingAddrs, err := netlink.AddrList(veth, netlink.FAMILY_V4)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -194,7 +224,31 @@ func DetachContainer(ns netns.NsHandle, id, ifName string, cidrs []*net.IPNet) e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get IP address for %q: %v", veth.Attrs().Name, err)
|
return fmt.Errorf("failed to get IP address for %q: %v", veth.Attrs().Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove multicast ACCEPT rules for subnets we no longer have addresses in
|
||||||
|
subnets := subnets(addrs)
|
||||||
|
rules, err := ipt.List("filter", "INPUT")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, rule := range rules {
|
||||||
|
ps := strings.Split(rule, " ")
|
||||||
|
if len(ps) == 10 &&
|
||||||
|
ps[0] == "-A" && ps[2] == "-s" && ps[4] == "-d" && ps[5] == "224.0.0.0/4" &&
|
||||||
|
ps[6] == "-i" && ps[7] == ifName && ps[8] == "-j" && ps[9] == "ACCEPT" {
|
||||||
|
|
||||||
|
if _, found := subnets[ps[3]]; !found {
|
||||||
|
if err := ipt.Delete("filter", "INPUT", ps[2:]...); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(addrs) == 0 { // all addresses gone: remove the interface
|
if len(addrs) == 0 { // all addresses gone: remove the interface
|
||||||
|
if err := ipt.Delete("filter", "INPUT", "-i", ifName, "-d", "224.0.0.0/4", "-j", "DROP"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := netlink.LinkDel(veth); err != nil {
|
if err := netlink.LinkDel(veth); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -202,3 +256,16 @@ func DetachContainer(ns netns.NsHandle, id, ifName string, cidrs []*net.IPNet) e
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func subnet(ipn *net.IPNet) string {
|
||||||
|
ones, _ := ipn.Mask.Size()
|
||||||
|
return fmt.Sprintf("%s/%d", ipn.IP.Mask(ipn.Mask).String(), ones)
|
||||||
|
}
|
||||||
|
|
||||||
|
func subnets(addrs []netlink.Addr) map[string]struct{} {
|
||||||
|
subnets := make(map[string]struct{})
|
||||||
|
for _, addr := range addrs {
|
||||||
|
subnets[subnet(addr.IPNet)] = struct{}{}
|
||||||
|
}
|
||||||
|
return subnets
|
||||||
|
}
|
||||||
+26
-13
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/docker/libnetwork/drivers/remote/api"
|
"github.com/docker/libnetwork/drivers/remote/api"
|
||||||
"github.com/docker/libnetwork/netlabel"
|
"github.com/docker/libnetwork/netlabel"
|
||||||
"github.com/docker/libnetwork/types"
|
"github.com/docker/libnetwork/types"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
weaveapi "github.com/weaveworks/weave/api"
|
weaveapi "github.com/weaveworks/weave/api"
|
||||||
@@ -94,11 +95,21 @@ func (driver *driver) DeleteNetwork(delreq *api.DeleteNetworkRequest) error {
|
|||||||
|
|
||||||
func (driver *driver) CreateEndpoint(create *api.CreateEndpointRequest) (*api.CreateEndpointResponse, error) {
|
func (driver *driver) CreateEndpoint(create *api.CreateEndpointRequest) (*api.CreateEndpointResponse, error) {
|
||||||
driver.logReq("CreateEndpoint", create, create.EndpointID)
|
driver.logReq("CreateEndpoint", create, create.EndpointID)
|
||||||
|
common.Log.Debugf("interface %+v", create.Interface)
|
||||||
|
|
||||||
if create.Interface == nil {
|
if create.Interface == nil {
|
||||||
return nil, driver.error("CreateEndpoint", "Not supported: creating an interface from within CreateEndpoint")
|
return nil, driver.error("CreateEndpoint", "Not supported: creating an interface from within CreateEndpoint")
|
||||||
}
|
}
|
||||||
resp := &api.CreateEndpointResponse{}
|
|
||||||
|
// create veths. note we assume endpoint IDs are unique in the first 9 chars
|
||||||
|
name, peerName := vethPair(create.EndpointID)
|
||||||
|
if _, err := weavenet.CreateAndAttachVeth(name, peerName, weavenet.WeaveBridgeName, 0, false, nil); err != nil {
|
||||||
|
return nil, driver.error("JoinEndpoint", "%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send back the MAC address
|
||||||
|
link, _ := netlink.LinkByName(peerName)
|
||||||
|
resp := &api.CreateEndpointResponse{Interface: &api.EndpointInterface{MacAddress: link.Attrs().HardwareAddr.String()}}
|
||||||
|
|
||||||
driver.logRes("CreateEndpoint", resp)
|
driver.logRes("CreateEndpoint", resp)
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@@ -106,6 +117,17 @@ func (driver *driver) CreateEndpoint(create *api.CreateEndpointRequest) (*api.Cr
|
|||||||
|
|
||||||
func (driver *driver) DeleteEndpoint(deleteReq *api.DeleteEndpointRequest) error {
|
func (driver *driver) DeleteEndpoint(deleteReq *api.DeleteEndpointRequest) error {
|
||||||
driver.logReq("DeleteEndpoint", deleteReq, deleteReq.EndpointID)
|
driver.logReq("DeleteEndpoint", deleteReq, deleteReq.EndpointID)
|
||||||
|
name, _ := vethPair(deleteReq.EndpointID)
|
||||||
|
veth := &netlink.Veth{LinkAttrs: netlink.LinkAttrs{Name: name}}
|
||||||
|
if err := netlink.LinkDel(veth); err != nil {
|
||||||
|
// Try again using the name construction from earlier plugin version,
|
||||||
|
// in case user has upgraded with endpoints still extant
|
||||||
|
veth.Name = "vethwl" + deleteReq.EndpointID[:5]
|
||||||
|
if err2 := netlink.LinkDel(veth); err2 != nil {
|
||||||
|
// Note we report the first error
|
||||||
|
driver.warn("LeaveEndpoint", "unable to delete veth %q: %s", name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,11 +144,7 @@ func (driver *driver) JoinEndpoint(j *api.JoinRequest) (*api.JoinResponse, error
|
|||||||
return nil, driver.error("JoinEndpoint", "unable to find network info: %s", err)
|
return nil, driver.error("JoinEndpoint", "unable to find network info: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
name, peerName := vethPair(j.EndpointID)
|
_, peerName := vethPair(j.EndpointID)
|
||||||
if _, err := weavenet.CreateAndAttachVeth(name, peerName, weavenet.WeaveBridgeName, 0, false, nil); err != nil {
|
|
||||||
return nil, driver.error("JoinEndpoint", "%s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
response := &api.JoinResponse{
|
response := &api.JoinResponse{
|
||||||
InterfaceName: &api.InterfaceName{
|
InterfaceName: &api.InterfaceName{
|
||||||
SrcName: peerName,
|
SrcName: peerName,
|
||||||
@@ -186,12 +204,6 @@ func (driver *driver) setupNetworkInfo(id string, isOurs bool, options map[strin
|
|||||||
|
|
||||||
func (driver *driver) LeaveEndpoint(leave *api.LeaveRequest) error {
|
func (driver *driver) LeaveEndpoint(leave *api.LeaveRequest) error {
|
||||||
driver.logReq("LeaveEndpoint", leave, fmt.Sprintf("%s:%s", leave.NetworkID, leave.EndpointID))
|
driver.logReq("LeaveEndpoint", leave, fmt.Sprintf("%s:%s", leave.NetworkID, leave.EndpointID))
|
||||||
|
|
||||||
name, _ := vethPair(leave.EndpointID)
|
|
||||||
veth := &netlink.Veth{LinkAttrs: netlink.LinkAttrs{Name: name}}
|
|
||||||
if err := netlink.LinkDel(veth); err != nil {
|
|
||||||
driver.warn("LeaveEndpoint", "unable to delete veth: %s", err)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +218,8 @@ func (driver *driver) DiscoverDelete(disco *api.DiscoveryNotification) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func vethPair(id string) (string, string) {
|
func vethPair(id string) (string, string) {
|
||||||
return "vethwl" + id[:5], "vethwg" + id[:5]
|
// IFNAMSIZ is buffer length; subtract 6 for "vethwl" and 1 for terminating nul
|
||||||
|
return "vethwl" + id[:unix.IFNAMSIZ-7], "vethwg" + id[:unix.IFNAMSIZ-7]
|
||||||
}
|
}
|
||||||
|
|
||||||
// logging
|
// logging
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
weaveapi "github.com/weaveworks/weave/api"
|
weaveapi "github.com/weaveworks/weave/api"
|
||||||
"github.com/weaveworks/weave/common"
|
|
||||||
"github.com/weaveworks/weave/common/docker"
|
"github.com/weaveworks/weave/common/docker"
|
||||||
weavenet "github.com/weaveworks/weave/net"
|
weavenet "github.com/weaveworks/weave/net"
|
||||||
)
|
)
|
||||||
@@ -46,7 +45,7 @@ func (w *watcher) ContainerStarted(id string) {
|
|||||||
if err := w.weave.RegisterWithDNS(id, fqdn, net.IPAddress); err != nil {
|
if err := w.weave.RegisterWithDNS(id, fqdn, net.IPAddress); err != nil {
|
||||||
w.driver.warn("ContainerStarted", "unable to register %s with weaveDNS: %s", id, err)
|
w.driver.warn("ContainerStarted", "unable to register %s with weaveDNS: %s", id, err)
|
||||||
}
|
}
|
||||||
if err := common.ConfigureARPforVeths(info.State.Pid, weavenet.VethName); err != nil {
|
if _, err := weavenet.WithNetNSByPid(info.State.Pid, "configure-arp", weavenet.VethName); err != nil {
|
||||||
w.driver.warn("ContainerStarted", "unable to configure interfaces: %s", err)
|
w.driver.warn("ContainerStarted", "unable to configure interfaces: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/mflag"
|
"github.com/weaveworks/docker/pkg/mflag"
|
||||||
"github.com/weaveworks/weave/common"
|
"github.com/weaveworks/weave/common"
|
||||||
"github.com/weaveworks/weave/common/mflagext"
|
"github.com/weaveworks/weave/common/mflagext"
|
||||||
"github.com/weaveworks/weave/proxy"
|
"github.com/weaveworks/weave/proxy"
|
||||||
|
|||||||
+13
-13
@@ -32,9 +32,21 @@ func checkForUpdates(dockerVersion string, network string) {
|
|||||||
|
|
||||||
var uts syscall.Utsname
|
var uts syscall.Utsname
|
||||||
syscall.Uname(&uts)
|
syscall.Uname(&uts)
|
||||||
|
|
||||||
|
release := uts.Release[:]
|
||||||
|
releaseBytes := make([]byte, len(release))
|
||||||
|
i := 0
|
||||||
|
for ; i < len(release); i++ {
|
||||||
|
if release[i] == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
releaseBytes[i] = uint8(release[i])
|
||||||
|
}
|
||||||
|
kernelVersion := string(releaseBytes[:i])
|
||||||
|
|
||||||
flags := map[string]string{
|
flags := map[string]string{
|
||||||
"docker-version": dockerVersion,
|
"docker-version": dockerVersion,
|
||||||
"kernel-version": charsToString(uts.Release[:]),
|
"kernel-version": kernelVersion,
|
||||||
}
|
}
|
||||||
if network != "" {
|
if network != "" {
|
||||||
flags["network"] = network
|
flags["network"] = network
|
||||||
@@ -49,15 +61,3 @@ func checkForUpdates(dockerVersion string, network string) {
|
|||||||
}
|
}
|
||||||
checker = checkpoint.CheckInterval(¶ms, updateCheckPeriod, handleResponse)
|
checker = checkpoint.CheckInterval(¶ms, updateCheckPeriod, handleResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
func charsToString(ca []int8) string {
|
|
||||||
s := make([]byte, len(ca))
|
|
||||||
i := 0
|
|
||||||
for ; i < len(ca); i++ {
|
|
||||||
if ca[i] == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
s[i] = uint8(ca[i])
|
|
||||||
}
|
|
||||||
return string(s[:i])
|
|
||||||
}
|
|
||||||
+2
-1
@@ -11,9 +11,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/mflag"
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/pkg/profile"
|
"github.com/pkg/profile"
|
||||||
|
"github.com/weaveworks/docker/pkg/mflag"
|
||||||
"github.com/weaveworks/mesh"
|
"github.com/weaveworks/mesh"
|
||||||
|
|
||||||
"github.com/weaveworks/weave/common"
|
"github.com/weaveworks/weave/common"
|
||||||
@@ -322,6 +322,7 @@ func main() {
|
|||||||
if errors := router.InitiateConnections(peers, false); len(errors) > 0 {
|
if errors := router.InitiateConnections(peers, false); len(errors) > 0 {
|
||||||
Log.Fatal(common.ErrorMessages(errors))
|
Log.Fatal(common.ErrorMessages(errors))
|
||||||
}
|
}
|
||||||
|
checkFatal(router.CreateRestartSentinel())
|
||||||
|
|
||||||
// The weave script always waits for a status call to succeed,
|
// The weave script always waits for a status call to succeed,
|
||||||
// so there is no point in doing "weave launch --http-addr ''".
|
// so there is no point in doing "weave launch --http-addr ''".
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/weaveworks/weave/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func dockerTLSArgs(args []string) error {
|
func dockerTLSArgs(args []string) error {
|
||||||
@@ -15,18 +17,14 @@ func dockerTLSArgs(args []string) error {
|
|||||||
cmdUsage("docker-tls-args", "")
|
cmdUsage("docker-tls-args", "")
|
||||||
}
|
}
|
||||||
procRoot := "/proc"
|
procRoot := "/proc"
|
||||||
dirEntries, err := ioutil.ReadDir(procRoot)
|
pids, err := common.AllPids(procRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dirEntry := range dirEntries {
|
for _, pid := range pids {
|
||||||
dirName := dirEntry.Name()
|
|
||||||
if _, err := strconv.Atoi(dirName); err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
isDaemon := false
|
isDaemon := false
|
||||||
|
dirName := strconv.Itoa(pid)
|
||||||
if comm, err := ioutil.ReadFile(filepath.Join(procRoot, dirName, "comm")); err != nil {
|
if comm, err := ioutil.ReadFile(filepath.Join(procRoot, dirName, "comm")); err != nil {
|
||||||
continue
|
continue
|
||||||
} else if string(comm) == "dockerd\n" {
|
} else if string(comm) == "dockerd\n" {
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ func init() {
|
|||||||
"create-plugin-network": createPluginNetwork,
|
"create-plugin-network": createPluginNetwork,
|
||||||
"remove-plugin-network": removePluginNetwork,
|
"remove-plugin-network": removePluginNetwork,
|
||||||
"container-addrs": containerAddrs,
|
"container-addrs": containerAddrs,
|
||||||
|
"process-addrs": processAddrs,
|
||||||
"attach-container": attach,
|
"attach-container": attach,
|
||||||
"detach-container": detach,
|
"detach-container": detach,
|
||||||
|
"configure-arp": configureARP,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/j-keck/arping"
|
||||||
|
"github.com/vishvananda/netlink"
|
||||||
|
|
||||||
|
weavenet "github.com/weaveworks/weave/net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func configureARP(args []string) error {
|
||||||
|
if len(args) != 1 {
|
||||||
|
cmdUsage("configure-arp", "<iface-name-prefix>")
|
||||||
|
}
|
||||||
|
prefix := args[0]
|
||||||
|
|
||||||
|
links, err := netlink.LinkList()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, link := range links {
|
||||||
|
ifName := link.Attrs().Name
|
||||||
|
if strings.HasPrefix(ifName, prefix) {
|
||||||
|
weavenet.ConfigureARPCache(ifName)
|
||||||
|
if addrs, err := netlink.AddrList(link, netlink.FAMILY_V4); err == nil {
|
||||||
|
for _, addr := range addrs {
|
||||||
|
arping.GratuitousArpOverIfaceByName(addr.IPNet.IP, ifName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/weaveworks/weave/common"
|
||||||
|
weavenet "github.com/weaveworks/weave/net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func processAddrs(args []string) error {
|
||||||
|
if len(args) < 1 {
|
||||||
|
cmdUsage("process-addrs", "<bridgeName>")
|
||||||
|
}
|
||||||
|
bridgeName := args[0]
|
||||||
|
|
||||||
|
pred, err := common.ConnectedToBridgePredicate(bridgeName)
|
||||||
|
if err != nil {
|
||||||
|
if err == weavenet.ErrLinkNotFound {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pids, err := common.AllPids("/proc")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NB: Because network namespaces (netns) are changed many times inside the loop,
|
||||||
|
// it's NOT safe to exec any code depending on the root netns without
|
||||||
|
// wrapping with WithNetNS*.
|
||||||
|
for _, pid := range pids {
|
||||||
|
netDevs, err := common.GetNetDevsWithPredicate(pid, pred)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
printNetDevs(strconv.Itoa(pid), netDevs)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -239,12 +239,16 @@ func (router *NetworkRouter) InitialPeers(resume bool, peers []string) ([]string
|
|||||||
return storedPeers, nil
|
return storedPeers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
sentinel, err := os.Create("restart.sentinel")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error creating sentinel: %v", err)
|
|
||||||
}
|
|
||||||
sentinel.Close()
|
|
||||||
|
|
||||||
log.Println("Launch detected - using supplied peer list:", peers)
|
log.Println("Launch detected - using supplied peer list:", peers)
|
||||||
return peers, nil
|
return peers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (router *NetworkRouter) CreateRestartSentinel() error {
|
||||||
|
sentinel, err := os.Create("restart.sentinel")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error creating sentinel: %v", err)
|
||||||
|
}
|
||||||
|
sentinel.Close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
+5
-5
@@ -73,7 +73,7 @@ Containers started in this way that subsequently restart, either
|
|||||||
by an explicit `docker restart` command or by Docker restart
|
by an explicit `docker restart` command or by Docker restart
|
||||||
policy, are re-attached to the Weave network by the `Weave Docker API Proxy`.
|
policy, are re-attached to the Weave network by the `Weave Docker API Proxy`.
|
||||||
|
|
||||||
See [Using the Weave Docker API Proxy](/site/weave-docker-api/using-proxy.md).
|
See [Integrating Docker via the API Proxy](/site/weave-docker-api.md).
|
||||||
|
|
||||||
|
|
||||||
###<a name="plugin"></a>Weave Network Docker Plugin
|
###<a name="plugin"></a>Weave Network Docker Plugin
|
||||||
@@ -88,14 +88,14 @@ Using the Weave plugin enables you to take advantage of [Docker's network functi
|
|||||||
Also, Weave’s Docker Network plugin doesn't require an external cluster store and you can start and stop containers even
|
Also, Weave’s Docker Network plugin doesn't require an external cluster store and you can start and stop containers even
|
||||||
when there are network connectivity problems.
|
when there are network connectivity problems.
|
||||||
|
|
||||||
See [Using the Weave Docker Network Plugin](/site/plugin.md) for more details.
|
See [Integrating Docker via the Network Plugin](/site/plugin.md) for more details.
|
||||||
|
|
||||||
|
|
||||||
###<a name="cniplugin"></a>Weave Network CNI Plugin
|
###<a name="cniplugin"></a>Weave Network CNI Plugin
|
||||||
|
|
||||||
Weave can be used as a plugin to systems that support the [Container Network Interface](https://github.com/appc/cni), such as Kubernetes.
|
Weave can be used as a plugin to systems that support the [Container Network Interface](https://github.com/appc/cni), such as Kubernetes and Mesosphere.
|
||||||
|
|
||||||
See [Using the Weave CNI Plugin](/site/cni-plugin.md) for more details.
|
See [Integrating Kubernetes and Mesos via the CNI Plugin](/site/cni-plugin.md) for more details.
|
||||||
|
|
||||||
|
|
||||||
###<a name="addressing"></a>IP Address Management (IPAM)
|
###<a name="addressing"></a>IP Address Management (IPAM)
|
||||||
@@ -120,7 +120,7 @@ and are discoverable by using standard, simple name lookups:
|
|||||||
|
|
||||||
WeaveDNS also supports [load balancing](/site/weavedns/load-balance-fault-weavedns.md), [fault resilience](/site/weavedns/load-balance-fault-weavedns.md) and [hot swapping](/site/weavedns/managing-entries-weavedns.md).
|
WeaveDNS also supports [load balancing](/site/weavedns/load-balance-fault-weavedns.md), [fault resilience](/site/weavedns/load-balance-fault-weavedns.md) and [hot swapping](/site/weavedns/managing-entries-weavedns.md).
|
||||||
|
|
||||||
See [Naming and discovery with WeaveDNS](/site/weavedns/how-works-weavedns.md).
|
See [Discovering Containers with WeaveDNS](/site/weavedns.md).
|
||||||
|
|
||||||
###<a name="application-isolation"></a>Application Isolation
|
###<a name="application-isolation"></a>Application Isolation
|
||||||
|
|
||||||
|
|||||||
@@ -39,4 +39,4 @@ The plugin accepts the following options via `docker network create ... --opt`:
|
|||||||
**See Also**
|
**See Also**
|
||||||
|
|
||||||
* [Integrating Docker via the Network Plugin](/site/plugin.md)
|
* [Integrating Docker via the Network Plugin](/site/plugin.md)
|
||||||
|
|
||||||
@@ -3,15 +3,38 @@ title: Integrating Docker via the API Proxy
|
|||||||
menu_order: 50
|
menu_order: 50
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
The Docker API proxy automatically attaches containers to the Weave
|
The Docker API proxy automatically attaches containers to the Weave
|
||||||
network when they are started using the ordinary Docker
|
network when they are started using the ordinary Docker
|
||||||
[command-line interface](https://docs.docker.com/reference/commandline/cli/)
|
[command-line interface](https://docs.docker.com/reference/commandline/cli/)
|
||||||
or the [remote API](https://docs.docker.com/reference/api/docker_remote_api/),
|
or the [remote API](https://docs.docker.com/reference/api/docker_remote_api/),
|
||||||
instead of `weave run`.
|
instead of `weave run`.
|
||||||
|
|
||||||
|
###<a name="attaching-containers"></a>Attaching Containers to a Weave Network
|
||||||
|
|
||||||
###Setting Up The Weave Net Docker API Proxy
|
There are three ways to attach containers to a Weave network (which method to use is
|
||||||
|
entirely up to you):
|
||||||
|
|
||||||
|
**1.** The Weave Net Docker API Proxy. See [Setting Up the Weave Net Docker API Proxy](#weave-api-proxy).
|
||||||
|
|
||||||
|
**2.** The Docker Network Plugin framework. The Docker Network Plugin is used when
|
||||||
|
Docker containers are started with the --net flag, for example:
|
||||||
|
|
||||||
|
`docker run --net <docker-run-options>`
|
||||||
|
|
||||||
|
**Where,**
|
||||||
|
|
||||||
|
* `<docker-run-options>` are the [docker run options](https://docs.docker.com/engine/reference/run/)
|
||||||
|
you give to your container on start
|
||||||
|
|
||||||
|
Note that if a Docker container is started with the --net flag, then the Weave Docker API Proxy
|
||||||
|
is automatically disabled and is not used to attach containers.
|
||||||
|
See [Integrating Docker via the Network Plugin](plugin.md).
|
||||||
|
|
||||||
|
**3.** Containers can also be attached to the Weave network with `weave run` commands. This method also
|
||||||
|
does not use the Weave Docker API Proxy.
|
||||||
|
See [Launching Containers With Weave Run (without the Proxy)](/site/weave-docker-api/launching-without-proxy.md).
|
||||||
|
|
||||||
|
###<a name="weave-api-proxy"></a>Setting Up The Weave Net Docker API Proxy
|
||||||
|
|
||||||
The proxy sits between the Docker client (command line or API) and the
|
The proxy sits between the Docker client (command line or API) and the
|
||||||
Docker daemon, and intercepts the communication between the two. You can
|
Docker daemon, and intercepts the communication between the two. You can
|
||||||
|
|||||||
+1
-1
@@ -44,5 +44,5 @@ disable weaveDNS itself, launch weave with the `--no-dns` option.
|
|||||||
|
|
||||||
**See Also**
|
**See Also**
|
||||||
|
|
||||||
* [How Weave Finds Containers](/site/weave-docker-api.md)
|
* [Integrating Docker via the API Proxy](/site/weave-docker-api.md)
|
||||||
* [Load Balancing and Fault Resilience with WeaveDNS](/site/weavedns/load-balance-fault-weavedns.md)
|
* [Load Balancing and Fault Resilience with WeaveDNS](/site/weavedns/load-balance-fault-weavedns.md)
|
||||||
+1
Submodule vendor/github.com/weaveworks/docker added at 4dc5990d75.
+1
-1
Submodule vendor/github.com/weaveworks/mesh updated: 50329b4166...3e1ae95e23.
+1
Submodule vendor/golang.org/x/sys added at 62bee03759.
@@ -597,9 +597,17 @@ create_bridge() {
|
|||||||
add_iptables_rule filter INPUT -i $DOCKER_BRIDGE -p udp --dport 53 -j ACCEPT
|
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
|
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
|
if [ "$2" = "--expect-npc" ] ; then # matches usage in weave-kube launch.sh
|
||||||
# across our bridge. E.g. ufw
|
# Steer traffic via the NPC
|
||||||
add_iptables_rule filter FORWARD -i $BRIDGE -o $BRIDGE -j ACCEPT
|
run_iptables -N WEAVE-NPC >/dev/null 2>&1 || true
|
||||||
|
add_iptables_rule filter FORWARD -o $BRIDGE -j WEAVE-NPC
|
||||||
|
add_iptables_rule filter FORWARD -o $BRIDGE -j LOG --log-prefix=WEAVE-NPC:
|
||||||
|
add_iptables_rule filter FORWARD -o $BRIDGE -j DROP
|
||||||
|
else
|
||||||
|
# Work around the situation where there are no rules allowing traffic
|
||||||
|
# across our bridge. E.g. ufw
|
||||||
|
add_iptables_rule filter FORWARD -i $BRIDGE -o $BRIDGE -j ACCEPT
|
||||||
|
fi
|
||||||
|
|
||||||
# create a chain for masquerading
|
# create a chain for masquerading
|
||||||
run_iptables -t nat -N WEAVE >/dev/null 2>&1 || true
|
run_iptables -t nat -N WEAVE >/dev/null 2>&1 || true
|
||||||
@@ -807,11 +815,6 @@ do_or_die() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute arguments as a command within the $CONTAINER_NETNS network namespace
|
|
||||||
netnsenter() {
|
|
||||||
nsenter --net=$CONTAINER_NETNS "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
add_iface_fastdp() {
|
add_iface_fastdp() {
|
||||||
util_op add-datapath-interface $DATAPATH $1
|
util_op add-datapath-interface $DATAPATH $1
|
||||||
}
|
}
|
||||||
@@ -858,10 +861,6 @@ ask_version() {
|
|||||||
[ -n "$DOCKERIMAGE" ] && docker run --rm --net=none -e WEAVE_CIDR=none $3 $DOCKERIMAGE $COVERAGE_ARGS --version
|
[ -n "$DOCKERIMAGE" ] && docker run --rm --net=none -e WEAVE_CIDR=none $3 $DOCKERIMAGE $COVERAGE_ARGS --version
|
||||||
}
|
}
|
||||||
|
|
||||||
container_in_host_ns() {
|
|
||||||
[ -h "$CONTAINER_NETNS" -a -h "/proc/self/ns/net" -a "$(readlink $CONTAINER_NETNS)" = "$(readlink /proc/self/ns/net)" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
attach() {
|
attach() {
|
||||||
ATTACH_ARGS=""
|
ATTACH_ARGS=""
|
||||||
[ -n "$NO_MULTICAST_ROUTE" ] && ATTACH_ARGS="--no-multicast-route"
|
[ -n "$NO_MULTICAST_ROUTE" ] && ATTACH_ARGS="--no-multicast-route"
|
||||||
@@ -1948,8 +1947,10 @@ really want to do this please set the WEAVE_NO_FASTDP environment variable.
|
|||||||
EOF
|
EOF
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
shift 1
|
||||||
fi
|
fi
|
||||||
create_bridge --without-ethtool
|
create_bridge --without-ethtool "$@"
|
||||||
;;
|
;;
|
||||||
attach-bridge)
|
attach-bridge)
|
||||||
if detect_bridge_type ; then
|
if detect_bridge_type ; then
|
||||||
|
|||||||
Reference in new issue
Block a user