Compile the dnet tool for Linux (x86, amd64 and arm)
and Windows (x86 and amd64)
- Moved installation of dependencies into `Dockerfile.build`
- Remove `start-services` from Makefile
- That's the responsibility of Docker or build environment
- Removed utils depending on `netlink` from `netutils/utils.go`
Unable to add `make cross` to CircleCI just yet as there are some
issues to solve that are unrelated to this PR
Also fix `.gitignore` which was not updated after changing the build
image name in #667
Signed-off-by: Dave Tucker <dt@docker.com>
| 37 | 37 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,8 @@ |
| 0 |
+FROM golang:1.4-cross |
|
| 1 |
+RUN apt-get update && apt-get -y install iptables |
|
| 2 |
+RUN go get github.com/tools/godep \ |
|
| 3 |
+ github.com/golang/lint/golint \ |
|
| 4 |
+ golang.org/x/tools/cmd/vet \ |
|
| 5 |
+ golang.org/x/tools/cmd/goimports \ |
|
| 6 |
+ golang.org/x/tools/cmd/cover\ |
|
| 7 |
+ github.com/mattn/goveralls |
| ... | ... |
@@ -1,42 +1,46 @@ |
| 1 |
-.PHONY: all all-local build build-local check check-code check-format run-tests check-local integration-tests install-deps coveralls circle-ci start-services clean |
|
| 1 |
+.PHONY: all all-local build build-local clean cross cross-local check check-code check-format run-tests integration-tests check-local coveralls circle-ci-cross circle-ci-build circle-ci-check circle-ci |
|
| 2 | 2 |
SHELL=/bin/bash |
| 3 | 3 |
build_image=libnetworkbuild |
| 4 | 4 |
dockerargs = --privileged -v $(shell pwd):/go/src/github.com/docker/libnetwork -w /go/src/github.com/docker/libnetwork |
| 5 | 5 |
container_env = -e "INSIDECONTAINER=-incontainer=true" |
| 6 |
-docker = docker run --rm -it ${dockerargs} ${container_env} ${build_image}
|
|
| 6 |
+docker = docker run --rm -it ${dockerargs} $$EXTRA_ARGS ${container_env} ${build_image}
|
|
| 7 | 7 |
ciargs = -e "COVERALLS_TOKEN=$$COVERALLS_TOKEN" -e "INSIDECONTAINER=-incontainer=true" |
| 8 |
-cidocker = docker run ${ciargs} ${dockerargs} golang:1.4
|
|
| 9 |
- |
|
| 10 |
-all: ${build_image}.created build check integration-tests clean
|
|
| 11 |
- |
|
| 12 |
-integration-tests: ./cmd/dnet/dnet |
|
| 13 |
- @./test/integration/dnet/run-integration-tests.sh |
|
| 14 |
- |
|
| 15 |
-./cmd/dnet/dnet: |
|
| 16 |
- make build |
|
| 17 |
- |
|
| 18 |
-clean: |
|
| 19 |
- @if [ -e ./cmd/dnet/dnet ]; then \ |
|
| 20 |
- echo "Removing dnet binary"; \ |
|
| 21 |
- rm -rf ./cmd/dnet/dnet; \ |
|
| 22 |
- fi |
|
| 23 |
- |
|
| 24 |
-all-local: check-local build-local |
|
| 8 |
+cidocker = docker run ${dockerargs} ${ciargs} ${container_env} ${build_image}
|
|
| 9 |
+CROSS_PLATFORMS = linux/amd64 linux/386 linux/arm windows/amd64 windows/386 |
|
| 25 | 10 |
|
| 26 | 11 |
${build_image}.created:
|
| 27 |
- docker run --name=libnetworkbuild -v $(shell pwd):/go/src/github.com/docker/libnetwork -w /go/src/github.com/docker/libnetwork golang:1.4 make install-deps |
|
| 28 |
- docker commit libnetworkbuild ${build_image}
|
|
| 29 |
- docker rm libnetworkbuild |
|
| 12 |
+ docker build -f Dockerfile.build -t ${build_image} .
|
|
| 30 | 13 |
touch ${build_image}.created
|
| 31 | 14 |
|
| 15 |
+all: ${build_image}.created build check integration-tests clean
|
|
| 16 |
+ |
|
| 17 |
+all-local: build-local check-local integration-tests-local clean |
|
| 18 |
+ |
|
| 32 | 19 |
build: ${build_image}.created
|
| 33 | 20 |
@echo "Building code... " |
| 34 | 21 |
@${docker} ./wrapmake.sh build-local
|
| 35 | 22 |
@echo "Done building code" |
| 36 | 23 |
|
| 37 | 24 |
build-local: |
| 38 |
- @$(shell which godep) go build ./... |
|
| 39 |
- @$(shell which godep) go build -o ./cmd/dnet/dnet ./cmd/dnet |
|
| 25 |
+ @mkdir -p "bin" |
|
| 26 |
+ $(shell which godep) go build -o "bin/dnet" ./cmd/dnet |
|
| 27 |
+ |
|
| 28 |
+clean: |
|
| 29 |
+ @if [ -d bin ]; then \ |
|
| 30 |
+ echo "Removing dnet binaries"; \ |
|
| 31 |
+ rm -rf bin; \ |
|
| 32 |
+ fi |
|
| 33 |
+ |
|
| 34 |
+cross: ${build_image}.created
|
|
| 35 |
+ @mkdir -p "bin" |
|
| 36 |
+ @for platform in ${CROSS_PLATFORMS}; do \
|
|
| 37 |
+ EXTRA_ARGS="-e GOOS=$${platform%/*} -e GOARCH=$${platform##*/}" ; \
|
|
| 38 |
+ echo "$${platform}..." ; \
|
|
| 39 |
+ ${docker} make cross-local ; \
|
|
| 40 |
+ done |
|
| 41 |
+ |
|
| 42 |
+cross-local: |
|
| 43 |
+ $(shell which godep) go build -o "bin/dnet-$$GOOS-$$GOARCH" ./cmd/dnet |
|
| 40 | 44 |
|
| 41 | 45 |
check: ${build_image}.created
|
| 42 | 46 |
@${docker} ./wrapmake.sh check-local
|
| ... | ... |
@@ -71,27 +75,31 @@ run-tests: |
| 71 | 71 |
done |
| 72 | 72 |
@echo "Done running tests" |
| 73 | 73 |
|
| 74 |
-check-local: check-format check-code start-services run-tests |
|
| 74 |
+check-local: check-format check-code run-tests |
|
| 75 |
+ |
|
| 76 |
+integration-tests: ./bin/dnet |
|
| 77 |
+ @./test/integration/dnet/run-integration-tests.sh |
|
| 75 | 78 |
|
| 76 |
-install-deps: |
|
| 77 |
- apt-get update && apt-get -y install iptables zookeeperd |
|
| 78 |
- git clone https://github.com/golang/tools /go/src/golang.org/x/tools |
|
| 79 |
- go install golang.org/x/tools/cmd/vet |
|
| 80 |
- go install golang.org/x/tools/cmd/goimports |
|
| 81 |
- go install golang.org/x/tools/cmd/cover |
|
| 82 |
- go get github.com/tools/godep |
|
| 83 |
- go get github.com/golang/lint/golint |
|
| 84 |
- go get github.com/mattn/goveralls |
|
| 79 |
+./bin/dnet: |
|
| 80 |
+ make build |
|
| 85 | 81 |
|
| 86 | 82 |
coveralls: |
| 87 | 83 |
-@goveralls -service circleci -coverprofile=coverage.coverprofile -repotoken $$COVERALLS_TOKEN |
| 88 | 84 |
|
| 89 | 85 |
# CircleCI's Docker fails when cleaning up using the --rm flag |
| 90 |
-# The following target is a workaround for this |
|
| 86 |
+# The following targets are a workaround for this |
|
| 87 |
+circle-ci-cross: ${build_image}.created
|
|
| 88 |
+ @mkdir -p "bin" |
|
| 89 |
+ @for platform in ${CROSS_PLATFORMS}; do \
|
|
| 90 |
+ EXTRA_ARGS="-e GOOS=$${platform%/*} -e GOARCH=$${platform##*/}" ; \
|
|
| 91 |
+ echo "$${platform}..." ; \
|
|
| 92 |
+ ${cidocker} make cross-local ; \
|
|
| 93 |
+ done |
|
| 94 |
+ |
|
| 95 |
+circle-ci-check: ${build_image}.created
|
|
| 96 |
+ @${cidocker} make check-local coveralls
|
|
| 91 | 97 |
|
| 92 |
-circle-ci: |
|
| 93 |
- @${cidocker} make install-deps build-local check-local coveralls
|
|
| 94 |
- make integration-tests |
|
| 98 |
+circle-ci-build: ${build_image}.created
|
|
| 99 |
+ @${cidocker} make build-local
|
|
| 95 | 100 |
|
| 96 |
-start-services: |
|
| 97 |
- service zookeeper start |
|
| 101 |
+circle-ci: circle-ci-check circle-ci-build integration-tests |
| ... | ... |
@@ -1,12 +1,18 @@ |
| 1 | 1 |
machine: |
| 2 |
- services: |
|
| 3 |
- - docker |
|
| 2 |
+ services: |
|
| 3 |
+ - docker |
|
| 4 | 4 |
|
| 5 | 5 |
dependencies: |
| 6 |
- override: |
|
| 7 |
- - echo "Nothing to install" |
|
| 6 |
+ override: |
|
| 7 |
+ - sudo apt-get update; sudo apt-get install -y iptables zookeeperd |
|
| 8 |
+ - go get golang.org/x/tools/cmd/vet |
|
| 9 |
+ - go get golang.org/x/tools/cmd/goimports |
|
| 10 |
+ - go get golang.org/x/tools/cmd/cover |
|
| 11 |
+ - go get github.com/tools/godep |
|
| 12 |
+ - go get github.com/golang/lint/golint |
|
| 13 |
+ - go get github.com/mattn/goveralls |
|
| 8 | 14 |
|
| 9 | 15 |
test: |
| 10 |
- override: |
|
| 11 |
- - make circle-ci |
|
| 16 |
+ override: |
|
| 17 |
+ - make circle-ci |
|
| 12 | 18 |
|
| ... | ... |
@@ -9,10 +9,8 @@ import ( |
| 9 | 9 |
"fmt" |
| 10 | 10 |
"io" |
| 11 | 11 |
"net" |
| 12 |
- "strings" |
|
| 13 | 12 |
|
| 14 | 13 |
"github.com/docker/libnetwork/types" |
| 15 |
- "github.com/vishvananda/netlink" |
|
| 16 | 14 |
) |
| 17 | 15 |
|
| 18 | 16 |
var ( |
| ... | ... |
@@ -22,8 +20,6 @@ var ( |
| 22 | 22 |
ErrNetworkOverlaps = errors.New("requested network overlaps with existing network")
|
| 23 | 23 |
// ErrNoDefaultRoute preformatted error |
| 24 | 24 |
ErrNoDefaultRoute = errors.New("no default route")
|
| 25 |
- |
|
| 26 |
- networkGetRoutesFct = netlink.RouteList |
|
| 27 | 25 |
) |
| 28 | 26 |
|
| 29 | 27 |
// CheckNameserverOverlaps checks whether the passed network overlaps with any of the nameservers |
| ... | ... |
@@ -42,21 +38,6 @@ func CheckNameserverOverlaps(nameservers []string, toCheck *net.IPNet) error {
|
| 42 | 42 |
return nil |
| 43 | 43 |
} |
| 44 | 44 |
|
| 45 |
-// CheckRouteOverlaps checks whether the passed network overlaps with any existing routes |
|
| 46 |
-func CheckRouteOverlaps(toCheck *net.IPNet) error {
|
|
| 47 |
- networks, err := networkGetRoutesFct(nil, netlink.FAMILY_V4) |
|
| 48 |
- if err != nil {
|
|
| 49 |
- return err |
|
| 50 |
- } |
|
| 51 |
- |
|
| 52 |
- for _, network := range networks {
|
|
| 53 |
- if network.Dst != nil && NetworkOverlaps(toCheck, network.Dst) {
|
|
| 54 |
- return ErrNetworkOverlaps |
|
| 55 |
- } |
|
| 56 |
- } |
|
| 57 |
- return nil |
|
| 58 |
-} |
|
| 59 |
- |
|
| 60 | 45 |
// NetworkOverlaps detects overlap between one IPNet and another |
| 61 | 46 |
func NetworkOverlaps(netX *net.IPNet, netY *net.IPNet) bool {
|
| 62 | 47 |
return netX.Contains(netY.IP) || netY.Contains(netX.IP) |
| ... | ... |
@@ -151,22 +132,3 @@ func GenerateRandomName(prefix string, size int) (string, error) {
|
| 151 | 151 |
} |
| 152 | 152 |
return prefix + hex.EncodeToString(id)[:size], nil |
| 153 | 153 |
} |
| 154 |
- |
|
| 155 |
-// GenerateIfaceName returns an interface name using the passed in |
|
| 156 |
-// prefix and the length of random bytes. The api ensures that the |
|
| 157 |
-// there are is no interface which exists with that name. |
|
| 158 |
-func GenerateIfaceName(prefix string, len int) (string, error) {
|
|
| 159 |
- for i := 0; i < 3; i++ {
|
|
| 160 |
- name, err := GenerateRandomName(prefix, len) |
|
| 161 |
- if err != nil {
|
|
| 162 |
- continue |
|
| 163 |
- } |
|
| 164 |
- if _, err := netlink.LinkByName(name); err != nil {
|
|
| 165 |
- if strings.Contains(err.Error(), "not found") {
|
|
| 166 |
- return name, nil |
|
| 167 |
- } |
|
| 168 |
- return "", err |
|
| 169 |
- } |
|
| 170 |
- } |
|
| 171 |
- return "", types.InternalErrorf("could not generate interface name")
|
|
| 172 |
-} |
| 173 | 154 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,50 @@ |
| 0 |
+// +build linux |
|
| 1 |
+// Network utility functions. |
|
| 2 |
+ |
|
| 3 |
+package netutils |
|
| 4 |
+ |
|
| 5 |
+import ( |
|
| 6 |
+ "net" |
|
| 7 |
+ "strings" |
|
| 8 |
+ |
|
| 9 |
+ "github.com/docker/libnetwork/types" |
|
| 10 |
+ "github.com/vishvananda/netlink" |
|
| 11 |
+) |
|
| 12 |
+ |
|
| 13 |
+var ( |
|
| 14 |
+ networkGetRoutesFct = netlink.RouteList |
|
| 15 |
+) |
|
| 16 |
+ |
|
| 17 |
+// CheckRouteOverlaps checks whether the passed network overlaps with any existing routes |
|
| 18 |
+func CheckRouteOverlaps(toCheck *net.IPNet) error {
|
|
| 19 |
+ networks, err := networkGetRoutesFct(nil, netlink.FAMILY_V4) |
|
| 20 |
+ if err != nil {
|
|
| 21 |
+ return err |
|
| 22 |
+ } |
|
| 23 |
+ |
|
| 24 |
+ for _, network := range networks {
|
|
| 25 |
+ if network.Dst != nil && NetworkOverlaps(toCheck, network.Dst) {
|
|
| 26 |
+ return ErrNetworkOverlaps |
|
| 27 |
+ } |
|
| 28 |
+ } |
|
| 29 |
+ return nil |
|
| 30 |
+} |
|
| 31 |
+ |
|
| 32 |
+// GenerateIfaceName returns an interface name using the passed in |
|
| 33 |
+// prefix and the length of random bytes. The api ensures that the |
|
| 34 |
+// there are is no interface which exists with that name. |
|
| 35 |
+func GenerateIfaceName(prefix string, len int) (string, error) {
|
|
| 36 |
+ for i := 0; i < 3; i++ {
|
|
| 37 |
+ name, err := GenerateRandomName(prefix, len) |
|
| 38 |
+ if err != nil {
|
|
| 39 |
+ continue |
|
| 40 |
+ } |
|
| 41 |
+ if _, err := netlink.LinkByName(name); err != nil {
|
|
| 42 |
+ if strings.Contains(err.Error(), "not found") {
|
|
| 43 |
+ return name, nil |
|
| 44 |
+ } |
|
| 45 |
+ return "", err |
|
| 46 |
+ } |
|
| 47 |
+ } |
|
| 48 |
+ return "", types.InternalErrorf("could not generate interface name")
|
|
| 49 |
+} |
| ... | ... |
@@ -21,10 +21,10 @@ load helpers |
| 21 | 21 |
run dnet_cmd 8080 network ls |
| 22 | 22 |
echo ${output}
|
| 23 | 23 |
[ "$status" -ne 0 ] |
| 24 |
- run ./cmd/dnet/dnet -H=unix://var/run/dnet.sock network ls |
|
| 24 |
+ run ./bin/dnet -H=unix://var/run/dnet.sock network ls |
|
| 25 | 25 |
echo ${output}
|
| 26 | 26 |
[ "$status" -ne 0 ] |
| 27 |
- run ./cmd/dnet/dnet -H= -l=invalid network ls |
|
| 27 |
+ run ./bin/dnet -H= -l=invalid network ls |
|
| 28 | 28 |
echo ${output}
|
| 29 | 29 |
[ "$status" -ne 0 ] |
| 30 | 30 |
stop_dnet 1 c |
| ... | ... |
@@ -73,7 +73,7 @@ function wait_for_dnet() {
|
| 73 | 73 |
echo "waiting on dnet to come up ..." |
| 74 | 74 |
for i in `seq 1 10`; |
| 75 | 75 |
do |
| 76 |
- hrun ./cmd/dnet/dnet -H tcp://127.0.0.1:${hport} network ls
|
|
| 76 |
+ hrun ./bin/dnet -H tcp://127.0.0.1:${hport} network ls
|
|
| 77 | 77 |
echo ${output}
|
| 78 | 78 |
if [ "$status" -eq 0 ]; then |
| 79 | 79 |
return |
| ... | ... |
@@ -168,7 +168,7 @@ EOF |
| 168 | 168 |
-v $(pwd)/${TMPC_ROOT}:/scratch \
|
| 169 | 169 |
-v /usr/local/bin/runc:/usr/local/bin/runc \ |
| 170 | 170 |
-w /go/src/github.com/docker/libnetwork \ |
| 171 |
- mrjana/golang ./cmd/dnet/dnet -d -D ${hopt} -c ${tomlfile}
|
|
| 171 |
+ mrjana/golang ./bin/dnet -d -D ${hopt} -c ${tomlfile}
|
|
| 172 | 172 |
|
| 173 | 173 |
wait_for_dnet $(inst_id2port ${inst}) ${name}
|
| 174 | 174 |
} |
| ... | ... |
@@ -196,7 +196,7 @@ function dnet_cmd() {
|
| 196 | 196 |
|
| 197 | 197 |
hport=$1 |
| 198 | 198 |
shift |
| 199 |
- ./cmd/dnet/dnet -H tcp://127.0.0.1:${hport} $*
|
|
| 199 |
+ ./bin/dnet -H tcp://127.0.0.1:${hport} $*
|
|
| 200 | 200 |
} |
| 201 | 201 |
|
| 202 | 202 |
function dnet_exec() {
|