Multi-Arch Support

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>
This commit is contained in:
Dave Tucker 2015-05-20 20:28:58 +01:00
parent 54948e26b5
commit 7ddd97684e
9 changed files with 126 additions and 90 deletions

1
.dockerignore Normal file
View File

@ -0,0 +1 @@
*

3
.gitignore vendored
View File

@ -2,6 +2,7 @@
*.o *.o
*.a *.a
*.so *.so
bin/
# Folders # Folders
integration-tmp/ integration-tmp/
@ -33,4 +34,4 @@ cmd/dnet/dnet
.project .project
.settings/ .settings/
libnetwork-build.created libnetworkbuild.created

8
Dockerfile.build Normal file
View File

@ -0,0 +1,8 @@
FROM golang:1.4-cross
RUN apt-get update && apt-get -y install iptables
RUN go get github.com/tools/godep \
github.com/golang/lint/golint \
golang.org/x/tools/cmd/vet \
golang.org/x/tools/cmd/goimports \
golang.org/x/tools/cmd/cover\
github.com/mattn/goveralls

View File

@ -1,33 +1,20 @@
.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 .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
SHELL=/bin/bash SHELL=/bin/bash
build_image=libnetworkbuild build_image=libnetworkbuild
dockerargs = --privileged -v $(shell pwd):/go/src/github.com/docker/libnetwork -w /go/src/github.com/docker/libnetwork dockerargs = --privileged -v $(shell pwd):/go/src/github.com/docker/libnetwork -w /go/src/github.com/docker/libnetwork
container_env = -e "INSIDECONTAINER=-incontainer=true" container_env = -e "INSIDECONTAINER=-incontainer=true"
docker = docker run --rm -it ${dockerargs} ${container_env} ${build_image} docker = docker run --rm -it ${dockerargs} $$EXTRA_ARGS ${container_env} ${build_image}
ciargs = -e "COVERALLS_TOKEN=$$COVERALLS_TOKEN" -e "INSIDECONTAINER=-incontainer=true" ciargs = -e "COVERALLS_TOKEN=$$COVERALLS_TOKEN" -e "INSIDECONTAINER=-incontainer=true"
cidocker = docker run ${ciargs} ${dockerargs} golang:1.4 cidocker = docker run ${dockerargs} ${ciargs} ${container_env} ${build_image}
CROSS_PLATFORMS = linux/amd64 linux/386 linux/arm windows/amd64 windows/386
${build_image}.created:
docker build -f Dockerfile.build -t ${build_image} .
touch ${build_image}.created
all: ${build_image}.created build check integration-tests clean all: ${build_image}.created build check integration-tests clean
integration-tests: ./cmd/dnet/dnet all-local: build-local check-local integration-tests-local clean
@./test/integration/dnet/run-integration-tests.sh
./cmd/dnet/dnet:
make build
clean:
@if [ -e ./cmd/dnet/dnet ]; then \
echo "Removing dnet binary"; \
rm -rf ./cmd/dnet/dnet; \
fi
all-local: check-local build-local
${build_image}.created:
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
docker commit libnetworkbuild ${build_image}
docker rm libnetworkbuild
touch ${build_image}.created
build: ${build_image}.created build: ${build_image}.created
@echo "Building code... " @echo "Building code... "
@ -35,8 +22,25 @@ build: ${build_image}.created
@echo "Done building code" @echo "Done building code"
build-local: build-local:
@$(shell which godep) go build ./... @mkdir -p "bin"
@$(shell which godep) go build -o ./cmd/dnet/dnet ./cmd/dnet $(shell which godep) go build -o "bin/dnet" ./cmd/dnet
clean:
@if [ -d bin ]; then \
echo "Removing dnet binaries"; \
rm -rf bin; \
fi
cross: ${build_image}.created
@mkdir -p "bin"
@for platform in ${CROSS_PLATFORMS}; do \
EXTRA_ARGS="-e GOOS=$${platform%/*} -e GOARCH=$${platform##*/}" ; \
echo "$${platform}..." ; \
${docker} make cross-local ; \
done
cross-local:
$(shell which godep) go build -o "bin/dnet-$$GOOS-$$GOARCH" ./cmd/dnet
check: ${build_image}.created check: ${build_image}.created
@${docker} ./wrapmake.sh check-local @${docker} ./wrapmake.sh check-local
@ -71,27 +75,31 @@ run-tests:
done done
@echo "Done running tests" @echo "Done running tests"
check-local: check-format check-code start-services run-tests check-local: check-format check-code run-tests
install-deps: integration-tests: ./bin/dnet
apt-get update && apt-get -y install iptables zookeeperd @./test/integration/dnet/run-integration-tests.sh
git clone https://github.com/golang/tools /go/src/golang.org/x/tools
go install golang.org/x/tools/cmd/vet ./bin/dnet:
go install golang.org/x/tools/cmd/goimports make build
go install golang.org/x/tools/cmd/cover
go get github.com/tools/godep
go get github.com/golang/lint/golint
go get github.com/mattn/goveralls
coveralls: coveralls:
-@goveralls -service circleci -coverprofile=coverage.coverprofile -repotoken $$COVERALLS_TOKEN -@goveralls -service circleci -coverprofile=coverage.coverprofile -repotoken $$COVERALLS_TOKEN
# CircleCI's Docker fails when cleaning up using the --rm flag # CircleCI's Docker fails when cleaning up using the --rm flag
# The following target is a workaround for this # The following targets are a workaround for this
circle-ci-cross: ${build_image}.created
@mkdir -p "bin"
@for platform in ${CROSS_PLATFORMS}; do \
EXTRA_ARGS="-e GOOS=$${platform%/*} -e GOARCH=$${platform##*/}" ; \
echo "$${platform}..." ; \
${cidocker} make cross-local ; \
done
circle-ci: circle-ci-check: ${build_image}.created
@${cidocker} make install-deps build-local check-local coveralls @${cidocker} make check-local coveralls
make integration-tests
start-services: circle-ci-build: ${build_image}.created
service zookeeper start @${cidocker} make build-local
circle-ci: circle-ci-check circle-ci-build integration-tests

