diff --git a/Makefile b/Makefile index 43552c4e..b7d2735f 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ REF ?= HEAD RUNC_REF ?= dc9208a3303feef5b3839f4323d9beb36df0a9dd GOVERSION ?= 1.12.17 -BUILD_IMAGE ?= centos:7 +BUILD_IMAGE ?= ubuntu:18.04 BUILD_TYPE = $(shell ./scripts/deb-or-rpm $(BUILD_IMAGE)) BUILD_BASE = $(shell ./scripts/determine-base $(BUILD_IMAGE)) PROGRESS = auto @@ -65,6 +65,18 @@ checkout: src @git -C src/github.com/opencontainers/runc checkout -q "$(RUNC_REF)" @git -C src/github.com/containerd/containerd checkout -q "$(REF)" +# NOTE: building static binaries currently only works when using an +# ubuntu/debian BUILD_IMAGE, because build-dependencies are not +# installed beforehand. +.PHONY: static +static: TARGET=binaries +static: build + +# This target is used for building rpm, deb, and static packages: +# +# - If TARGET=static, static binaries are build +# - If TARGET is not specified, the default is either "rpm" or "deb", +# depending on the BUILD_IMAGE .PHONY: build build: checkout build: diff --git a/README.md b/README.md index 98723f9f..0a18cc48 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,13 @@ make docker.io/library/: [docker.io/library/: After build completes, packages can be found in the `build` directory. +To build static binaries: + +```bash +make clean +make static +``` + ## Building a package from a local source directory Specify the path to the local source directory using `CONTAINERD_DIR` and/or diff --git a/dockerfiles/deb.dockerfile b/dockerfiles/deb.dockerfile index 00c0dc21..1910da01 100644 --- a/dockerfiles/deb.dockerfile +++ b/dockerfiles/deb.dockerfile @@ -61,6 +61,7 @@ RUN apt-get update -q \ && apt-get clean \ && rm -rf /var/cache/apt /var/lib/apt/lists/* COPY scripts/build-deb /root/ +COPY scripts/build-static /root/ COPY scripts/.helpers /root/ ARG PACKAGE @@ -100,6 +101,26 @@ FROM scratch AS packages COPY --from=build-packages /archive /archive COPY --from=verify-packages /build /build +FROM build-env AS build-binaries +# NOTE: not using a cache-mount for /root/.cache/go-build, to prevent issues +# with CGO when building multiple distros on the same machine / build-cache +RUN --mount=type=bind,from=golang,source=/usr/local/go/,target=/usr/local/go/ \ + --mount=type=bind,source=/src,target=/go/src,rw \ + /root/build-static +ARG UID=0 +ARG GID=0 +RUN chown -R ${UID}:${GID} /build + +FROM distro-image AS verify-binaries +COPY --from=build-binaries /build /build +RUN tar -C /usr/local/bin/ --strip-components 1 -xzf "$(find /build/static -type f -name containerd.io*.tar.gz)" +RUN containerd --version +RUN ctr --version +RUN runc --version + +FROM scratch AS binaries +COPY --from=verify-binaries /build /build + # This stage is mainly for debugging (running the build interactively with mounted source) FROM build-env AS runtime COPY --from=golang /usr/local/go/ /usr/local/go/ diff --git a/dockerfiles/rpm.dockerfile b/dockerfiles/rpm.dockerfile index d170942b..cc51d814 100644 --- a/dockerfiles/rpm.dockerfile +++ b/dockerfiles/rpm.dockerfile @@ -71,7 +71,8 @@ COPY --from=go-md2man /go/bin/go-md2man /go/bin/go-md2man COPY rpm/containerd.spec SPECS/containerd.spec COPY scripts/build-rpm /root/ COPY scripts/.rpm-helpers /root/ -RUN . /root/.rpm-helpers; install_build_deps SPECS/containerd.spec +RUN . /root/.rpm-helpers \ + && install_build_deps SPECS/containerd.spec ARG PACKAGE ENV PACKAGE=${PACKAGE:-containerd.io} diff --git a/scripts/build-static b/scripts/build-static new file mode 100755 index 00000000..f912ceed --- /dev/null +++ b/scripts/build-static @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# Copyright 2018-2020 Docker Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +VERSION="$(git --git-dir "${GO_SRC_PATH}/.git" describe --tags | sed 's/^v//')" +# Check if we're on a tagged version, change VERSION to dev build if not +if ! git --git-dir "${GO_SRC_PATH}/.git" describe --exact-match HEAD >/dev/null 2>&1; then + git_date=$(date --date "@$(git --git-dir "${GO_SRC_PATH}/.git" log -1 --pretty='%at')" +'%Y%m%d.%H%M%S') + git_sha=$(git --git-dir "${GO_SRC_PATH}/.git" log -1 --pretty='%h') + VERSION="${git_date}~${git_sha}" +fi + +ARCH=$(uname -m) +DEST_DIR="/build/static/${ARCH}/" +mkdir -p "${DEST_DIR}" + +# Build containerd +( + set -x + export BUILDTAGS='netgo osusergo static_build seccomp apparmor selinux' + export EXTRA_FLAGS='-buildmode=pie' + export EXTRA_LDFLAGS='-extldflags "-fno-PIC -static"' + + make -C "/go/src/github.com/containerd/containerd" + make -C "/go/src/github.com/containerd/containerd" DESTDIR="${DEST_DIR}" install +) + +# Build runc +( + set -x + RUNC_BUILDTAGS="seccomp apparmor selinux" + make -C "/go/src/github.com/opencontainers/runc" BUILDTAGS="${RUNC_BUILDTAGS}" static + install -D -p -t "${DEST_DIR}/bin" "/go/src/github.com/opencontainers/runc/runc" +) + +tar -C "${DEST_DIR}" --exclude=containerd-stress -czf "${DEST_DIR}/containerd.io-${VERSION}.linux-${ARCH}.tar.gz" "bin/" +rm -r "${DEST_DIR:?}/bin/"