Add initial support for Docker on ARM

Signed-off-by: Govinda Fichtner <govinda.fichtner@googlemail.com>
This commit is contained in:
Govinda Fichtner 2015-11-05 15:38:41 +01:00
parent 343c8547df
commit b74fd0628a
6 changed files with 275 additions and 5 deletions

42
ARM.md Normal file
View file

@ -0,0 +1,42 @@
# ARM support
The ARM support should be considered experimental. It will be extended step by step in the coming weeks.
Building a Docker Development Image works in the same fashion as for Intel platform (x86-64).
Currently we have initial support for 32bit ARMv7 devices.
To work with the Docker Development Image you have to clone the Docker/Docker repo on a supported device.
It needs to have a Docker Engine installed to build the Docker Development Image.
From the root of the Docker/Docker repo one can use make to execute the following make targets:
- make validate
- make binary
- make build
- make bundles
- make default
- make shell
- make
The Makefile does include logic to determine on which OS and architecture the Docker Development Image is built.
Based on OS and architecture it chooses the correct Dockerfile.
For the ARM 32bit architecture it uses `Dockerfile.arm`.
So for example in order to build a Docker binary one has to
1. clone the Docker/Docker repository on an ARM device `git clone git@github.com:docker/docker.git`
2. change into the checked out repository with `cd docker`
3. execute `make binary` to create a Docker Engine binary for ARM
# Supported devices
## Scaleway Server C1
A Scaleway C1 server can be easily purchased on demand on the Scaleway website:
https://www.scaleway.com
It is a cheap and fast way to get access to a pysical ARM server.
It features a 4-cores ARMv7 CPU with 2GB of RAM and a 1 Gbit/s network card.
Scaleway servers can be started we prepared images from their image hub.
The best image to build a Docker Development Image is:
https://www.scaleway.com/imagehub/docker/

188
Dockerfile.arm Normal file
View file

