diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..a81b3fc70 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +# Image for cross compiling mantle. + +FROM ubuntu:17.04 + +ARG GO_VERSION=1.9.1 + +RUN apt-get update && apt-get install -y \ + apt-utils \ + gcc \ + gcc-aarch64-linux-gnu \ + git \ + wget \ + && rm -rf /var/lib/apt/lists/* + +RUN wget --no-verbose https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz && \ + tar -C /usr/local -xf go${GO_VERSION}.linux-amd64.tar.gz && \ + rm go${GO_VERSION}.linux-amd64.tar.gz + +ENV PATH /usr/local/go/bin:${PATH} + +CMD /bin/bash diff --git a/Jenkinsfile b/Jenkinsfile index a508a46b4..38c83b26d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -6,26 +6,42 @@ properties([ [$class: 'CopyArtifactPermissionProperty', projectNames: '*'], - parameters([ - choice(name: 'GOARCH', - choices: "amd64\narm64", - description: 'target architecture for building binaries') - ]), - pipelineTriggers([pollSCM('H/15 * * * *')]) ]) +def docker_args = "-e CGO_ENABLED=1 --rm -u \"\$(id -u):\$(id -g)\" \ + -v /etc/passwd:/etc/passwd:ro -v /etc/group:/etc/group:ro -v \"\$PWD\":/usr/src/myapp \ + -w /usr/src/myapp mantle-builder:1.9.1.0" + +def buildMantle = { String targetArch, String targetCC, String extraArgs -> + def args = "-e GOARCH=${targetArch} -e CC=${targetCC} ${extraArgs} ${docker_args}" + sh "docker run ${args} ./build" +} + +def build_map = [:] + +build_map.failFast = false +build_map['amd64'] = buildMantle.curry('amd64', 'gcc', '') +build_map['arm64'] = buildMantle.curry('arm64', 'aarch64-linux-gnu-gcc', '-e NO_CROSS=1') + node('amd64 && docker') { stage('SCM') { checkout scm } + stage('Build Docker') { + sh "bash -x ./build-docker --force" + } + stage('Build') { - sh "docker run --rm -e CGO_ENABLED=1 -e GOARCH=${params.GOARCH} -u \"\$(id -u):\$(id -g)\" -v /etc/passwd:/etc/passwd:ro -v /etc/group:/etc/group:ro -v \"\$PWD\":/usr/src/myapp -w /usr/src/myapp golang:1.9.1 ./build" + build_map.each { + if (it.value) + it.value.call() + } } stage('Test') { - sh 'docker run --rm -u "$(id -u):$(id -g)" -v /etc/passwd:/etc/passwd:ro -v /etc/group:/etc/group:ro -v "$PWD":/usr/src/myapp -w /usr/src/myapp golang:1.9.1 ./test' + sh "docker run ${docker_args} ./test -v" } stage('Post-build') { diff --git a/build b/build index 44914a4ab..0715dcd16 100755 --- a/build +++ b/build @@ -17,10 +17,18 @@ ldflags="-X ${REPO_PATH}/version.Version=${version}" host_build() { echo "Building $1" - go build -i -ldflags "${ldflags}" -o "bin/$1" "${REPO_PATH}/cmd/$1" + + if [[ "${GOHOSTARCH}" == "${GOARCH}" ]]; then + install_dir="bin" + else + install_dir="bin/${GOARCH}" + fi + mkdir -p "${install_dir}" + go build -ldflags "${ldflags}" -o "${install_dir}/$1" "${REPO_PATH}/cmd/$1" } cross_build() { + [[ -z "${NO_CROSS}" ]] || return 0 local a for a in amd64 arm64; do echo "Building $a/$1" diff --git a/build-docker b/build-docker new file mode 100755 index 000000000..0d9ff761c --- /dev/null +++ b/build-docker @@ -0,0 +1,57 @@ +#!/bin/bash + +set -e + +: ${DOCKER_NAME:="mantle-builder"} +: ${GO_VERSION:="1.9.1"} +: ${REVISION:=".0"} + +docker_tag="${DOCKER_NAME}:${GO_VERSION}${REVISION}" + +usage () { + echo "Usage: $(basename $0) [flags]" >&2 + echo "Option flags:" >&2 + echo " -f --force - Rebuild existing docker image." >&2 + echo " -h --help - Show this help and exit." >&2 + echo " -p --purge - Remove existing docker image and rebuild." >&2 + echo "Environment:" >&2 + echo " DOCKER_NAME - Default: '${DOCKER_NAME}'" >&2 + echo " GO_VERSION - Default: '${GO_VERSION}'" >&2 + echo " REVISION - Default: '${REVISION}'" >&2 + echo "Docker tag: ${docker_tag}" >&2 +} + +while [[ $# -gt 0 ]]; do + case "${1}" in + -h | --help | help) + usage + exit 0 + ;; + -f | --force | force) + force=1 + ;; + -p | --purge | purge) + purge=1 + ;; + *) + usage + exit 1 + ;; + esac + shift +done + +if [[ -n "${purge}" ]] && docker inspect --type image ${docker_tag} > /dev/null; then + echo "removing docker image: ${docker_tag}" >&2 + docker rmi ${docker_tag} +elif [[ -z "${force}" ]] && docker inspect --type image ${docker_tag} > /dev/null; then + echo "docker image exists: ${docker_tag}" >&2 + exit 0 +fi + +echo "building image: ${docker_tag}" >&2 + +docker build \ + --build-arg GO_VERSION=${GO_VERSION} \ + --tag ${docker_tag}\ + .