From 07253735ad448adf751e4f9ba4c71acdb735367f Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Tue, 25 Apr 2017 13:24:19 -0700 Subject: [PATCH] Convert to templates and add some initial multi-architecture support For building on amd64, this should be 100% equivalent. What this opens up is the possibility of building these as-is on other architectures (I've tested successfully on s390x by only modifying the `FROM` of `1.8/Dockerfile` and `1.8/alpine/Dockerfile`). --- 1.7/Dockerfile | 36 +++++- 1.7/alpine/Dockerfile | 41 +++--- 1.7/alpine3.5/Dockerfile | 41 +++--- 1.7/wheezy/Dockerfile | 36 +++++- 1.7/windows/nanoserver/Dockerfile | 12 +- 1.7/windows/windowsservercore/Dockerfile | 12 +- 1.8/Dockerfile | 36 +++++- 1.8/alpine/Dockerfile | 38 +++--- 1.8/stretch/Dockerfile | 36 +++++- 1.8/windows/nanoserver/Dockerfile | 12 +- 1.8/windows/windowsservercore/Dockerfile | 12 +- Dockerfile-alpine.template | 45 +++++++ Dockerfile-debian.template | 42 ++++++ Dockerfile-windows-nanoserver.template | 43 +++++++ Dockerfile-windows-windowsservercore.template | 72 +++++++++++ update.sh | 121 +++++++++++------- 16 files changed, 490 insertions(+), 145 deletions(-) create mode 100644 Dockerfile-alpine.template create mode 100644 Dockerfile-debian.template create mode 100644 Dockerfile-windows-nanoserver.template create mode 100644 Dockerfile-windows-windowsservercore.template diff --git a/1.7/Dockerfile b/1.7/Dockerfile index 7e227c28..1647524b 100644 --- a/1.7/Dockerfile +++ b/1.7/Dockerfile @@ -10,13 +10,37 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* ENV GOLANG_VERSION 1.7.5 -ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 2e4dd6c44f0693bef4e7b46cc701513d74c3cc44f2419bf519d7868b12931ac3 -RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \ - && echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - \ - && tar -C /usr/local -xzf golang.tar.gz \ - && rm golang.tar.gz +RUN set -eux; \ + \ +# this "case" statement is generated via "update.sh" + dpkgArch="$(dpkg --print-architecture)"; \ + case "${dpkgArch##*-}" in \ + ppc64el) goRelArch='linux-ppc64le'; goRelSha256='ced737e36f2b2017b59f31cce86f50a2519245f017a81b8dce93bf986717e3ed' ;; \ + i386) goRelArch='linux-386'; goRelSha256='432cb92ae656f6fe1fa96a981782ef5948438b6da6691423aae900918b1eb955' ;; \ + s390x) goRelArch='linux-s390x'; goRelSha256='858df47609594570479ff937e3704c58e06b40e485ce29d7f934eae87b7a4450' ;; \ + armhf) goRelArch='linux-armv6l'; goRelSha256='cf93c8171dda189c226fe337e3aae11db24bd600841caab36c91d753f631aa2b' ;; \ + amd64) goRelArch='linux-amd64'; goRelSha256='2e4dd6c44f0693bef4e7b46cc701513d74c3cc44f2419bf519d7868b12931ac3' ;; \ + *) goRelArch='src'; goRelSha256='4e834513a2079f8cbbd357502cccaac9507fd00a1efe672375798858ff291815'; \ + echo >&2; echo >&2 "warning: current architecture ($dpkgArch) does not have a corresponding Go binary release; will be building from source"; echo >&2 ;; \ + esac; \ + \ + url="https://golang.org/dl/go${GOLANG_VERSION}.${goRelArch}.tar.gz"; \ + wget -O go.tgz "$url"; \ + echo "${goRelSha256} *go.tgz" | sha256sum -c -; \ + tar -C /usr/local -xzf go.tgz; \ + rm go.tgz; \ + \ + if [ "$goRelArch" = 'src' ]; then \ + echo >&2; \ + echo >&2 'error: UNIMPLEMENTED'; \ + echo >&2 'TODO install golang-any from jessie-backports for GOROOT_BOOTSTRAP (and uninstall after build)'; \ + echo >&2; \ + exit 1; \ + fi; \ + \ + export PATH="/usr/local/go/bin:$PATH"; \ + go version ENV GOPATH /go ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH diff --git a/1.7/alpine/Dockerfile b/1.7/alpine/Dockerfile index 74f03367..66c8a27c 100644 --- a/1.7/alpine/Dockerfile +++ b/1.7/alpine/Dockerfile @@ -3,35 +3,38 @@ FROM alpine:3.4 RUN apk add --no-cache ca-certificates ENV GOLANG_VERSION 1.7.5 -ENV GOLANG_SRC_URL https://golang.org/dl/go$GOLANG_VERSION.src.tar.gz -ENV GOLANG_SRC_SHA256 4e834513a2079f8cbbd357502cccaac9507fd00a1efe672375798858ff291815 -# https://golang.org/issue/14851 -COPY no-pic.patch / -# https://golang.org/issue/17847 -COPY 17847.patch / +# https://golang.org/issue/14851 (Go 1.8 & 1.7) +# https://golang.org/issue/17847 (Go 1.7) +COPY *.patch /go-alpine-patches/ -RUN set -ex \ - && apk add --no-cache --virtual .build-deps \ +RUN set -eux; \ + apk add --no-cache --virtual .build-deps \ bash \ gcc \ musl-dev \ openssl \ go \ + ; \ + export GOROOT_BOOTSTRAP="$(go env GOROOT)"; \ \ - && export GOROOT_BOOTSTRAP="$(go env GOROOT)" \ + wget -O go.tgz "https://golang.org/dl/go$GOLANG_VERSION.src.tar.gz"; \ + echo '4e834513a2079f8cbbd357502cccaac9507fd00a1efe672375798858ff291815 *go.tgz' | sha256sum -c -; \ + tar -C /usr/local -xzf go.tgz; \ + rm go.tgz; \ \ - && wget -q "$GOLANG_SRC_URL" -O golang.tar.gz \ - && echo "$GOLANG_SRC_SHA256 golang.tar.gz" | sha256sum -c - \ - && tar -C /usr/local -xzf golang.tar.gz \ - && rm golang.tar.gz \ - && cd /usr/local/go/src \ - && patch -p2 -i /no-pic.patch \ - && patch -p2 -i /17847.patch \ - && ./make.bash \ + cd /usr/local/go/src; \ + for p in /go-alpine-patches/*.patch; do \ + [ -f "$p" ] || continue; \ + patch -p2 -i "$p"; \ + done; \ + ./make.bash; \ \ - && rm -rf /*.patch \ - && apk del .build-deps + rm -rf /go-alpine-patches; \ + apk del .build-deps; \ + \ + export PATH="/usr/local/go/bin:$PATH"; \ + go version ENV GOPATH /go ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH diff --git a/1.7/alpine3.5/Dockerfile b/1.7/alpine3.5/Dockerfile index fe4bdb6a..31016da9 100644 --- a/1.7/alpine3.5/Dockerfile +++ b/1.7/alpine3.5/Dockerfile @@ -3,35 +3,38 @@ FROM alpine:3.5 RUN apk add --no-cache ca-certificates ENV GOLANG_VERSION 1.7.5 -ENV GOLANG_SRC_URL https://golang.org/dl/go$GOLANG_VERSION.src.tar.gz -ENV GOLANG_SRC_SHA256 4e834513a2079f8cbbd357502cccaac9507fd00a1efe672375798858ff291815 -# https://golang.org/issue/14851 -COPY no-pic.patch / -# https://golang.org/issue/17847 -COPY 17847.patch / +# https://golang.org/issue/14851 (Go 1.8 & 1.7) +# https://golang.org/issue/17847 (Go 1.7) +COPY *.patch /go-alpine-patches/ -RUN set -ex \ - && apk add --no-cache --virtual .build-deps \ +RUN set -eux; \ + apk add --no-cache --virtual .build-deps \ bash \ gcc \ musl-dev \ openssl \ go \ + ; \ + export GOROOT_BOOTSTRAP="$(go env GOROOT)"; \ \ - && export GOROOT_BOOTSTRAP="$(go env GOROOT)" \ + wget -O go.tgz "https://golang.org/dl/go$GOLANG_VERSION.src.tar.gz"; \ + echo '4e834513a2079f8cbbd357502cccaac9507fd00a1efe672375798858ff291815 *go.tgz' | sha256sum -c -; \ + tar -C /usr/local -xzf go.tgz; \ + rm go.tgz; \ \ - && wget -q "$GOLANG_SRC_URL" -O golang.tar.gz \ - && echo "$GOLANG_SRC_SHA256 golang.tar.gz" | sha256sum -c - \ - && tar -C /usr/local -xzf golang.tar.gz \ - && rm golang.tar.gz \ - && cd /usr/local/go/src \ - && patch -p2 -i /no-pic.patch \ - && patch -p2 -i /17847.patch \ - && ./make.bash \ + cd /usr/local/go/src; \ + for p in /go-alpine-patches/*.patch; do \ + [ -f "$p" ] || continue; \ + patch -p2 -i "$p"; \ + done; \ + ./make.bash; \ \ - && rm -rf /*.patch \ - && apk del .build-deps + rm -rf /go-alpine-patches; \ + apk del .build-deps; \ + \ + export PATH="/usr/local/go/bin:$PATH"; \ + go version ENV GOPATH /go ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH diff --git a/1.7/wheezy/Dockerfile b/1.7/wheezy/Dockerfile index 14671230..a5a1db26 100644 --- a/1.7/wheezy/Dockerfile +++ b/1.7/wheezy/Dockerfile @@ -10,13 +10,37 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* ENV GOLANG_VERSION 1.7.5 -ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 2e4dd6c44f0693bef4e7b46cc701513d74c3cc44f2419bf519d7868b12931ac3 -RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \ - && echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - \ - && tar -C /usr/local -xzf golang.tar.gz \ - && rm golang.tar.gz +RUN set -eux; \ + \ +# this "case" statement is generated via "update.sh" + dpkgArch="$(dpkg --print-architecture)"; \ + case "${dpkgArch##*-}" in \ + ppc64el) goRelArch='linux-ppc64le'; goRelSha256='ced737e36f2b2017b59f31cce86f50a2519245f017a81b8dce93bf986717e3ed' ;; \ + i386) goRelArch='linux-386'; goRelSha256='432cb92ae656f6fe1fa96a981782ef5948438b6da6691423aae900918b1eb955' ;; \ + s390x) goRelArch='linux-s390x'; goRelSha256='858df47609594570479ff937e3704c58e06b40e485ce29d7f934eae87b7a4450' ;; \ + armhf) goRelArch='linux-armv6l'; goRelSha256='cf93c8171dda189c226fe337e3aae11db24bd600841caab36c91d753f631aa2b' ;; \ + amd64) goRelArch='linux-amd64'; goRelSha256='2e4dd6c44f0693bef4e7b46cc701513d74c3cc44f2419bf519d7868b12931ac3' ;; \ + *) goRelArch='src'; goRelSha256='4e834513a2079f8cbbd357502cccaac9507fd00a1efe672375798858ff291815'; \ + echo >&2; echo >&2 "warning: current architecture ($dpkgArch) does not have a corresponding Go binary release; will be building from source"; echo >&2 ;; \ + esac; \ + \ + url="https://golang.org/dl/go${GOLANG_VERSION}.${goRelArch}.tar.gz"; \ + wget -O go.tgz "$url"; \ + echo "${goRelSha256} *go.tgz" | sha256sum -c -; \ + tar -C /usr/local -xzf go.tgz; \ + rm go.tgz; \ + \ + if [ "$goRelArch" = 'src' ]; then \ + echo >&2; \ + echo >&2 'error: UNIMPLEMENTED'; \ + echo >&2 'TODO install golang-any from jessie-backports for GOROOT_BOOTSTRAP (and uninstall after build)'; \ + echo >&2; \ + exit 1; \ + fi; \ + \ + export PATH="/usr/local/go/bin:$PATH"; \ + go version ENV GOPATH /go ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH diff --git a/1.7/windows/nanoserver/Dockerfile b/1.7/windows/nanoserver/Dockerfile index 8d668bcd..0e1e17e5 100644 --- a/1.7/windows/nanoserver/Dockerfile +++ b/1.7/windows/nanoserver/Dockerfile @@ -17,14 +17,14 @@ RUN $newPath = ('{0}\bin;C:\go\bin;{1}' -f $env:GOPATH, $env:PATH); \ # doing this first to share cache across versions more aggressively ENV GOLANG_VERSION 1.7.5 -ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.windows-amd64.zip -ENV GOLANG_DOWNLOAD_SHA256 01eb518cb5a12edd6cf7380ec17ebedee755e3ce7e5362febeebb9e70e45fcaa -RUN Write-Host ('Downloading {0} ...' -f $env:GOLANG_DOWNLOAD_URL); \ - Invoke-WebRequest -Uri $env:GOLANG_DOWNLOAD_URL -OutFile 'go.zip'; \ +RUN $url = ('https://golang.org/dl/go{0}.windows-amd64.zip' -f $env:GOLANG_VERSION); \ + Write-Host ('Downloading {0} ...' -f $url); \ + Invoke-WebRequest -Uri $url -OutFile 'go.zip'; \ \ - Write-Host ('Verifying sha256 ({0}) ...' -f $env:GOLANG_DOWNLOAD_SHA256); \ - if ((Get-FileHash go.zip -Algorithm sha256).Hash -ne $env:GOLANG_DOWNLOAD_SHA256) { \ + $sha256 = '01eb518cb5a12edd6cf7380ec17ebedee755e3ce7e5362febeebb9e70e45fcaa'; \ + Write-Host ('Verifying sha256 ({0}) ...' -f $sha256); \ + if ((Get-FileHash go.zip -Algorithm sha256).Hash -ne $sha256) { \ Write-Host 'FAILED!'; \ exit 1; \ }; \ diff --git a/1.7/windows/windowsservercore/Dockerfile b/1.7/windows/windowsservercore/Dockerfile index cd605579..be5baeef 100644 --- a/1.7/windows/windowsservercore/Dockerfile +++ b/1.7/windows/windowsservercore/Dockerfile @@ -46,14 +46,14 @@ RUN $newPath = ('{0}\bin;C:\go\bin;{1}' -f $env:GOPATH, $env:PATH); \ # doing this first to share cache across versions more aggressively ENV GOLANG_VERSION 1.7.5 -ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.windows-amd64.zip -ENV GOLANG_DOWNLOAD_SHA256 01eb518cb5a12edd6cf7380ec17ebedee755e3ce7e5362febeebb9e70e45fcaa -RUN Write-Host ('Downloading {0} ...' -f $env:GOLANG_DOWNLOAD_URL); \ - Invoke-WebRequest -Uri $env:GOLANG_DOWNLOAD_URL -OutFile 'go.zip'; \ +RUN $url = ('https://golang.org/dl/go{0}.windows-amd64.zip' -f $env:GOLANG_VERSION); \ + Write-Host ('Downloading {0} ...' -f $url); \ + Invoke-WebRequest -Uri $url -OutFile 'go.zip'; \ \ - Write-Host ('Verifying sha256 ({0}) ...' -f $env:GOLANG_DOWNLOAD_SHA256); \ - if ((Get-FileHash go.zip -Algorithm sha256).Hash -ne $env:GOLANG_DOWNLOAD_SHA256) { \ + $sha256 = '01eb518cb5a12edd6cf7380ec17ebedee755e3ce7e5362febeebb9e70e45fcaa'; \ + Write-Host ('Verifying sha256 ({0}) ...' -f $sha256); \ + if ((Get-FileHash go.zip -Algorithm sha256).Hash -ne $sha256) { \ Write-Host 'FAILED!'; \ exit 1; \ }; \ diff --git a/1.8/Dockerfile b/1.8/Dockerfile index b294c748..7d33cc6b 100644 --- a/1.8/Dockerfile +++ b/1.8/Dockerfile @@ -10,13 +10,37 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* ENV GOLANG_VERSION 1.8.1 -ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 a579ab19d5237e263254f1eac5352efcf1d70b9dacadb6d6bb12b0911ede8994 -RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \ - && echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - \ - && tar -C /usr/local -xzf golang.tar.gz \ - && rm golang.tar.gz +RUN set -eux; \ + \ +# this "case" statement is generated via "update.sh" + dpkgArch="$(dpkg --print-architecture)"; \ + case "${dpkgArch##*-}" in \ + ppc64el) goRelArch='linux-ppc64le'; goRelSha256='b7b47572a2676449716865a66901090c057f6f1d8dfb1e19528fcd0372e5ce74' ;; \ + i386) goRelArch='linux-386'; goRelSha256='cb3f4527112075a8b045d708f793aeee2709d2f5ddd320973a1413db06fddb50' ;; \ + s390x) goRelArch='linux-s390x'; goRelSha256='0a59f4034a27fc51431989da520fd244d5261f364888134cab737e5bc2158cb2' ;; \ + armhf) goRelArch='linux-armv6l'; goRelSha256='e8a8326913640409028ef95c2107773f989b1b2a6e11ceb463c77c42887381da' ;; \ + amd64) goRelArch='linux-amd64'; goRelSha256='a579ab19d5237e263254f1eac5352efcf1d70b9dacadb6d6bb12b0911ede8994' ;; \ + *) goRelArch='src'; goRelSha256='33daf4c03f86120fdfdc66bddf6bfff4661c7ca11c5da473e537f4d69b470e57'; \ + echo >&2; echo >&2 "warning: current architecture ($dpkgArch) does not have a corresponding Go binary release; will be building from source"; echo >&2 ;; \ + esac; \ + \ + url="https://golang.org/dl/go${GOLANG_VERSION}.${goRelArch}.tar.gz"; \ + wget -O go.tgz "$url"; \ + echo "${goRelSha256} *go.tgz" | sha256sum -c -; \ + tar -C /usr/local -xzf go.tgz; \ + rm go.tgz; \ + \ + if [ "$goRelArch" = 'src' ]; then \ + echo >&2; \ + echo >&2 'error: UNIMPLEMENTED'; \ + echo >&2 'TODO install golang-any from jessie-backports for GOROOT_BOOTSTRAP (and uninstall after build)'; \ + echo >&2; \ + exit 1; \ + fi; \ + \ + export PATH="/usr/local/go/bin:$PATH"; \ + go version ENV GOPATH /go ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH diff --git a/1.8/alpine/Dockerfile b/1.8/alpine/Dockerfile index bb567229..7e485b82 100644 --- a/1.8/alpine/Dockerfile +++ b/1.8/alpine/Dockerfile @@ -3,32 +3,38 @@ FROM alpine:3.5 RUN apk add --no-cache ca-certificates ENV GOLANG_VERSION 1.8.1 -ENV GOLANG_SRC_URL https://golang.org/dl/go$GOLANG_VERSION.src.tar.gz -ENV GOLANG_SRC_SHA256 33daf4c03f86120fdfdc66bddf6bfff4661c7ca11c5da473e537f4d69b470e57 -# https://golang.org/issue/14851 -COPY no-pic.patch / +# https://golang.org/issue/14851 (Go 1.8 & 1.7) +# https://golang.org/issue/17847 (Go 1.7) +COPY *.patch /go-alpine-patches/ -RUN set -ex \ - && apk add --no-cache --virtual .build-deps \ +RUN set -eux; \ + apk add --no-cache --virtual .build-deps \ bash \ gcc \ musl-dev \ openssl \ go \ + ; \ + export GOROOT_BOOTSTRAP="$(go env GOROOT)"; \ \ - && export GOROOT_BOOTSTRAP="$(go env GOROOT)" \ + wget -O go.tgz "https://golang.org/dl/go$GOLANG_VERSION.src.tar.gz"; \ + echo '33daf4c03f86120fdfdc66bddf6bfff4661c7ca11c5da473e537f4d69b470e57 *go.tgz' | sha256sum -c -; \ + tar -C /usr/local -xzf go.tgz; \ + rm go.tgz; \ \ - && wget -q "$GOLANG_SRC_URL" -O golang.tar.gz \ - && echo "$GOLANG_SRC_SHA256 golang.tar.gz" | sha256sum -c - \ - && tar -C /usr/local -xzf golang.tar.gz \ - && rm golang.tar.gz \ - && cd /usr/local/go/src \ - && patch -p2 -i /no-pic.patch \ - && ./make.bash \ + cd /usr/local/go/src; \ + for p in /go-alpine-patches/*.patch; do \ + [ -f "$p" ] || continue; \ + patch -p2 -i "$p"; \ + done; \ + ./make.bash; \ \ - && rm -rf /*.patch \ - && apk del .build-deps + rm -rf /go-alpine-patches; \ + apk del .build-deps; \ + \ + export PATH="/usr/local/go/bin:$PATH"; \ + go version ENV GOPATH /go ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH diff --git a/1.8/stretch/Dockerfile b/1.8/stretch/Dockerfile index 8d512c48..afe68cb5 100644 --- a/1.8/stretch/Dockerfile +++ b/1.8/stretch/Dockerfile @@ -10,13 +10,37 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* ENV GOLANG_VERSION 1.8.1 -ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ENV GOLANG_DOWNLOAD_SHA256 a579ab19d5237e263254f1eac5352efcf1d70b9dacadb6d6bb12b0911ede8994 -RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \ - && echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - \ - && tar -C /usr/local -xzf golang.tar.gz \ - && rm golang.tar.gz +RUN set -eux; \ + \ +# this "case" statement is generated via "update.sh" + dpkgArch="$(dpkg --print-architecture)"; \ + case "${dpkgArch##*-}" in \ + ppc64el) goRelArch='linux-ppc64le'; goRelSha256='b7b47572a2676449716865a66901090c057f6f1d8dfb1e19528fcd0372e5ce74' ;; \ + i386) goRelArch='linux-386'; goRelSha256='cb3f4527112075a8b045d708f793aeee2709d2f5ddd320973a1413db06fddb50' ;; \ + s390x) goRelArch='linux-s390x'; goRelSha256='0a59f4034a27fc51431989da520fd244d5261f364888134cab737e5bc2158cb2' ;; \ + armhf) goRelArch='linux-armv6l'; goRelSha256='e8a8326913640409028ef95c2107773f989b1b2a6e11ceb463c77c42887381da' ;; \ + amd64) goRelArch='linux-amd64'; goRelSha256='a579ab19d5237e263254f1eac5352efcf1d70b9dacadb6d6bb12b0911ede8994' ;; \ + *) goRelArch='src'; goRelSha256='33daf4c03f86120fdfdc66bddf6bfff4661c7ca11c5da473e537f4d69b470e57'; \ + echo >&2; echo >&2 "warning: current architecture ($dpkgArch) does not have a corresponding Go binary release; will be building from source"; echo >&2 ;; \ + esac; \ + \ + url="https://golang.org/dl/go${GOLANG_VERSION}.${goRelArch}.tar.gz"; \ + wget -O go.tgz "$url"; \ + echo "${goRelSha256} *go.tgz" | sha256sum -c -; \ + tar -C /usr/local -xzf go.tgz; \ + rm go.tgz; \ + \ + if [ "$goRelArch" = 'src' ]; then \ + echo >&2; \ + echo >&2 'error: UNIMPLEMENTED'; \ + echo >&2 'TODO install golang-any from jessie-backports for GOROOT_BOOTSTRAP (and uninstall after build)'; \ + echo >&2; \ + exit 1; \ + fi; \ + \ + export PATH="/usr/local/go/bin:$PATH"; \ + go version ENV GOPATH /go ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH diff --git a/1.8/windows/nanoserver/Dockerfile b/1.8/windows/nanoserver/Dockerfile index 7098eea5..84035302 100644 --- a/1.8/windows/nanoserver/Dockerfile +++ b/1.8/windows/nanoserver/Dockerfile @@ -17,14 +17,14 @@ RUN $newPath = ('{0}\bin;C:\go\bin;{1}' -f $env:GOPATH, $env:PATH); \ # doing this first to share cache across versions more aggressively ENV GOLANG_VERSION 1.8.1 -ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.windows-amd64.zip -ENV GOLANG_DOWNLOAD_SHA256 bb6f0fbef8b80c382455af8699bfbb7fe89256d4baf06d927feaeceb7342e4ee -RUN Write-Host ('Downloading {0} ...' -f $env:GOLANG_DOWNLOAD_URL); \ - Invoke-WebRequest -Uri $env:GOLANG_DOWNLOAD_URL -OutFile 'go.zip'; \ +RUN $url = ('https://golang.org/dl/go{0}.windows-amd64.zip' -f $env:GOLANG_VERSION); \ + Write-Host ('Downloading {0} ...' -f $url); \ + Invoke-WebRequest -Uri $url -OutFile 'go.zip'; \ \ - Write-Host ('Verifying sha256 ({0}) ...' -f $env:GOLANG_DOWNLOAD_SHA256); \ - if ((Get-FileHash go.zip -Algorithm sha256).Hash -ne $env:GOLANG_DOWNLOAD_SHA256) { \ + $sha256 = 'bb6f0fbef8b80c382455af8699bfbb7fe89256d4baf06d927feaeceb7342e4ee'; \ + Write-Host ('Verifying sha256 ({0}) ...' -f $sha256); \ + if ((Get-FileHash go.zip -Algorithm sha256).Hash -ne $sha256) { \ Write-Host 'FAILED!'; \ exit 1; \ }; \ diff --git a/1.8/windows/windowsservercore/Dockerfile b/1.8/windows/windowsservercore/Dockerfile index 2b5121b7..1aa27da8 100644 --- a/1.8/windows/windowsservercore/Dockerfile +++ b/1.8/windows/windowsservercore/Dockerfile @@ -46,14 +46,14 @@ RUN $newPath = ('{0}\bin;C:\go\bin;{1}' -f $env:GOPATH, $env:PATH); \ # doing this first to share cache across versions more aggressively ENV GOLANG_VERSION 1.8.1 -ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.windows-amd64.zip -ENV GOLANG_DOWNLOAD_SHA256 bb6f0fbef8b80c382455af8699bfbb7fe89256d4baf06d927feaeceb7342e4ee -RUN Write-Host ('Downloading {0} ...' -f $env:GOLANG_DOWNLOAD_URL); \ - Invoke-WebRequest -Uri $env:GOLANG_DOWNLOAD_URL -OutFile 'go.zip'; \ +RUN $url = ('https://golang.org/dl/go{0}.windows-amd64.zip' -f $env:GOLANG_VERSION); \ + Write-Host ('Downloading {0} ...' -f $url); \ + Invoke-WebRequest -Uri $url -OutFile 'go.zip'; \ \ - Write-Host ('Verifying sha256 ({0}) ...' -f $env:GOLANG_DOWNLOAD_SHA256); \ - if ((Get-FileHash go.zip -Algorithm sha256).Hash -ne $env:GOLANG_DOWNLOAD_SHA256) { \ + $sha256 = 'bb6f0fbef8b80c382455af8699bfbb7fe89256d4baf06d927feaeceb7342e4ee'; \ + Write-Host ('Verifying sha256 ({0}) ...' -f $sha256); \ + if ((Get-FileHash go.zip -Algorithm sha256).Hash -ne $sha256) { \ Write-Host 'FAILED!'; \ exit 1; \ }; \ diff --git a/Dockerfile-alpine.template b/Dockerfile-alpine.template new file mode 100644 index 00000000..28a4138e --- /dev/null +++ b/Dockerfile-alpine.template @@ -0,0 +1,45 @@ +FROM alpine:%%ALPINE-VERSION%% + +RUN apk add --no-cache ca-certificates + +ENV GOLANG_VERSION %%VERSION%% + +# https://golang.org/issue/14851 (Go 1.8 & 1.7) +# https://golang.org/issue/17847 (Go 1.7) +COPY *.patch /go-alpine-patches/ + +RUN set -eux; \ + apk add --no-cache --virtual .build-deps \ + bash \ + gcc \ + musl-dev \ + openssl \ + go \ + ; \ + export GOROOT_BOOTSTRAP="$(go env GOROOT)"; \ + \ + wget -O go.tgz "https://golang.org/dl/go$GOLANG_VERSION.src.tar.gz"; \ + echo '%%SRC-SHA256%% *go.tgz' | sha256sum -c -; \ + tar -C /usr/local -xzf go.tgz; \ + rm go.tgz; \ + \ + cd /usr/local/go/src; \ + for p in /go-alpine-patches/*.patch; do \ + [ -f "$p" ] || continue; \ + patch -p2 -i "$p"; \ + done; \ + ./make.bash; \ + \ + rm -rf /go-alpine-patches; \ + apk del .build-deps; \ + \ + export PATH="/usr/local/go/bin:$PATH"; \ + go version + +ENV GOPATH /go +ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH + +RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" +WORKDIR $GOPATH + +COPY go-wrapper /usr/local/bin/ diff --git a/Dockerfile-debian.template b/Dockerfile-debian.template new file mode 100644 index 00000000..9f4f867a --- /dev/null +++ b/Dockerfile-debian.template @@ -0,0 +1,42 @@ +FROM buildpack-deps:%%DEBIAN-SUITE%%-scm + +# gcc for cgo +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + gcc \ + libc6-dev \ + make \ + pkg-config \ + && rm -rf /var/lib/apt/lists/* + +ENV GOLANG_VERSION %%VERSION%% + +RUN set -eux; \ + \ +# this "case" statement is generated via "update.sh" + %%ARCH-CASE%%; \ + \ + url="https://golang.org/dl/go${GOLANG_VERSION}.${goRelArch}.tar.gz"; \ + wget -O go.tgz "$url"; \ + echo "${goRelSha256} *go.tgz" | sha256sum -c -; \ + tar -C /usr/local -xzf go.tgz; \ + rm go.tgz; \ + \ + if [ "$goRelArch" = 'src' ]; then \ + echo >&2; \ + echo >&2 'error: UNIMPLEMENTED'; \ + echo >&2 'TODO install golang-any from jessie-backports for GOROOT_BOOTSTRAP (and uninstall after build)'; \ + echo >&2; \ + exit 1; \ + fi; \ + \ + export PATH="/usr/local/go/bin:$PATH"; \ + go version + +ENV GOPATH /go +ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH + +RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" +WORKDIR $GOPATH + +COPY go-wrapper /usr/local/bin/ diff --git a/Dockerfile-windows-nanoserver.template b/Dockerfile-windows-nanoserver.template new file mode 100644 index 00000000..0170be62 --- /dev/null +++ b/Dockerfile-windows-nanoserver.template @@ -0,0 +1,43 @@ +FROM microsoft/nanoserver + +# $ProgressPreference: https://github.com/PowerShell/PowerShell/issues/2138#issuecomment-251261324 +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +# no Git installed (intentionally) +# -- Nano Server is "Windows Slim" + +# ideally, this would be C:\go to match Linux a bit closer, but C:\go is the recommended install path for Go itself on Windows +ENV GOPATH C:\\gopath + +# PATH isn't actually set in the Docker image, so we have to set it from within the container +RUN $newPath = ('{0}\bin;C:\go\bin;{1}' -f $env:GOPATH, $env:PATH); \ + Write-Host ('Updating PATH: {0}' -f $newPath); \ +# Nano Server does not have "[Environment]::SetEnvironmentVariable()" + setx /M PATH $newPath; +# doing this first to share cache across versions more aggressively + +ENV GOLANG_VERSION %%VERSION%% + +RUN $url = ('https://golang.org/dl/go{0}.windows-amd64.zip' -f $env:GOLANG_VERSION); \ + Write-Host ('Downloading {0} ...' -f $url); \ + Invoke-WebRequest -Uri $url -OutFile 'go.zip'; \ + \ + $sha256 = '%%WIN-SHA256%%'; \ + Write-Host ('Verifying sha256 ({0}) ...' -f $sha256); \ + if ((Get-FileHash go.zip -Algorithm sha256).Hash -ne $sha256) { \ + Write-Host 'FAILED!'; \ + exit 1; \ + }; \ + \ + Write-Host 'Expanding ...'; \ + Expand-Archive go.zip -DestinationPath C:\; \ + \ + Write-Host 'Verifying install ("go version") ...'; \ + go version; \ + \ + Write-Host 'Removing ...'; \ + Remove-Item go.zip -Force; \ + \ + Write-Host 'Complete.'; + +WORKDIR $GOPATH diff --git a/Dockerfile-windows-windowsservercore.template b/Dockerfile-windows-windowsservercore.template new file mode 100644 index 00000000..00a16e76 --- /dev/null +++ b/Dockerfile-windows-windowsservercore.template @@ -0,0 +1,72 @@ +FROM microsoft/windowsservercore + +# $ProgressPreference: https://github.com/PowerShell/PowerShell/issues/2138#issuecomment-251261324 +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +# install MinGit (especially for "go get") +# https://blogs.msdn.microsoft.com/visualstudioalm/2016/09/03/whats-new-in-git-for-windows-2-10/ +# "Essentially, it is a Git for Windows that was stripped down as much as possible without sacrificing the functionality in which 3rd-party software may be interested." +# "It currently requires only ~45MB on disk." +ENV GIT_VERSION 2.11.1 +ENV GIT_TAG v${GIT_VERSION}.windows.1 +ENV GIT_DOWNLOAD_URL https://github.com/git-for-windows/git/releases/download/${GIT_TAG}/MinGit-${GIT_VERSION}-64-bit.zip +ENV GIT_DOWNLOAD_SHA256 668d16a799dd721ed126cc91bed49eb2c072ba1b25b50048280a4e2c5ed56e59 +# steps inspired by "chcolateyInstall.ps1" from "git.install" (https://chocolatey.org/packages/git.install) +RUN Write-Host ('Downloading {0} ...' -f $env:GIT_DOWNLOAD_URL); \ + Invoke-WebRequest -Uri $env:GIT_DOWNLOAD_URL -OutFile 'git.zip'; \ + \ + Write-Host ('Verifying sha256 ({0}) ...' -f $env:GIT_DOWNLOAD_SHA256); \ + if ((Get-FileHash git.zip -Algorithm sha256).Hash -ne $env:GIT_DOWNLOAD_SHA256) { \ + Write-Host 'FAILED!'; \ + exit 1; \ + }; \ + \ + Write-Host 'Expanding ...'; \ + Expand-Archive -Path git.zip -DestinationPath C:\git\.; \ + \ + Write-Host 'Removing ...'; \ + Remove-Item git.zip -Force; \ + \ + Write-Host 'Updating PATH ...'; \ + $env:PATH = 'C:\git\cmd;C:\git\mingw64\bin;C:\git\usr\bin;' + $env:PATH; \ + [Environment]::SetEnvironmentVariable('PATH', $env:PATH, [EnvironmentVariableTarget]::Machine); \ + \ + Write-Host 'Verifying install ...'; \ + Write-Host ' git --version'; git --version; \ + \ + Write-Host 'Complete.'; + +# ideally, this would be C:\go to match Linux a bit closer, but C:\go is the recommended install path for Go itself on Windows +ENV GOPATH C:\\gopath + +# PATH isn't actually set in the Docker image, so we have to set it from within the container +RUN $newPath = ('{0}\bin;C:\go\bin;{1}' -f $env:GOPATH, $env:PATH); \ + Write-Host ('Updating PATH: {0}' -f $newPath); \ + [Environment]::SetEnvironmentVariable('PATH', $newPath, [EnvironmentVariableTarget]::Machine); +# doing this first to share cache across versions more aggressively + +ENV GOLANG_VERSION %%VERSION%% + +RUN $url = ('https://golang.org/dl/go{0}.windows-amd64.zip' -f $env:GOLANG_VERSION); \ + Write-Host ('Downloading {0} ...' -f $url); \ + Invoke-WebRequest -Uri $url -OutFile 'go.zip'; \ + \ + $sha256 = '%%WIN-SHA256%%'; \ + Write-Host ('Verifying sha256 ({0}) ...' -f $sha256); \ + if ((Get-FileHash go.zip -Algorithm sha256).Hash -ne $sha256) { \ + Write-Host 'FAILED!'; \ + exit 1; \ + }; \ + \ + Write-Host 'Expanding ...'; \ + Expand-Archive go.zip -DestinationPath C:\; \ + \ + Write-Host 'Verifying install ("go version") ...'; \ + go version; \ + \ + Write-Host 'Removing ...'; \ + Remove-Item go.zip -Force; \ + \ + Write-Host 'Complete.'; + +WORKDIR $GOPATH diff --git a/update.sh b/update.sh index 2f06e66d..8521e11a 100755 --- a/update.sh +++ b/update.sh @@ -1,5 +1,25 @@ #!/bin/bash -set -e +set -Eeuo pipefail + +# a mapping of "dpkg --print-architecture" to Go release arch +# see https://golang.org/dl/ +declare -A dpkgArches=( + [amd64]='amd64' + [armhf]='armv6l' + [i386]='386' + [ppc64el]='ppc64le' + [s390x]='s390x' +) + +defaultDebianSuite='stretch' +declare -A debianSuite=( + [1.8]='jessie' + [1.7]='jessie' +) +defaultAlpineVersion='3.5' +declare -A alpineVersion=( + [1.7]='3.4' +) cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" @@ -9,10 +29,22 @@ if [ ${#versions[@]} -eq 0 ]; then fi versions=( "${versions[@]%/}" ) +# see http://stackoverflow.com/a/2705678/433558 +sed_escape_lhs() { + echo "$@" | sed -e 's/[]\/$*.^|[]/\\&/g' +} +sed_escape_rhs() { + echo "$@" | sed -e 's/[\/&]/\\&/g' | sed -e ':a;N;$!ba;s/\n/\\n/g' +} + +googleSource="$(curl -fsSL 'https://golang.org/dl/')" +scrape_sha256() { + local filename="$1" + echo $googleSource | grep -Po '">'"$(sed_escape_lhs "$filename")"'.*?>[a-f0-9]{40,64}<' | sed -r 's!.*>([a-f0-9]{64})<.*!\1!; s!.*[<>]+.*!!' | tail -1 +} travisEnv= appveyorEnv= -googleSource="$(curl -fsSL 'https://golang.org/dl/')" for version in "${versions[@]}"; do rcVersion="${version%-rc}" rcGrepV='-v' @@ -33,56 +65,59 @@ for version in "${versions[@]}"; do continue fi fullVersion="${fullVersion#go}" # strip "go" off "go1.4.2" - versionTag="$fullVersion" - - # Try and fetch the checksum from the golang source page - linuxSha256="$(echo $googleSource | grep -Po '">go'"$fullVersion"'\.linux-amd64\.tar\.gz.*?>[a-f0-9]{40,64}<' | sed -r 's!.*>([a-f0-9]{64})<.*!\1!; s!.*[<>]+.*!!' | tail -1)" - if [ -z "$linuxSha256" ]; then - echo >&2 "warning: cannot find sha256 for $fullVersion" - continue - fi - windowsSha256="$(echo $googleSource | grep -Po '">go'"$fullVersion"'\.windows-amd64\.zip.*?>[a-f0-9]{40,64}<' | sed -r 's!.*>([a-f0-9]{64})<.*!\1!; s!.*[<>]+.*!!' | tail -1)" - - srcSha256="$(echo $googleSource | grep -Po '">go'"$fullVersion"'\.src\.tar\.gz.*?>[a-f0-9]{40,64}<' | sed -r 's!.*>([a-f0-9]{64})<.*!\1!; s!.*[<>]+.*!!' | tail -1)" + srcSha256="$(scrape_sha256 "go${fullVersion}.src.tar.gz")" + linuxArchCase='dpkgArch="$(dpkg --print-architecture)"; '$'\\\n' + linuxArchCase+=$'\t''case "${dpkgArch##*-}" in '$'\\\n' + for dpkgArch in "${!dpkgArches[@]}"; do + goArch="${dpkgArches[$dpkgArch]}" + sha256="$(scrape_sha256 "go${fullVersion}.linux-${goArch}.tar.gz")" + if [ -z "$sha256" ]; then + echo >&2 "warning: cannot find sha256 for $fullVersion on arch $goArch" + continue 2 + fi + linuxArchCase+=$'\t\t'"$dpkgArch) goRelArch='linux-$goArch'; goRelSha256='$sha256' ;; "$'\\\n' + done + linuxArchCase+=$'\t\t'"*) goRelArch='src'; goRelSha256='$srcSha256'; "$'\\\n' + linuxArchCase+=$'\t\t\t''echo >&2; echo >&2 "warning: current architecture ($dpkgArch) does not have a corresponding Go binary release; will be building from source"; echo >&2 ;; '$'\\\n' + linuxArchCase+=$'\t''esac' + windowsSha256="$(scrape_sha256 "go${fullVersion}.windows-amd64.zip")" - [[ "$versionTag" == *.*[^0-9]* ]] || versionTag+='.0' - ( - set -x - sed -ri \ - -e 's/^(ENV GOLANG_VERSION) .*/\1 '"$fullVersion"'/' \ - -e 's/^(ENV GOLANG_DOWNLOAD_SHA256) .*/\1 '"$linuxSha256"'/' \ - -e 's/^(ENV GOLANG_SRC_SHA256) .*/\1 '"$srcSha256"'/' \ - -e 's/^(FROM golang):.*/\1:'"$version"'/' \ - "$version/Dockerfile" \ - "$version/"*"/Dockerfile" - cp go-wrapper "$version/" - ) - for variant in alpine3.5 alpine stretch wheezy; do + for variant in alpine3.5 alpine; do if [ -d "$version/$variant" ]; then - if [[ "$variant" != 'alpine'* ]]; then - ( - set -x - sed 's/^FROM .*/FROM buildpack-deps:'"$variant"'-scm/' "$version/Dockerfile" > "$version/$variant/Dockerfile" - ) - fi - cp "$version/go-wrapper" "$version/$variant/" + ver="${variant#alpine}" + ver="${ver:-${alpineVersion[$version]:-$defaultAlpineVersion}}" + sed -r \ + -e 's!%%VERSION%%!'"$fullVersion"'!g' \ + -e 's!%%ALPINE-VERSION%%!'"$ver"'!g' \ + -e 's!%%SRC-SHA256%%!'"$srcSha256"'!g' \ + Dockerfile-alpine.template > "$version/$variant/Dockerfile" + cp go-wrapper "$version/$variant/" travisEnv='\n - VERSION='"$version VARIANT=$variant$travisEnv" fi done - for variant in windows/windowsservercore windows/nanoserver; do + for variant in stretch wheezy ''; do if [ -d "$version/$variant" ]; then - ( - set -x - sed -ri \ - -e 's/^(ENV GOLANG_VERSION) .*/\1 '"$fullVersion"'/' \ - -e 's/^(ENV GOLANG_DOWNLOAD_SHA256) .*/\1 '"$windowsSha256"'/' \ - "$version/$variant/Dockerfile" - ) - appveyorEnv='\n - version: '"$version"'\n variant: '"$(basename "$variant")$appveyorEnv" + sed -r \ + -e 's!%%VERSION%%!'"$fullVersion"'!g' \ + -e 's!%%DEBIAN-SUITE%%!'"${variant:-${debianSuite[$version]:-$defaultDebianSuite}}"'!g' \ + -e 's!%%ARCH-CASE%%!'"$(sed_escape_rhs "$linuxArchCase")"'!g' \ + Dockerfile-debian.template > "$version/$variant/Dockerfile" + cp go-wrapper "$version/$variant/" + travisEnv='\n - VERSION='"$version VARIANT=$variant$travisEnv" fi done - travisEnv='\n - VERSION='"$version VARIANT=$travisEnv" + for winVariant in windowsservercore nanoserver; do + if [ -d "$version/windows/$winVariant" ]; then + sed -r \ + -e 's!%%VERSION%%!'"$fullVersion"'!g' \ + -e 's!%%WIN-SHA256%%!'"$windowsSha256"'!g' \ + "Dockerfile-windows-$winVariant.template" > "$version/windows/$winVariant/Dockerfile" + appveyorEnv='\n - version: '"$version"'\n variant: '"$winVariant$appveyorEnv" + fi + done + + echo "$version: $fullVersion ($srcSha256)" done travis="$(awk -v 'RS=\n\n' '$1 == "env:" { $0 = "env:'"$travisEnv"'" } { printf "%s%s", $0, RS }' .travis.yml)"