@ -0,0 +1,188 @@
# This file describes the standard way to build Docker on ARM, using docker
#
# Usage:
#
# # Assemble the full dev environment. This is slow the first time.
# docker build -t docker -f Dockerfile.arm .
#
# # Mount your source in an interactive container for quick testing:
# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash
#
# # Run the test suite:
# docker run --privileged docker hack/make.sh test
#
# # Publish a release:
# docker run --privileged \
# -e AWS_S3_BUCKET=baz \
# -e AWS_ACCESS_KEY=foo \
# -e AWS_SECRET_KEY=bar \
# -e GPG_PASSPHRASE=gloubiboulga \
# docker hack/release.sh
#
# Note: AppArmor used to mess with privileged mode, but this is no longer
# the case. Therefore, you don't have to disable it anymore.
#
FROM ioft/armhf-ubuntu:14.04
MAINTAINER Govinda Fichtner <govinda.fichtner@googlemail.com> (@_beagile_)
# Packaged dependencies
RUN apt-get update && apt-get install -y \
apparmor \
aufs-tools \
automake \
bash-completion \
btrfs-tools \
build-essential \
createrepo \
curl \
dpkg-sig \
git \
iptables \
libapparmor-dev \
libcap-dev \
libsqlite3-dev \
libsystemd-journal-dev \
mercurial \
parallel \
pkg-config \
python-mock \
python-pip \
python-websocket \
s3cmd=1.1.0* \
--no-install-recommends
# Get lvm2 source for compiling statically
RUN git clone -b v2_02_103 https://git.fedorahosted.org/git/lvm2.git /usr/local/lvm2
# see https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags
# Compile and install lvm2
RUN cd /usr/local/lvm2 \
&& ./configure --enable-static_link \
&& make device-mapper \
&& make install_device-mapper
# see https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
# Install Go
ENV GO_VERSION 1.4.3
RUN curl -sSL https://golang.org/dl/go${GO_VERSION}.src.tar.gz | tar -v -C /usr/local -xz \
&& mkdir -p /go/bin
ENV PATH /go/bin:/usr/local/go/bin:$PATH
ENV GOPATH /go:/go/src/github.com/docker/docker/vendor
# (set an explicit GOARM of 5 for maximum compatibility)
ENV GOARM 5
RUN cd /usr/local/go/src && ./make.bash --no-clean 2>&1
# Compile Go for cross compilation
ENV DOCKER_CROSSPLATFORMS " "
# This has been commented out and kept as reference because we don't support compiling with older Go anymore.
# ENV GOFMT_VERSION 1.3.3
# RUN curl -sSL https://storage.googleapis.com/golang/go${GOFMT_VERSION}.$(go env GOOS)-$(go env GOARCH).tar.gz | tar -C /go/bin -xz --strip-components=2 go/bin/gofmt
# Update this sha when we upgrade to go 1.5.0
ENV GO_TOOLS_COMMIT 069d2f3bcb68257b627205f0486d6cc69a231ff9
# Grab Go's cover tool for dead-simple code coverage testing
# Grab Go's vet tool for examining go code to find suspicious constructs
# and help prevent errors that the compiler might not catch
RUN git clone https://github.com/golang/tools.git /go/src/golang.org/x/tools \
&& (cd /go/src/golang.org/x/tools && git checkout -q $GO_TOOLS_COMMIT) \
&& go install -v golang.org/x/tools/cmd/cover \
&& go install -v golang.org/x/tools/cmd/vet
# Grab Go's lint tool
ENV GO_LINT_COMMIT f42f5c1c440621302702cb0741e9d2ca547ae80f
RUN git clone https://github.com/golang/lint.git /go/src/github.com/golang/lint \
&& (cd /go/src/github.com/golang/lint && git checkout -q $GO_LINT_COMMIT) \
&& go install -v github.com/golang/lint/golint
# Install registry
ENV REGISTRY_COMMIT ec87e9b6971d831f0eff752ddb54fb64693e51cd
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/docker/distribution.git "$GOPATH/src/github.com/docker/distribution" \
&& (cd "$GOPATH/src/github.com/docker/distribution" && git checkout -q "$REGISTRY_COMMIT") \
&& GOPATH="$GOPATH/src/github.com/docker/distribution/Godeps/_workspace:$GOPATH" \
go build -o /usr/local/bin/registry-v2 github.com/docker/distribution/cmd/registry \
&& rm -rf "$GOPATH"
# Install notary server
# commented Notary temporary as we are waiting for an update of jose2go: https://github.com/docker/notary/issues/239
#
# ENV NOTARY_COMMIT 8e8122eb5528f621afcd4e2854c47302f17392f7
# RUN set -x \
# && export GOPATH="$(mktemp -d)" \
# && git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \
# && (cd "$GOPATH/src/github.com/docker/notary" && git checkout -q "$NOTARY_COMMIT") \
# && GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH" \
# go build -o /usr/local/bin/notary-server github.com/docker/notary/cmd/notary-server \
# && rm -rf "$GOPATH"
# Get the "docker-py" source so we can run their integration tests
ENV DOCKER_PY_COMMIT 139850f3f3b17357bab5ba3edfb745fb14043764
RUN git clone https://github.com/docker/docker-py.git /docker-py \
&& cd /docker-py \
&& git checkout -q $DOCKER_PY_COMMIT
# Setup s3cmd config
RUN { \
echo '[default]'; \
echo 'access_key=$AWS_ACCESS_KEY'; \
echo 'secret_key=$AWS_SECRET_KEY'; \
} > ~/.s3cfg
# Set user.email so crosbymichael's in-container merge commits go smoothly
RUN git config --global user.email 'docker-dummy@example.com'
# Add an unprivileged user to be used for tests which need it
RUN groupadd -r docker
RUN useradd --create-home --gid docker unprivilegeduser
VOLUME /var/lib/docker
WORKDIR /go/src/github.com/docker/docker
ENV DOCKER_BUILDTAGS apparmor selinux
# Let us use a .bashrc file
RUN ln -sfv $PWD/.bashrc ~/.bashrc
# Register Docker's bash completion.
RUN ln -sv $PWD/contrib/completion/bash/docker /etc/bash_completion.d/docker
# Get useful and necessary Hub images so we can "docker load" locally instead of pulling
COPY contrib/download-frozen-image.sh /go/src/github.com/docker/docker/contrib/
RUN ./contrib/download-frozen-image.sh /docker-frozen-images \
hypriot/armhf-busybox@ea0800bb83571c585c5652b53668e76b29c7c0eef719892f9d0a48607984f9e1 \
hypriot/armhf-hello-world@508c59a4f8b23c77bbcf43296c3f580873dc7eecb1f0d680cea3067e221fd4c2 \
hypriot/armhf-unshare@3f1db65f8bbabc743fd739cf7145a56c35b2a0979ae3174e9d79b7fa4b00fca1
# see also "hack/make/.ensure-frozen-images" (which needs to be updated any time this list is)
# Download man page generator
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone -b v1.0.3 https://github.com/cpuguy83/go-md2man.git "$GOPATH/src/github.com/cpuguy83/go-md2man" \
&& git clone -b v1.2 https://github.com/russross/blackfriday.git "$GOPATH/src/github.com/russross/blackfriday" \
&& go get -v -d github.com/cpuguy83/go-md2man \
&& go build -v -o /usr/local/bin/go-md2man github.com/cpuguy83/go-md2man \
&& rm -rf "$GOPATH"
# Download toml validator
ENV TOMLV_COMMIT 9baf8a8a9f2ed20a8e54160840c492f937eeaf9a
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/BurntSushi/toml.git "$GOPATH/src/github.com/BurntSushi/toml" \
&& (cd "$GOPATH/src/github.com/BurntSushi/toml" && git checkout -q "$TOMLV_COMMIT") \
&& go build -v -o /usr/local/bin/tomlv github.com/BurntSushi/toml/cmd/tomlv \
&& rm -rf "$GOPATH"
# Build/install the tool for embedding resources in Windows binaries
ENV RSRC_COMMIT e48dbf1b7fc464a9e85fcec450dddf80816b76e0
RUN set -x \
&& git clone https://github.com/akavel/rsrc.git /go/src/github.com/akavel/rsrc \
&& cd /go/src/github.com/akavel/rsrc \
&& git checkout -q $RSRC_COMMIT \
&& go install -v
# Wrap all commands in the "docker-in-docker" script to allow nested containers
ENTRYPOINT ["hack/dind"]
# Upload docker source
COPY . /go/src/github.com/docker/docker