View File

@ -1,12 +1,18 @@
machine: machine:
services: services:
- docker - docker
dependencies: dependencies:
override: override:
- echo "Nothing to install" - sudo apt-get update; sudo apt-get install -y iptables zookeeperd
- go get golang.org/x/tools/cmd/vet
- go get golang.org/x/tools/cmd/goimports
- go get golang.org/x/tools/cmd/cover
- go get github.com/tools/godep
- go get github.com/golang/lint/golint
- go get github.com/mattn/goveralls
test: test:
override: override:
- make circle-ci - make circle-ci

View File

@ -9,10 +9,8 @@ import (
"fmt" "fmt"
"io" "io"
"net" "net"
"strings"
"github.com/docker/libnetwork/types" "github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink"
) )
var ( var (
@ -22,8 +20,6 @@ var (
ErrNetworkOverlaps = errors.New("requested network overlaps with existing network") ErrNetworkOverlaps = errors.New("requested network overlaps with existing network")
// ErrNoDefaultRoute preformatted error // ErrNoDefaultRoute preformatted error
ErrNoDefaultRoute = errors.New("no default route") ErrNoDefaultRoute = errors.New("no default route")
networkGetRoutesFct = netlink.RouteList
) )
// CheckNameserverOverlaps checks whether the passed network overlaps with any of the nameservers // CheckNameserverOverlaps checks whether the passed network overlaps with any of the nameservers
@ -42,21 +38,6 @@ func CheckNameserverOverlaps(nameservers []string, toCheck *net.IPNet) error {
return nil return nil
} }
// CheckRouteOverlaps checks whether the passed network overlaps with any existing routes
func CheckRouteOverlaps(toCheck *net.IPNet) error {
networks, err := networkGetRoutesFct(nil, netlink.FAMILY_V4)
if err != nil {
return err
}
for _, network := range networks {
if network.Dst != nil && NetworkOverlaps(toCheck, network.Dst) {
return ErrNetworkOverlaps
}
}
return nil
}
// NetworkOverlaps detects overlap between one IPNet and another // NetworkOverlaps detects overlap between one IPNet and another
func NetworkOverlaps(netX *net.IPNet, netY *net.IPNet) bool { func NetworkOverlaps(netX *net.IPNet, netY *net.IPNet) bool {
return netX.Contains(netY.IP) || netY.Contains(netX.IP) return netX.Contains(netY.IP) || netY.Contains(netX.IP)
@ -151,22 +132,3 @@ func GenerateRandomName(prefix string, size int) (string, error) {
} }
return prefix + hex.EncodeToString(id)[:size], nil return prefix + hex.EncodeToString(id)[:size], nil
} }
// GenerateIfaceName returns an interface name using the passed in
// prefix and the length of random bytes. The api ensures that the
// there are is no interface which exists with that name.
func GenerateIfaceName(prefix string, len int) (string, error) {
for i := 0; i < 3; i++ {
name, err := GenerateRandomName(prefix, len)
if err != nil {
continue
}
if _, err := netlink.LinkByName(name); err != nil {
if strings.Contains(err.Error(), "not found") {
return name, nil
}
return "", err
}
}
return "", types.InternalErrorf("could not generate interface name")
}

