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
*.a
*.so
bin/
# Folders
integration-tmp/
@ -33,4 +34,4 @@ cmd/dnet/dnet
.project
.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
build_image=libnetworkbuild
dockerargs = --privileged -v $(shell pwd):/go/src/github.com/docker/libnetwork -w /go/src/github.com/docker/libnetwork
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"
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
integration-tests: ./cmd/dnet/dnet
@./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
all-local: build-local check-local integration-tests-local clean
build: ${build_image}.created
@echo "Building code... "
@ -35,8 +22,25 @@ build: ${build_image}.created
@echo "Done building code"
build-local:
@$(shell which godep) go build ./...
@$(shell which godep) go build -o ./cmd/dnet/dnet ./cmd/dnet
@mkdir -p "bin"
$(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
@${docker} ./wrapmake.sh check-local
@ -71,27 +75,31 @@ run-tests:
done
@echo "Done running tests"
check-local: check-format check-code start-services run-tests
check-local: check-format check-code run-tests
install-deps:
apt-get update && apt-get -y install iptables zookeeperd
git clone https://github.com/golang/tools /go/src/golang.org/x/tools
go install golang.org/x/tools/cmd/vet
go install golang.org/x/tools/cmd/goimports
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
integration-tests: ./bin/dnet
@./test/integration/dnet/run-integration-tests.sh
./bin/dnet:
make build
coveralls:
-@goveralls -service circleci -coverprofile=coverage.coverprofile -repotoken $$COVERALLS_TOKEN
# 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:
@${cidocker} make install-deps build-local check-local coveralls
make integration-tests
circle-ci-check: ${build_image}.created
@${cidocker} make check-local coveralls
start-services:
service zookeeper start
circle-ci-build: ${build_image}.created
@${cidocker} make build-local
circle-ci: circle-ci-check circle-ci-build integration-tests

View File

@ -1,12 +1,18 @@
machine:
services:
- docker
services:
- docker
dependencies:
override:
- echo "Nothing to install"
override:
- 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:
override:
- make circle-ci
override:
- make circle-ci

View File

@ -9,10 +9,8 @@ import (
"fmt"
"io"
"net"
"strings"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink"
)
var (
@ -22,8 +20,6 @@ var (
ErrNetworkOverlaps = errors.New("requested network overlaps with existing network")
// ErrNoDefaultRoute preformatted error
ErrNoDefaultRoute = errors.New("no default route")
networkGetRoutesFct = netlink.RouteList
)
// 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
}
// 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
func NetworkOverlaps(netX *net.IPNet, netY *net.IPNet) bool {
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
}
// 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
echo ${output}
[ "$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}
[ "$status" -ne 0 ]
run ./cmd/dnet/dnet -H= -l=invalid network ls
run ./bin/dnet -H= -l=invalid network ls
echo ${output}
[ "$status" -ne 0 ]
stop_dnet 1 c

View File

@ -73,7 +73,7 @@ function wait_for_dnet() {
echo "waiting on dnet to come up ..."
for i in `seq 1 10`;
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}
if [ "$status" -eq 0 ]; then
return
@ -168,7 +168,7 @@ EOF
-v $(pwd)/${TMPC_ROOT}:/scratch \
-v /usr/local/bin/runc:/usr/local/bin/runc \
-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}
}
@ -196,7 +196,7 @@ function dnet_cmd() {
hport=$1
shift
./cmd/dnet/dnet -H tcp://127.0.0.1:${hport} $*
./bin/dnet -H tcp://127.0.0.1:${hport} $*
}
function dnet_exec() {