View file

@ -1,5 +1,20 @@
.PHONY: all binary build cross default docs docs-build docs-shell shell test test-unit test-integration-cli test-docker-py validate .PHONY: all binary build cross default docs docs-build docs-shell shell test test-unit test-integration-cli test-docker-py validate
# get OS/Arch of docker engine
DOCKER_ENGINE_OSARCH = $(shell docker version | grep 'OS/Arch' | tail -1 | cut -d':' -f2 | tr -d '[[:space:]]')
DOCKER_ENGINE_GOOS = $(word 1, $(subst /, ,$(DOCKER_ENGINE_OSARCH)))
DOCKER_ENGINE_GOARCH = $(word 2, $(subst /, ,$(DOCKER_ENGINE_OSARCH)))
export DOCKER_ENGINE_OSARCH
export DOCKER_ENGINE_GOOS
export DOCKER_ENGINE_GOARCH
# default for linux/amd64 and others
DOCKER_FILE = Dockerfile
# switch to different Dockerfile for linux/arm
ifeq ($(DOCKER_ENGINE_OSARCH),linux/arm)
DOCKER_FILE = Dockerfile.arm
endif
export DOCKER_FILE
# env vars passed through directly to Docker's build scripts # env vars passed through directly to Docker's build scripts
# to allow things like `make DOCKER_CLIENTONLY=1 binary` easily # to allow things like `make DOCKER_CLIENTONLY=1 binary` easily
# `docs/sources/contributing/devenvironment.md ` and `project/PACKAGERS.md` have some limited documentation of some of these # `docs/sources/contributing/devenvironment.md ` and `project/PACKAGERS.md` have some limited documentation of some of these
@ -13,6 +28,10 @@ DOCKER_ENVS := \
-e DOCKER_GRAPHDRIVER \ -e DOCKER_GRAPHDRIVER \
-e DOCKER_STORAGE_OPTS \ -e DOCKER_STORAGE_OPTS \
-e DOCKER_USERLANDPROXY \ -e DOCKER_USERLANDPROXY \
-e DOCKER_ENGINE_OSARCH \
-e DOCKER_ENGINE_GOOS \
-e DOCKER_ENGINE_GOARCH \
-e DOCKER_FILE \
-e TESTDIRS \ -e TESTDIRS \
-e TESTFLAGS \ -e TESTFLAGS \
-e TIMEOUT -e TIMEOUT
@ -77,7 +96,7 @@ shell: build
$(DOCKER_RUN_DOCKER) bash $(DOCKER_RUN_DOCKER) bash
build: bundles build: bundles
docker build -t "$(DOCKER_IMAGE)" . docker build -t "$(DOCKER_IMAGE)" -f $(DOCKER_FILE) .
bundles: bundles:
mkdir bundles mkdir bundles

