diff --git a/.ci/scripts/buildx.sh b/.ci/scripts/buildx.sh new file mode 100755 index 00000000..b8198438 --- /dev/null +++ b/.ci/scripts/buildx.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e +set +x + +BUILDER_NAME="multibuilder${RANDOM}" +echo "Add support for multiarch" +docker run --privileged --rm tonistiigi/binfmt --install all + +docker buildx ls +echo 'Create builder' +docker buildx create --name "${BUILDER_NAME}" +docker buildx use "${BUILDER_NAME}" +docker buildx inspect --bootstrap +echo 'Build Docker image' +docker buildx build --platform linux/amd64,linux/arm64 --push $* diff --git a/.gitignore b/.gitignore index 9f96714d..44ade9b4 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,11 @@ *.o .idea .vagrant +.vscode _obj Dockerfile .status.* *.bck CHANGELOG.md npcap/lib/*.exe + diff --git a/Jenkinsfile b/Jenkinsfile index 0312a6a8..f362c5b4 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,7 +12,8 @@ pipeline { DOCKER_REGISTRY_SECRET = 'secret/observability-team/ci/docker-registry/prod' REGISTRY = 'docker.elastic.co' STAGING_IMAGE = "${env.REGISTRY}/observability-ci" - GO_VERSION = '1.17.10' + GO_VERSION = '1.17.11' + BUILDX = "1" } options { timeout(time: 3, unit: 'HOURS') @@ -175,7 +176,9 @@ def buildImages(){ dir("${env.BASE_DIR}"){ def platform = (PLATFORM?.trim().equals('arm')) ? '-arm' : '' retryWithSleep(retries: 3, seconds: 15, backoff: true) { - sh "make -C go -f ${MAKEFILE} build${platform}" + withDockerEnv(secret: "${env.DOCKER_REGISTRY_SECRET}", registry: "${env.REGISTRY}") { + sh "make -C go -f ${MAKEFILE} build${platform}" + } } sh(label: 'list Docker images', script: 'docker images --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}" --filter=reference="docker.elastic.co/beats-dev/golang-crossbuild"') } diff --git a/Makefile.common b/Makefile.common index fb5adc66..ebb429a9 100644 --- a/Makefile.common +++ b/Makefile.common @@ -8,6 +8,12 @@ NPCAP_FILE := npcap-$(NPCAP_VERSION)-oem.exe SUFFIX_NPCAP_VERSION := -npcap-$(NPCAP_VERSION) NPCAP_REPOSITORY := docker.elastic.co/observability-ci +ifeq ($(BUILDX),1) +ifeq ($(shell test $(DEBIAN_VERSION) -ge 10; echo $$?),0) +DOCKER_MULTIARCH := 1 +endif +endif + # Requires login at google storage. copy-npcap: status=".status.copy-npcap" copy-npcap: diff --git a/go/Makefile.common b/go/Makefile.common index 02e3a841..4415b544 100644 --- a/go/Makefile.common +++ b/go/Makefile.common @@ -2,17 +2,19 @@ SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) include $(SELF_DIR)/../Makefile.common NAME := golang-crossbuild -VERSION := 1.17.10 +VERSION := 1.17.11 DEBIAN_VERSION ?= 9 SUFFIX := -$(shell basename $(CURDIR)) TAG_EXTENSION ?= export DEBIAN_VERSION TAG_EXTENSION +DOCKER_CMD := docker build + build: copy-npcap @echo ">> Building $(REPOSITORY)/$(NAME):$(VERSION)$(SUFFIX)$(TAG_EXTENSION)" @go run $(SELF_DIR)/../template.go -t Dockerfile.tmpl -o Dockerfile - @docker build -t "$(REPOSITORY)/$(NAME):$(VERSION)$(SUFFIX)$(TAG_EXTENSION)" \ + @$(DOCKER_CMD) -t "$(REPOSITORY)/$(NAME):$(VERSION)$(SUFFIX)$(TAG_EXTENSION)" \ --build-arg REPOSITORY=$(REPOSITORY) \ --build-arg VERSION=$(VERSION) \ --build-arg DEBIAN_VERSION=$(DEBIAN_VERSION) \ diff --git a/go/arm/Dockerfile.tmpl b/go/arm/Dockerfile.tmpl index 5fe9b114..9513aba8 100644 --- a/go/arm/Dockerfile.tmpl +++ b/go/arm/Dockerfile.tmpl @@ -1,7 +1,7 @@ ARG REPOSITORY ARG VERSION ARG TAG_EXTENSION='' -FROM ${REPOSITORY}/golang-crossbuild:${VERSION}-base${TAG_EXTENSION} +FROM --platform=linux/amd64 ${REPOSITORY}/golang-crossbuild:${VERSION}-base${TAG_EXTENSION} as stage-amd64 RUN dpkg --add-architecture arm64 \ && apt update -y --no-install-recommends \ @@ -46,6 +46,56 @@ RUN apt install -y \ libsystemd-dev:arm64 {{ end }} +ARG REPOSITORY +ARG VERSION +ARG TAG_EXTENSION='' +FROM --platform=linux/arm64 ${REPOSITORY}/golang-crossbuild:${VERSION}-base${TAG_EXTENSION} as stage-arm64 + +RUN dpkg --add-architecture arm64 \ + && apt update -y --no-install-recommends \ + && apt upgrade -y --no-install-recommends \ + && apt full-upgrade -y --no-install-recommends \ + && apt install -qq -y --no-install-recommends \ + build-essential \ + libc-dev \ + libpopt-dev \ + linux-libc-dev + +{{- if eq .DEBIAN_VERSION "9"}} +# librpm-dev +RUN apt install -y \ + librpm-dev \ + librpm3 \ + librpmio3 \ + librpmbuild3 \ + librpmsign3 \ + libxml2-dev \ + libsqlite3-dev \ + libnss3 \ + libsqlite3-0 \ + libxml2 \ + libsqlite3-0 + +# libsystemd-dev +RUN apt install -y \ + libsystemd-dev libsystemd0 liblz4-1 +{{- end }} + +{{- if or (eq .DEBIAN_VERSION "10") (eq .DEBIAN_VERSION "11")}} +# librpm-dev +RUN apt install -y \ + librpm-dev + +# libsystemd-dev +RUN apt install -y \ + libsystemd-dev +{{- end }} + +# Declare TARGETARCH to make it available +ARG TARGETARCH=amd64 +# Select final stage based on TARGETARCH ARG +FROM stage-${TARGETARCH} as final + RUN rm -rf /var/lib/apt/lists/* COPY rootfs / diff --git a/go/arm/Makefile b/go/arm/Makefile index 0a42375f..633e0149 100644 --- a/go/arm/Makefile +++ b/go/arm/Makefile @@ -1 +1,19 @@ include ../Makefile.common + +ifeq ($(DOCKER_MULTIARCH),1) +DOCKER_CMD := $(SELF_DIR)/../.ci/scripts/buildx.sh + +push: + @echo "Already done by buildx (.ci/scripts/buildx.sh)." +atomic-push: + @echo "Already done by buildx (.ci/scripts/buildx.sh)." +endif + +ifeq ($(BUILDX)$(DEBIAN_VERSION),19) +DOCKER_CMD := $(SELF_DIR)/../.ci/scripts/buildx.sh + +push: + @echo "Already done by buildx (.ci/scripts/buildx.sh)." +atomic-push: + @echo "Already done by buildx (.ci/scripts/buildx.sh)." +endif diff --git a/go/base-arm/Dockerfile.tmpl b/go/base-arm/Dockerfile.tmpl index f3395660..1c47158a 100644 --- a/go/base-arm/Dockerfile.tmpl +++ b/go/base-arm/Dockerfile.tmpl @@ -37,9 +37,9 @@ RUN \ libsqlite3-0 \ && rm -rf /var/lib/apt/lists/* -ARG GOLANG_VERSION=1.17.10 +ARG GOLANG_VERSION=1.17.11 ARG GOLANG_DOWNLOAD_URL=https://golang.org/dl/go$GOLANG_VERSION.linux-arm64.tar.gz -ARG GOLANG_DOWNLOAD_SHA256=649141201efa7195403eb1301b95dc79c5b3e65968986a391da1370521701b0c +ARG GOLANG_DOWNLOAD_SHA256=adefa7412c6798f9cad02d1e8336fc2242f5bade30c5b32781759181e01961b7 RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \ && echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - \ diff --git a/go/base/Dockerfile.tmpl b/go/base/Dockerfile.tmpl index d9f765d0..47b22322 100644 --- a/go/base/Dockerfile.tmpl +++ b/go/base/Dockerfile.tmpl @@ -18,25 +18,24 @@ RUN apt-get -o Acquire::Check-Valid-Until=false update -y --no-install-recommend file \ flex \ bison \ -{{if or (eq .DEBIAN_VERSION "10") (eq .DEBIAN_VERSION "11")}} + xz-utils \ +{{- if or (eq .DEBIAN_VERSION "10") (eq .DEBIAN_VERSION "11")}} + binutils-multiarch \ + binutils-multiarch-dev \ python3-venv \ python3-pip \ python3 \ -{{ end }} +{{- end }} && rm -rf /var/lib/apt/lists/* {{if eq .DEBIAN_VERSION "10"}} RUN ln -s /usr/bin/pip3 /usr/bin/pip {{ end }} -ARG GOLANG_VERSION=1.17.10 -ARG GOLANG_DOWNLOAD_URL=https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz -ARG GOLANG_DOWNLOAD_SHA256=87fc728c9c731e2f74e4a999ef53cf07302d7ed3504b0839027bd9c10edaa3fd - -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 +COPY install-go.sh /tmp/install-go.sh +RUN chmod ugo+rx /tmp/install-go.sh \ + && /tmp/install-go.sh \ + && rm /tmp/install-go.sh ENV GOPATH /go ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH diff --git a/go/base/Makefile b/go/base/Makefile index 0a42375f..633e0149 100644 --- a/go/base/Makefile +++ b/go/base/Makefile @@ -1 +1,19 @@ include ../Makefile.common + +ifeq ($(DOCKER_MULTIARCH),1) +DOCKER_CMD := $(SELF_DIR)/../.ci/scripts/buildx.sh + +push: + @echo "Already done by buildx (.ci/scripts/buildx.sh)." +atomic-push: + @echo "Already done by buildx (.ci/scripts/buildx.sh)." +endif + +ifeq ($(BUILDX)$(DEBIAN_VERSION),19) +DOCKER_CMD := $(SELF_DIR)/../.ci/scripts/buildx.sh + +push: + @echo "Already done by buildx (.ci/scripts/buildx.sh)." +atomic-push: + @echo "Already done by buildx (.ci/scripts/buildx.sh)." +endif diff --git a/go/base/install-go.sh b/go/base/install-go.sh new file mode 100644 index 00000000..ab32af6a --- /dev/null +++ b/go/base/install-go.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# This script install the Go version correct for each architecture. +set -e + +## These variables are automatically bumped. +## If you change their name please change .ci/bump-go-release-version.sh +GOLANG_VERSION=1.17.11 +GOLANG_DOWNLOAD_URL=https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz +GOLANG_DOWNLOAD_SHA256_AMD=d69a4fe2694f795d8e525c72b497ededc209cb7185f4c3b62d7a98dd6227b3fe +GOLANG_DOWNLOAD_SHA256_ARM=adefa7412c6798f9cad02d1e8336fc2242f5bade30c5b32781759181e01961b7 + +GO_TAR_FILE=/tmp/golang.tar.gz + +if [ "$(uname -m)" == "x86_64" ]; then + curl -fsSL "$GOLANG_DOWNLOAD_URL" -o "${GO_TAR_FILE}" + echo "$GOLANG_DOWNLOAD_SHA256_AMD ${GO_TAR_FILE}" | sha256sum -c - +fi + +GOLANG_DOWNLOAD_URL=https://golang.org/dl/go$GOLANG_VERSION.linux-arm64.tar.gz + +if [ "$(uname -m)" != "x86_64" ]; then + curl -fsSL "$GOLANG_DOWNLOAD_URL" -o "${GO_TAR_FILE}" + echo "$GOLANG_DOWNLOAD_SHA256_ARM ${GO_TAR_FILE}" | sha256sum -c - +fi + +tar -C /usr/local -xzf "${GO_TAR_FILE}" +rm "${GO_TAR_FILE}" diff --git a/go/darwin-arm64/Dockerfile.tmpl b/go/darwin-arm64/Dockerfile.tmpl index b189c3d0..00032021 100644 --- a/go/darwin-arm64/Dockerfile.tmpl +++ b/go/darwin-arm64/Dockerfile.tmpl @@ -1,8 +1,23 @@ ARG REPOSITORY ARG VERSION ARG TAG_EXTENSION='' +{{- if or (eq .DEBIAN_VERSION "10") (eq .DEBIAN_VERSION "11")}} +FROM --platform=linux/amd64 docker.elastic.co/beats-dev/golang-crossbuild:llvm-apple-debian{{ .DEBIAN_VERSION }}-amd64 AS build-llvm-apple-amd64 +FROM --platform=linux/arm64 docker.elastic.co/beats-dev/golang-crossbuild:llvm-apple-debian{{ .DEBIAN_VERSION }}-arm64 AS build-llvm-apple-arm64 +# workaround to https://github.com/moby/moby/issues/34482 +ARG TARGETARCH=amd64 +ARG BUILDARCH=amd64 +FROM build-llvm-apple-${TARGETARCH} as build-llvm-apple +ARG TARGETARCH +ARG BUILDARCH +RUN echo "Building ${TARGETARCH} on a ${BUILDARCH}" +{{- end }} FROM ${REPOSITORY}/golang-crossbuild:${VERSION}-base${TAG_EXTENSION} +{{- if and (ne .DEBIAN_VERSION "10") (ne .DEBIAN_VERSION "11")}} +RUN echo "This Docker image will work only with Debian >10" && exit 1 +{{- end }} + RUN \ apt-get -o Acquire::Check-Valid-Until=false update \ && apt-get install -qq -y --no-install-recommends --allow-unauthenticated \ @@ -14,30 +29,18 @@ RUN \ uuid-dev \ && rm -rf /var/lib/apt/lists/* -{{if or (eq .DEBIAN_VERSION "10") (eq .DEBIAN_VERSION "11")}} -ARG OSXCROSS_SDK_URL=https://storage.googleapis.com/obs-ci-cache/beats/MacOSX11.3.sdk.tar.xz -ARG OSXCROSS_PATH=/usr/osxcross -ARG OSXCROSS_REV=035cc170338b7b252e3f13b0e3ccbf4411bffc41 -ARG SDK_VERSION=11.3 -ARG DARWIN_VERSION=20 -ARG OSX_VERSION_MIN=11.3 -{{ else }} -RUN echo "This Docker image will work only with Debian 10" && exit 1 -{{ end }} +COPY --from=build-llvm-apple /llvm-apple-Linux.tar.gz /tmp/llvm-apple-Linux.tar.gz +RUN tar -xzf /tmp/llvm-apple-Linux.tar.gz --strip 1 -C /usr/local \ + && rm /tmp/llvm-apple-Linux.tar.gz -RUN \ - mkdir -p /tmp/osxcross && cd /tmp/osxcross \ - && curl -sSL "https://codeload.github.com/tpoechtrager/osxcross/tar.gz/${OSXCROSS_REV}" \ - | tar -C /tmp/osxcross --strip=1 -xzf - \ - && curl -sSLo "tarballs/MacOSX${SDK_VERSION}.sdk.tar.xz" "${OSXCROSS_SDK_URL}" \ - && UNATTENDED=yes ENABLE_CLANG_INSTALL=yes ./build_clang.sh >/dev/null \ - && UNATTENDED=yes ./build.sh >/dev/null \ - && mv target "${OSXCROSS_PATH}" \ - && rm -rf /tmp/osxcross "/usr/osxcross/SDK/MacOSX${SDK_VERSION}.sdk/usr/share/man" +ARG OSXCROSS_PATH=/usr/local/osxcross +COPY --from=build-llvm-apple /osxcross.tar.gz /tmp/osxcross.tar.gz +RUN tar -xzf /tmp/osxcross.tar.gz -C / \ + && rm /tmp/osxcross.tar.gz ENV PATH $OSXCROSS_PATH/bin:$PATH # Add osxcross libraries to the library PATH -ENV LD_LIBRARY_PATH /usr/osxcross/lib:$LD_LIBRARY_PATH +ENV LD_LIBRARY_PATH $OSXCROSS_PATH/lib:/lib:/usr/lib:/usr/local/lib:$LD_LIBRARY_PATH COPY rootfs / diff --git a/go/darwin-arm64/Makefile b/go/darwin-arm64/Makefile index 0a42375f..62165d32 100644 --- a/go/darwin-arm64/Makefile +++ b/go/darwin-arm64/Makefile @@ -1 +1,10 @@ include ../Makefile.common + +ifeq ($(DOCKER_MULTIARCH),1) +DOCKER_CMD := $(SELF_DIR)/../.ci/scripts/buildx.sh + +push: + @echo "Already done by buildx (.ci/scripts/buildx.sh)." +atomic-push: + @echo "Already done by buildx (.ci/scripts/buildx.sh)." +endif diff --git a/go/darwin/Dockerfile.tmpl b/go/darwin/Dockerfile.tmpl index 25296d44..9d1baa81 100644 --- a/go/darwin/Dockerfile.tmpl +++ b/go/darwin/Dockerfile.tmpl @@ -1,6 +1,17 @@ ARG REPOSITORY ARG VERSION ARG TAG_EXTENSION='' +{{- if or (eq .DEBIAN_VERSION "10") (eq .DEBIAN_VERSION "11")}} +FROM --platform=linux/amd64 docker.elastic.co/beats-dev/golang-crossbuild:llvm-apple-debian{{ .DEBIAN_VERSION }}-amd64 AS build-llvm-apple-amd64 +FROM --platform=linux/arm64 docker.elastic.co/beats-dev/golang-crossbuild:llvm-apple-debian{{ .DEBIAN_VERSION }}-arm64 AS build-llvm-apple-arm64 +# workaround to https://github.com/moby/moby/issues/34482 +ARG TARGETARCH=amd64 +ARG BUILDARCH=amd64 +FROM build-llvm-apple-${TARGETARCH} as build-llvm-apple +ARG TARGETARCH +ARG BUILDARCH +RUN echo "Building ${TARGETARCH} on a ${BUILDARCH}" +{{- end }} FROM ${REPOSITORY}/golang-crossbuild:${VERSION}-base${TAG_EXTENSION} RUN \ @@ -20,22 +31,18 @@ RUN \ uuid-dev \ && rm -rf /var/lib/apt/lists/* -{{if or (eq .DEBIAN_VERSION "10") (eq .DEBIAN_VERSION "11")}} -ARG OSXCROSS_SDK_URL=https://storage.googleapis.com/obs-ci-cache/beats/MacOSX10.14.sdk.tar.xz -ARG OSXCROSS_PATH=/usr/osxcross -ARG OSXCROSS_REV=8a716a43a72dab1db9630d7824ee0af3730cb8f9 -ARG SDK_VERSION=10.14 -ARG DARWIN_VERSION=17 -ARG OSX_VERSION_MIN=10.10 -{{ else }} +{{- if or (eq .DEBIAN_VERSION "10") (eq .DEBIAN_VERSION "11")}} +ARG OSXCROSS_PATH=/usr/local/osxcross +COPY --from=build-llvm-apple /osxcross.tar.gz /tmp/osxcross.tar.gz +RUN tar -xzf /tmp/osxcross.tar.gz -C / \ + && rm /tmp/osxcross.tar.gz +{{- else }} ARG OSXCROSS_SDK_URL=https://storage.googleapis.com/obs-ci-cache/beats/MacOSX10.11.sdk.tar.xz ARG OSXCROSS_PATH=/usr/osxcross ARG OSXCROSS_REV=3034f7149716d815bc473d0a7b35d17e4cf175aa ARG SDK_VERSION=10.11 ARG DARWIN_VERSION=15 ARG OSX_VERSION_MIN=10.10 -{{ end }} - RUN \ mkdir -p /tmp/osxcross && cd /tmp/osxcross \ && curl -sSL "https://codeload.github.com/tpoechtrager/osxcross/tar.gz/${OSXCROSS_REV}" \ @@ -44,27 +51,40 @@ RUN \ && UNATTENDED=yes ./build.sh >/dev/null \ && mv target "${OSXCROSS_PATH}" \ && rm -rf /tmp/osxcross "/usr/osxcross/SDK/MacOSX${SDK_VERSION}.sdk/usr/share/man" +{{- end }} ENV PATH $OSXCROSS_PATH/bin:$PATH # Add osxcross libraries to the library PATH -ENV LD_LIBRARY_PATH /usr/osxcross/lib:$LD_LIBRARY_PATH +ENV LD_LIBRARY_PATH $OSXCROSS_PATH/lib:/lib:/usr/lib:/usr/local/lib:$LD_LIBRARY_PATH COPY rootfs / # Basic test RUN cd / \ - && o64-clang helloWorld.c -o helloWorld \ - && file helloWorld \ - && file helloWorld | grep -c 'Mach-O 64-bit x86_64' + && o64-clang helloWorld.c -o helloWorld.x86_64 \ + && file helloWorld.x86_64 \ + && file helloWorld.x86_64 | grep -c 'Mach-O 64-bit x86_64' + +{{- if or (eq .DEBIAN_VERSION "10") (eq .DEBIAN_VERSION "11")}} +RUN cd / \ + && oa64-clang helloWorld.c -o helloWorld.arm64 \ + && file helloWorld.arm64 \ + && file helloWorld.arm64 | grep -c 'Mach-O 64-bit arm64' + +RUN cd / \ + && lipo -create -output helloWorld.universal helloWorld.x86_64 helloWorld.arm64 \ + && file helloWorld.universal | grep 'Mach-O universal binary' +{{- end }} # MacOSX10.14 SDK does not have 32bits compiler {{if and (ne .DEBIAN_VERSION "10") (ne .DEBIAN_VERSION "11")}} RUN cd / \ - && o32-clang helloWorld.c -o helloWorld \ - && file helloWorld \ - && file helloWorld | grep -c 'Mach-O i386' \ - && rm helloWorld.c helloWorld -{{ end }} + && o32-clang helloWorld.c -o helloWorld.i368 \ + && file helloWorld.i368 \ + && file helloWorld.i368 | grep -c 'Mach-O i386' +{{- end }} + +RUN rm /helloWorld.* # Build-time metadata as defined at http://label-schema.org. ARG BUILD_DATE diff --git a/go/darwin/Makefile b/go/darwin/Makefile index 0a42375f..62165d32 100644 --- a/go/darwin/Makefile +++ b/go/darwin/Makefile @@ -1 +1,10 @@ include ../Makefile.common + +ifeq ($(DOCKER_MULTIARCH),1) +DOCKER_CMD := $(SELF_DIR)/../.ci/scripts/buildx.sh + +push: + @echo "Already done by buildx (.ci/scripts/buildx.sh)." +atomic-push: + @echo "Already done by buildx (.ci/scripts/buildx.sh)." +endif