From b184b3f0e10bed32728ee28e80e61b6aa9d4e952 Mon Sep 17 00:00:00 2001 From: Justin Cormack Date: Fri, 13 Jan 2017 15:39:57 +0000 Subject: [PATCH] Compile Go code with docker run not docker build Go code is really fast to compile so we do not really need to use the cache features of `docker build`. So make a compile container instead. This can also output a build context and Dockerfile if you want to do a build. For reference, an uncached `docker build` of our Go code takes about 7s, a cached one 1.2s, and this takes 1.7s, so the best case is a little worse, but we save a lot of images, and the worst case is better. This is mainly designed to make the nested builds for containerd containers simpler too. Will add a variant for the C code as well. Also add `-static` to the flags so we always make static executables, which was omitted previously. Signed-off-by: Justin Cormack --- alpine/base/go-compile/Dockerfile | 8 ++++ alpine/base/go-compile/Makefile | 29 +++++++++++++ alpine/base/go-compile/compile.sh | 59 ++++++++++++++++++++++++++ alpine/base/go-compile/lint.sh | 16 +++++++ alpine/packages/diagnostics/Dockerfile | 12 ------ alpine/packages/diagnostics/Makefile | 13 +++--- alpine/packages/proxy/Makefile | 8 ++-- alpine/packages/vsudd/Dockerfile | 12 ------ alpine/packages/vsudd/Makefile | 16 +++---- 9 files changed, 131 insertions(+), 42 deletions(-) create mode 100644 alpine/base/go-compile/Dockerfile create mode 100644 alpine/base/go-compile/Makefile create mode 100755 alpine/base/go-compile/compile.sh create mode 100755 alpine/base/go-compile/lint.sh delete mode 100644 alpine/packages/diagnostics/Dockerfile delete mode 100644 alpine/packages/vsudd/Dockerfile diff --git a/alpine/base/go-compile/Dockerfile b/alpine/base/go-compile/Dockerfile new file mode 100644 index 000000000..5e942b91e --- /dev/null +++ b/alpine/base/go-compile/Dockerfile @@ -0,0 +1,8 @@ +FROM golang:1.7-alpine +RUN apk update && apk add --no-cache build-base git + +RUN go get -u github.com/golang/lint/golint + +COPY lint.sh compile.sh /usr/bin/ + +ENTRYPOINT ["/usr/bin/compile.sh"] diff --git a/alpine/base/go-compile/Makefile b/alpine/base/go-compile/Makefile new file mode 100644 index 000000000..11cf6feac --- /dev/null +++ b/alpine/base/go-compile/Makefile @@ -0,0 +1,29 @@ +.PHONY: tag push + +BASE=golang:1.7-alpine +IMAGE=go-compile + +default: push + +hash: Dockerfile lint.sh compile.sh + DOCKER_CONTENT_TRUST=1 docker pull $(BASE) + tar cf - $^ | docker build --no-cache -t $(IMAGE):build - + docker run --rm --entrypoint=/bin/sh $(IMAGE):build -c 'cat /usr/local/go/bin/go /lib/apk/db/installed /usr/bin/lint.sh /go/bin/golint /usr/bin/compile.sh | sha1sum' | sed 's/ .*//' > hash + +push: hash + docker pull mobylinux/$(IMAGE):$(shell cat hash) || \ + (docker tag $(IMAGE):build mobylinux/$(IMAGE):$(shell cat hash) && \ + docker push mobylinux/$(IMAGE):$(shell cat hash)) + docker rmi $(IMAGE):build + rm -f hash + +tag: hash + docker pull mobylinux/$(IMAGE):$(shell cat hash) || \ + docker tag $(IMAGE):build mobylinux/$(IMAGE):$(shell cat hash) + docker rmi $(IMAGE):build + rm -f hash + +clean: + rm -f hash + +.DELETE_ON_ERROR: diff --git a/alpine/base/go-compile/compile.sh b/alpine/base/go-compile/compile.sh new file mode 100755 index 000000000..1d32f4e1a --- /dev/null +++ b/alpine/base/go-compile/compile.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +# This is designed to compile a single package to a single binary +# so it makes some assumptions about things to simplify config +# to output a single binary (in a tarball) just use -o file +# use --docker to output a tarball for input to docker build - + +set -e + +usage() { + echo "Usage: -o file [--docker]" + exit 1 +} + +[ $# = 0 ] && usage + +while [ $# -gt 1 ] +do + flag="$1" + case "$flag" in + -o) + out="$2" + mkdir -p "$(dirname $2)" + shift + ;; + *) + echo "Unknown option $1" + exit 1 + esac + shift +done + +[ $# -gt 0 ] && [ $1 = "--docker" ] && DOCKER=1 && shift + +[ $# -gt 0 ] && usage +[ -z "$out" ] && usage + +package=$(basename "$out") + +dir="$GOPATH/src/$package" + +mkdir -p $dir + +# untar input +tar xf - -C $dir + +/usr/bin/lint.sh $dir + +go build -o $out --ldflags '-extldflags "-fno-PIC -static"' "$package" + +if [ -z "$DOCKER" ] +then + tar cf - $out + exit 0 +fi + +printf "FROM scratch\nCOPY $out $out\nENTRYPOINT [\"$out\"]\n" > Dockerfile + +tar cf - Dockerfile $out diff --git a/alpine/base/go-compile/lint.sh b/alpine/base/go-compile/lint.sh new file mode 100755 index 000000000..669a41496 --- /dev/null +++ b/alpine/base/go-compile/lint.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +set -e + +cd $1 + +>&2 echo "gofmt..." +test -z $(gofmt -s -l .| grep -v .pb. | grep -v */vendor/ | tee /dev/stderr) + +>&2 echo "govet..." +test -z $(go tool vet -printf=false . 2>&1 | grep -v */vendor/ | tee /dev/stderr) + +>&2 echo "golint..." +test -z $(find . -type f -name "*.go" -not -path "*/vendor/*" -not -name "*.pb.*" -exec golint {} \; | tee /dev/stderr) + +>&2 echo "Successful lint check!" \ No newline at end of file diff --git a/alpine/packages/diagnostics/Dockerfile b/alpine/packages/diagnostics/Dockerfile deleted file mode 100644 index 81cff8243..000000000 --- a/alpine/packages/diagnostics/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -# Tag: 2c9434f1c4ff70b102f34a97d2df1a8363a11a65 -FROM mobylinux/alpine-build-go@sha256:d528bbf7102e4209bd59ef030d41de9003ab8e42c303956f62b2df47f3e17849 - -COPY ./ /go/src/diagnostics-server/ - -WORKDIR /go/src/diagnostics-server - -RUN lint.sh . - -RUN go install --ldflags '-extldflags "-fno-PIC"' - -CMD ["tar", "cf", "-", "-C", "/go/bin", "diagnostics-server"] diff --git a/alpine/packages/diagnostics/Makefile b/alpine/packages/diagnostics/Makefile index 541c19900..b3f6858b4 100644 --- a/alpine/packages/diagnostics/Makefile +++ b/alpine/packages/diagnostics/Makefile @@ -1,12 +1,13 @@ -all: usr/bin/diagnostics-server +# Tag: 470f68ec32e016484fb8e0bcc2f06cd3f201ea68 +GO_COMPILE=mobylinux/go-compile@sha256:b723c0e95a6293300392e57d6ab52574f9217e2410b390a24cbfc4f9070edb6b -DEPS=Dockerfile $(wildcard *.go) +default: usr/bin/diagnostics-server + +DEPS=$(wildcard *.go) usr/bin/diagnostics-server: $(DEPS) ../vendor/manifest - BUILD=$$( tar cf - $(DEPS) -C .. vendor | docker build -q - ) && \ - [ -n "$$BUILD" ] && \ - echo "Built $$BUILD" && \ - docker run --rm --net=none $$BUILD | tar xf - -C usr/bin + mkdir -p $(dir $@) + tar cf - $(DEPS) -C .. vendor | docker run --rm --net=none --log-driver=none -i $(GO_COMPILE) -o $@ | tar xf - clean: rm -f usr/bin/diagnostics-server diff --git a/alpine/packages/proxy/Makefile b/alpine/packages/proxy/Makefile index 964b08a6d..5db3a144d 100644 --- a/alpine/packages/proxy/Makefile +++ b/alpine/packages/proxy/Makefile @@ -1,12 +1,12 @@ +# Tag: 470f68ec32e016484fb8e0bcc2f06cd3f201ea68 +GO_COMPILE=mobylinux/go-compile@sha256:b723c0e95a6293300392e57d6ab52574f9217e2410b390a24cbfc4f9070edb6b + all: usr/bin/slirp-proxy sbin/proxy-vsockd DEPS=Dockerfile $(wildcard *.go libproxy/*.go) proxy: $(DEPS) ../vendor/manifest - BUILD=$$( tar cf - $(DEPS) -C .. vendor | docker build -q - ) && \ - [ -n "$$BUILD" ] && \ - echo "Built $$BUILD" && \ - docker run --rm --net=none $$BUILD | tar xf - + tar cf - $(DEPS) -C .. vendor | docker run --rm --net=none --log-driver=none -i $(GO_COMPILE) -o $@ | tar xf - usr/bin/slirp-proxy: proxy mkdir -p usr/bin diff --git a/alpine/packages/vsudd/Dockerfile b/alpine/packages/vsudd/Dockerfile deleted file mode 100644 index 7ac82c375..000000000 --- a/alpine/packages/vsudd/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -# Tag: 2c9434f1c4ff70b102f34a97d2df1a8363a11a65 -FROM mobylinux/alpine-build-go@sha256:d528bbf7102e4209bd59ef030d41de9003ab8e42c303956f62b2df47f3e17849 - -COPY ./ /go/src/vsudd/ - -WORKDIR /go/src/vsudd - -RUN lint.sh . - -RUN go install --ldflags '-extldflags "-fno-PIC"' - -CMD ["tar", "cf", "-", "-C", "/go/bin", "vsudd"] diff --git a/alpine/packages/vsudd/Makefile b/alpine/packages/vsudd/Makefile index ec5aec1a8..d976e289c 100644 --- a/alpine/packages/vsudd/Makefile +++ b/alpine/packages/vsudd/Makefile @@ -1,13 +1,13 @@ -all: vsudd +# Tag: 470f68ec32e016484fb8e0bcc2f06cd3f201ea68 +GO_COMPILE=mobylinux/go-compile@sha256:b723c0e95a6293300392e57d6ab52574f9217e2410b390a24cbfc4f9070edb6b -DEPS=Dockerfile $(wildcard *.go) +default: sbin/vsudd -vsudd: $(DEPS) ../vendor/manifest - mkdir -p sbin - BUILD=$$( tar cf - $(DEPS) -C .. vendor | docker build -q - ) && \ - [ -n "$$BUILD" ] && \ - echo "Built $$BUILD" && \ - docker run --rm --net=none $$BUILD | tar xf - -C sbin +DEPS=$(wildcard *.go) + +sbin/vsudd: $(DEPS) ../vendor/manifest + mkdir -p $(dir $@) + tar cf - $(DEPS) -C .. vendor | docker run --rm --net=none --log-driver=none -i $(GO_COMPILE) -o $@ | tar xf - clean: rm -rf sbin