50
netutils/utils_linux.go Normal file
View File

@ -0,0 +1,50 @@
// +build linux
// Network utility functions.
package netutils
import (
"net"
"strings"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink"
)
var (
networkGetRoutesFct = netlink.RouteList
)
// CheckRouteOverlaps checks whether the passed network overlaps with any existing routes
func CheckRouteOverlaps(toCheck *net.IPNet) error {
networks, err := networkGetRoutesFct(nil, netlink.FAMILY_V4)
if err != nil {
return err
}
for _, network := range networks {
if network.Dst != nil && NetworkOverlaps(toCheck, network.Dst) {
return ErrNetworkOverlaps
}
}
return nil
}
// GenerateIfaceName returns an interface name using the passed in
// prefix and the length of random bytes. The api ensures that the
// there are is no interface which exists with that name.
func GenerateIfaceName(prefix string, len int) (string, error) {
for i := 0; i < 3; i++ {
name, err := GenerateRandomName(prefix, len)
if err != nil {
continue
}
if _, err := netlink.LinkByName(name); err != nil {
if strings.Contains(err.Error(), "not found") {
return name, nil
}
return "", err
}
}
return "", types.InternalErrorf("could not generate interface name")
}

View File

@ -21,10 +21,10 @@ load helpers
run dnet_cmd 8080 network ls run dnet_cmd 8080 network ls
echo ${output} echo ${output}
[ "$status" -ne 0 ] [ "$status" -ne 0 ]
run ./cmd/dnet/dnet -H=unix://var/run/dnet.sock network ls run ./bin/dnet -H=unix://var/run/dnet.sock network ls
echo ${output} echo ${output}
[ "$status" -ne 0 ] [ "$status" -ne 0 ]
run ./cmd/dnet/dnet -H= -l=invalid network ls run ./bin/dnet -H= -l=invalid network ls
echo ${output} echo ${output}
[ "$status" -ne 0 ] [ "$status" -ne 0 ]
stop_dnet 1 c stop_dnet 1 c

View File

@ -73,7 +73,7 @@ function wait_for_dnet() {
echo "waiting on dnet to come up ..." echo "waiting on dnet to come up ..."
for i in `seq 1 10`; for i in `seq 1 10`;
do do
hrun ./cmd/dnet/dnet -H tcp://127.0.0.1:${hport} network ls hrun ./bin/dnet -H tcp://127.0.0.1:${hport} network ls
echo ${output} echo ${output}
if [ "$status" -eq 0 ]; then if [ "$status" -eq 0 ]; then
return return
@ -168,7 +168,7 @@ EOF
-v $(pwd)/${TMPC_ROOT}:/scratch \ -v $(pwd)/${TMPC_ROOT}:/scratch \
-v /usr/local/bin/runc:/usr/local/bin/runc \ -v /usr/local/bin/runc:/usr/local/bin/runc \
-w /go/src/github.com/docker/libnetwork \ -w /go/src/github.com/docker/libnetwork \
mrjana/golang ./cmd/dnet/dnet -d -D ${hopt} -c ${tomlfile} mrjana/golang ./bin/dnet -d -D ${hopt} -c ${tomlfile}
wait_for_dnet $(inst_id2port ${inst}) ${name} wait_for_dnet $(inst_id2port ${inst}) ${name}
} }
@ -196,7 +196,7 @@ function dnet_cmd() {
hport=$1 hport=$1
shift shift
./cmd/dnet/dnet -H tcp://127.0.0.1:${hport} $* ./bin/dnet -H tcp://127.0.0.1:${hport} $*
} }
function dnet_exec() { function dnet_exec() {