View file

@ -62,7 +62,7 @@ _dockerfile_env() {
print; print;
exit; exit;
} }
' Dockerfile ' ${DOCKER_FILE:="Dockerfile"}
} }
clean() { clean() {
@ -71,7 +71,7 @@ clean() {
"${PROJECT}/dockerinit" # package main "${PROJECT}/dockerinit" # package main
"${PROJECT}/integration-cli" # external tests "${PROJECT}/integration-cli" # external tests
) )
local dockerPlatforms=( linux/amd64 $(_dockerfile_env DOCKER_CROSSPLATFORMS) ) local dockerPlatforms=( ${DOCKER_ENGINE_OSARCH:="linux/amd64"} $(_dockerfile_env DOCKER_CROSSPLATFORMS) )
local dockerBuildTags="$(_dockerfile_env DOCKER_BUILDTAGS)" local dockerBuildTags="$(_dockerfile_env DOCKER_BUILDTAGS)"
local buildTagCombos=( local buildTagCombos=(
'' ''

View file

@ -8,6 +8,15 @@ images=(
jess/unshare:latest jess/unshare:latest
) )
# on ARM we need images that work for the ARM architecture
if [ -v DOCKER_ENGINE_OSARCH ] && [ "$DOCKER_ENGINE_OSARCH" = "linux/arm" ]; then
images=(
hypriot/armhf-busybox@ea0800bb83571c585c5652b53668e76b29c7c0eef719892f9d0a48607984f9e1
hypriot/armhf-hello-world@508c59a4f8b23c77bbcf43296c3f580873dc7eecb1f0d680cea3067e221fd4c2
hypriot/armhf-unshare@3f1db65f8bbabc743fd739cf7145a56c35b2a0979ae3174e9d79b7fa4b00fca1
)
fi
if ! docker inspect "${images[@]}" &> /dev/null; then if ! docker inspect "${images[@]}" &> /dev/null; then
hardCodedDir='/docker-frozen-images' hardCodedDir='/docker-frozen-images'
if [ -d "$hardCodedDir" ]; then if [ -d "$hardCodedDir" ]; then
@ -32,7 +41,19 @@ if ! docker inspect "${images[@]}" &> /dev/null; then
inCont = 0; inCont = 0;
} }
} }
' Dockerfile | sh -x ' ${DOCKER_FILE:="Dockerfile"} | sh -x
( set -x; tar -cC "$dir" . | docker load ) ( set -x; tar -cC "$dir" . | docker load )
fi fi
fi fi
if [ -v DOCKER_ENGINE_OSARCH ] && [ "$DOCKER_ENGINE_OSARCH" = "linux/arm" ]; then
# tag images to ensure that all integrations work with the defined image names
docker tag hypriot/armhf-busybox:latest busybox:latest
docker tag hypriot/armhf-hello-world:latest hello-world:frozen
docker tag hypriot/armhf-unshare:latest jess/unshare:latest
# remove orignal tags as these make problems with later tests: TestInspectApiImageResponse
docker rmi hypriot/armhf-busybox:latest
docker rmi hypriot/armhf-hello-world:latest
docker rmi hypriot/armhf-unshare:latest
fi

View file

@ -8,7 +8,7 @@ dir="$DEST/httpserver"
mkdir -p "$dir" mkdir -p "$dir"
( (
cd "$dir" cd "$dir"
GOOS=linux GOARCH=amd64 go build -o httpserver github.com/docker/docker/contrib/httpserver GOOS=${DOCKER_ENGINE_GOOS:="linux"} GOARCH=${DOCKER_ENGINE_GOARCH:="amd64"} go build -o httpserver github.com/docker/docker/contrib/httpserver
cp ../../../../contrib/httpserver/Dockerfile . cp ../../../../contrib/httpserver/Dockerfile .
docker build -qt httpserver . > /dev/null docker build -qt httpserver . > /dev/null
) )