diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8f0ea39f..6cdc18c3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,45 +1,104 @@ -image: docker:latest - -services: - - docker:dind +# Build packages for all supported OS / ARCH combinations stages: - - build + - build-one + - build-all -.build_template: &build_definition - stage: build - script: - - OS="${CI_JOB_NAME#*:}" - - apk add make +.build-setup: &build-setup + image: docker:19.03.8 + + services: + - name: docker:19.03.8-dind + command: ["--experimental"] + + before_script: + - apk update + - apk upgrade + - apk add coreutils build-base sed git bash make + - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes -c yes + +# build-one jobs build packages for a single OS / ARCH combination. +# +# They are run during the first stage of the pipeline as a smoke test to ensure +# that we can successfully build packages on all of our architectures for a +# single OS. They are triggered on any change to an MR. No artifacts are +# produced as part of build-one jobs. +.build-one-setup: &build-one-setup + <<: *build-setup + stage: build-one + only: + - merge_requests + +# build-all jobs build packages for every OS / ARCH combination we support. +# +# They are run under two conditions: +# 1) Automatically whenever a new tag is pushed to the repo (e.g. v1.1.0) +# 2) Manually by a reviewer just before merging a MR. +# +# Unlike build-one jobs, it takes a long time to build the full suite +# OS / ARCH combinations, so this is optimized to only run once per MR +# (assuming it all passes). A full set of artifacts including the packages +# built for each OS / ARCH are produced as a result of these jobs. +.build-all-setup: &build-all-setup + <<: *build-setup + stage: build-all + timeout: 2h 30m + rules: + - if: $CI_COMMIT_TAG + when: always + - if: $CI_MERGE_REQUEST_ID + when: manual + + variables: + ARTIFACTS_NAME: "${CI_PROJECT_NAME}-${CI_COMMIT_REF_SLUG}-${CI_JOB_NAME}-artifacts-${CI_PIPELINE_ID}" + ARTIFACTS_DIR: "${CI_PROJECT_NAME}-${CI_COMMIT_REF_SLUG}-artifacts-${CI_PIPELINE_ID}" + DIST_DIR: "${CI_PROJECT_DIR}/${ARTIFACTS_DIR}" - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - - make REGISTRY=${CI_REGISTRY_IMAGE} ${OS} - - make REGISTRY=${CI_REGISTRY_IMAGE} push${OS} artifacts: - expire_in: 1 week + name: ${ARTIFACTS_NAME} paths: - - dist/ + - ${ARTIFACTS_DIR} -amd64:amzn1: - <<: *build_definition +# The full set of build-one jobs organizes to build +# ubuntu18.04 in parallel on each of our supported ARCHs. +build-one-amd64: + <<: *build-one-setup + script: + - make ubuntu18.04-amd64 -amd64:amzn2: - <<: *build_definition +build-one-ppc64le: + <<: *build-one-setup + script: + - make ubuntu18.04-ppc64le -amd64:centos7: - <<: *build_definition +build-one-arm64: + <<: *build-one-setup + script: + - make ubuntu18.04-arm64 -amd64:opensuse-leap15.1: - <<: *build_definition +# The full set of build-all jobs organized to +# have builds for each ARCH run in parallel. +build-all-amd64: + <<: *build-all-setup + script: + - make docker-amd64 -amd64:debian9: - <<: *build_definition +build-all-x86_64: + <<: *build-all-setup + script: + - make docker-x86_64 -amd64:debian10: - <<: *build_definition +build-all-ppc64le: + <<: *build-all-setup + script: + - make docker-ppc64le -amd64:ubuntu16.04: - <<: *build_definition +build-all-arm64: + <<: *build-all-setup + script: + - make docker-arm64 -amd64:ubuntu18.04: - <<: *build_definition +build-all-aarch64: + <<: *build-all-setup + script: + - make docker-aarch64 diff --git a/Makefile b/Makefile index 8f79e091..72fa84e6 100644 --- a/Makefile +++ b/Makefile @@ -2,20 +2,17 @@ DOCKER ?= docker MKDIR ?= mkdir -REGISTRY ?= nvidia/container-toolkit +DIST_DIR ?= $(CURDIR)/dist + +LIB_NAME := nvidia-container-toolkit +LIB_VERSION := 1.0.5 GOLANG_VERSION := 1.14.2 -VERSION := 1.0.5 -DIST_DIR := $(CURDIR)/dist - -TOOLKIT=nvidia-container-toolkit +GOLANG_PKG_PATH := github.com/NVIDIA/container-toolkit/pkg +# By default run all native docker-based targets +docker-native: include $(CURDIR)/docker.mk -.PHONY: all - -all: ubuntu18.04 ubuntu16.04 debian10 debian9 centos7 amzn2 amzn1 opensuse-leap15.1 - binary: - go build -ldflags "-s -w" -o "$(TOOLKIT)" github.com/NVIDIA/container-toolkit/pkg - + go build -ldflags "-s -w" -o "$(LIB_NAME)" $(GOLANG_PKG_PATH) diff --git a/docker.mk b/docker.mk index c9df9eb2..23f9bc8f 100644 --- a/docker.mk +++ b/docker.mk @@ -1,74 +1,128 @@ # Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. -push%: - docker push "$(REGISTRY)/$*" +# Supported OSs by architecture +AMD64_TARGETS := ubuntu20.04 ubuntu18.04 ubuntu16.04 debian10 debian9 +X86_64_TARGETS := centos7 centos8 rhel7 rhel8 amazonlinux1 amazonlinux2 opensuse-leap15.1 +PPC64LE_TARGETS := ubuntu18.04 ubuntu16.04 centos7 centos8 rhel7 rhel8 +ARM64_TARGETS := ubuntu20.04 ubuntu18.04 +AARCH64_TARGETS := centos8 rhel8 -ubuntu%: ARCH := amd64 -ubuntu%: - $(DOCKER) build --pull \ - --build-arg GOLANG_VERSION="$(GOLANG_VERSION)" \ - --build-arg VERSION_ID="$*" \ - --build-arg PKG_VERS="$(VERSION)" \ - --build-arg PKG_REV="1" \ - --tag "$(REGISTRY)/ubuntu$*" \ - --file docker/Dockerfile.ubuntu . - $(MKDIR) -p $(DIST_DIR)/$@/$(ARCH) - $(DOCKER) run --cidfile $@.cid "$(REGISTRY)/ubuntu$*" - $(DOCKER) cp $$(cat $@.cid):/dist/. $(DIST_DIR)/$@/$(ARCH)/ - $(DOCKER) rm $$(cat $@.cid) && rm $@.cid +# Define top-level build targets +docker%: SHELL:=/bin/bash -debian%: ARCH := amd64 -debian%: - $(DOCKER) build --pull \ - --build-arg GOLANG_VERSION="$(GOLANG_VERSION)" \ - --build-arg VERSION_ID="$*" \ - --build-arg PKG_VERS="$(VERSION)" \ - --build-arg PKG_REV="1" \ - --tag "$(REGISTRY)/debian$*" \ - --file docker/Dockerfile.debian . - $(MKDIR) -p $(DIST_DIR)/$@/$(ARCH) - $(DOCKER) run --cidfile $@.cid "$(REGISTRY)/debian$*" - $(DOCKER) cp $$(cat $@.cid):/dist/. $(DIST_DIR)/$@/$(ARCH)/ - $(DOCKER) rm $$(cat $@.cid) && rm $@.cid +# Native targets +PLATFORM ?= $(shell uname -m) +ifeq ($(PLATFORM),x86_64) +NATIVE_TARGETS := $(AMD64_TARGETS) $(X86_64_TARGETS) +$(AMD64_TARGETS): %: %-amd64 +$(X86_64_TARGETS): %: %-x86_64 +else ifeq ($(PLATFORM),ppc64le) +NATIVE_TARGETS := $(PPC64LE_TARGETS) +$(PPC64LE_TARGETS): %: %-ppc64le +else ifeq ($(PLATFORM),aarch64) +NATIVE_TARGETS := $(ARM64_TARGETS) $(AARCH64_TARGETS) +$(ARM64_TARGETS): %: %-arm64 +$(AARCH64_TARGETS): %: %-aarch64 +endif +docker-native: $(NATIVE_TARGETS) -centos%: ARCH := x86_64 -centos%: - $(DOCKER) build --pull \ - --build-arg GOLANG_VERSION="$(GOLANG_VERSION)" \ - --build-arg VERSION_ID="$*" \ - --build-arg PKG_VERS="$(VERSION)" \ - --build-arg PKG_REV="2" \ - --tag "$(REGISTRY)/centos$*" \ - --file docker/Dockerfile.centos . - $(MKDIR) -p $(DIST_DIR)/$@/$(ARCH) - $(DOCKER) run --cidfile $@.cid "$(REGISTRY)/centos$*" - $(DOCKER) cp $$(cat $@.cid):/dist/. $(DIST_DIR)/$@/$(ARCH)/ - $(DOCKER) rm $$(cat $@.cid) && rm $@.cid +# amd64 targets +AMD64_TARGETS := $(patsubst %, %-amd64, $(AMD64_TARGETS)) +$(AMD64_TARGETS): ARCH := amd64 +$(AMD64_TARGETS): %: --% +docker-amd64: $(AMD64_TARGETS) -amzn%: ARCH := x86_64 -amzn%: - $(DOCKER) build --pull \ - --build-arg GOLANG_VERSION="$(GOLANG_VERSION)" \ - --build-arg VERSION_ID="$*" \ - --build-arg PKG_VERS="$(VERSION)" \ - --build-arg PKG_REV="2.amzn$*" \ - --tag "$(REGISTRY)/amzn$*" \ - --file docker/Dockerfile.amzn . - $(MKDIR) -p $(DIST_DIR)/$@/$(ARCH) - $(DOCKER) run --cidfile $@.cid "$(REGISTRY)/amzn$*" - $(DOCKER) cp $$(cat $@.cid):/dist/. $(DIST_DIR)/$@/$(ARCH)/ - $(DOCKER) rm $$(cat $@.cid) && rm $@.cid +# x86_64 targets +X86_64_TARGETS := $(patsubst %, %-x86_64, $(X86_64_TARGETS)) +$(X86_64_TARGETS): ARCH := x86_64 +$(X86_64_TARGETS): %: --% +docker-x86_64: $(X86_64_TARGETS) -opensuse-leap%: ARCH := x86_64 -opensuse-leap%: - $(DOCKER) build --pull \ - --build-arg GOLANG_VERSION="$(GOLANG_VERSION)" \ - --build-arg VERSION_ID="$*" \ - --build-arg PKG_VERS="$(VERSION)" \ - --build-arg PKG_REV="1" \ - --tag "$(REGISTRY)/opensuse-leap$*" \ - --file docker/Dockerfile.opensuse-leap . - $(MKDIR) -p $(DIST_DIR)/$@/$(ARCH) - $(DOCKER) run --cidfile $@.cid "$(REGISTRY)/opensuse-leap$*" - $(DOCKER) cp $$(cat $@.cid):/dist/. $(DIST_DIR)/$@/$(ARCH)/ - $(DOCKER) rm $$(cat $@.cid) && rm $@.cid +# arm64 targets +ARM64_TARGETS := $(patsubst %, %-arm64, $(ARM64_TARGETS)) +$(ARM64_TARGETS): ARCH := arm64 +$(ARM64_TARGETS): %: --% +docker-arm64: $(ARM64_TARGETS) + +# aarch64 targets +AARCH64_TARGETS := $(patsubst %, %-aarch64, $(AARCH64_TARGETS)) +$(AARCH64_TARGETS): ARCH := aarch64 +$(AARCH64_TARGETS): %: --% +docker-aarch64: $(AARCH64_TARGETS) + +# ppc64le targets +PPC64LE_TARGETS := $(patsubst %, %-ppc64le, $(PPC64LE_TARGETS)) +$(PPC64LE_TARGETS): ARCH := ppc64le +$(PPC64LE_TARGETS): WITH_LIBELF := yes +$(PPC64LE_TARGETS): %: --% +docker-ppc64le: $(PPC64LE_TARGETS) + +# docker target to build for all os/arch combinations +docker-all: $(AMD64_TARGETS) $(X86_64_TARGETS) \ + $(ARM64_TARGETS) $(AARCH64_TARGETS) \ + $(PPC64LE_TARGETS) + +# Default variables for all private '--' targets below. +# One private target is defined for each OS we support. +--%: TARGET_PLATFORM = $(*) +--%: VERSION = $(patsubst $(OS)%-$(ARCH),%,$(TARGET_PLATFORM)) +--%: BASEIMAGE = $(OS):$(VERSION) +--%: BUILDIMAGE = nvidia/$(LIB_NAME)/$(OS)$(VERSION)-$(ARCH) +--%: DOCKERFILE = $(CURDIR)/docker/Dockerfile.$(OS) +--%: ARTIFACTS_DIR = $(DIST_DIR)/$(OS)$(VERSION)/$(ARCH) +--%: docker-build-% + @ + +# private ubuntu target +--ubuntu%: OS := ubuntu +--ubuntu%: PKG_REV := 1 + +# private debian target +--debian%: OS := debian +--debian%: PKG_REV := 1 + +# private centos target +--centos%: OS := centos +--centos%: PKG_REV := 2 + +# private amazonlinux target +--amazonlinux%: OS := amazonlinux +--amazonlinux%: PKG_REV = 2.amzn$(VERSION) + +# private opensuse-leap target +--opensuse-leap%: OS = opensuse-leap +--opensuse-leap%: BASEIMAGE = opensuse/leap:$(VERSION) +--opensuse-leap%: PKG_REV := 1 + +# private rhel target (actually built on centos) +--rhel%: OS := centos +--rhel%: PKG_REV := 2 +--rhel%: VERSION = $(patsubst rhel%-$(ARCH),%,$(TARGET_PLATFORM)) +--rhel%: ARTIFACTS_DIR = $(DIST_DIR)/rhel$(VERSION)/$(ARCH) + +docker-build-%: + @echo "Building for $(TARGET_PLATFORM)" + docker pull --platform=linux/$(ARCH) $(BASEIMAGE) + DOCKER_BUILDKIT=1 \ + $(DOCKER) build \ + --progress=plain \ + --build-arg BASEIMAGE=$(BASEIMAGE) \ + --build-arg GOLANG_VERSION="$(GOLANG_VERSION)" \ + --build-arg PKG_VERS="$(LIB_VERSION)" \ + --build-arg PKG_REV="$(PKG_REV)" \ + --tag $(BUILDIMAGE) \ + --file $(DOCKERFILE) . + $(DOCKER) run \ + -e DISTRIB \ + -e SECTION \ + -v $(ARTIFACTS_DIR):/dist \ + $(BUILDIMAGE) + +docker-clean: + IMAGES=$$(docker images "nvidia/$(LIB_NAME)/*" --format="{{.ID}}"); \ + if [ "$${IMAGES}" != "" ]; then \ + docker rmi -f $${IMAGES}; \ + fi + +distclean: + rm -rf $(DIST_DIR) diff --git a/docker/Dockerfile.amzn b/docker/Dockerfile.amazonlinux similarity index 97% rename from docker/Dockerfile.amzn rename to docker/Dockerfile.amazonlinux index 1337405f..46af3780 100644 --- a/docker/Dockerfile.amzn +++ b/docker/Dockerfile.amazonlinux @@ -1,5 +1,5 @@ -ARG VERSION_ID -FROM amazonlinux:${VERSION_ID} +ARG BASEIMAGE +FROM ${BASEIMAGE} RUN yum install -y \ ca-certificates \ diff --git a/docker/Dockerfile.centos b/docker/Dockerfile.centos index bbe72cb1..ee1ec486 100644 --- a/docker/Dockerfile.centos +++ b/docker/Dockerfile.centos @@ -1,5 +1,5 @@ -ARG VERSION_ID -FROM centos:${VERSION_ID} +ARG BASEIMAGE +FROM ${BASEIMAGE} RUN yum install -y \ ca-certificates \ diff --git a/docker/Dockerfile.debian b/docker/Dockerfile.debian index 3b073c2f..29c1329d 100644 --- a/docker/Dockerfile.debian +++ b/docker/Dockerfile.debian @@ -1,6 +1,7 @@ -ARG VERSION_ID -FROM debian:${VERSION_ID} +ARG BASEIMAGE +FROM ${BASEIMAGE} +ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ wget \ ca-certificates \ diff --git a/docker/Dockerfile.opensuse-leap b/docker/Dockerfile.opensuse-leap index ef7a71ee..c9ac070a 100644 --- a/docker/Dockerfile.opensuse-leap +++ b/docker/Dockerfile.opensuse-leap @@ -1,5 +1,5 @@ -ARG VERSION_ID -FROM opensuse/leap:${VERSION_ID} +ARG BASEIMAGE +FROM ${BASEIMAGE} RUN zypper install -y \ ca-certificates \ diff --git a/docker/Dockerfile.ubuntu b/docker/Dockerfile.ubuntu index 45577028..649cdf3a 100644 --- a/docker/Dockerfile.ubuntu +++ b/docker/Dockerfile.ubuntu @@ -1,6 +1,7 @@ -ARG VERSION_ID -FROM ubuntu:${VERSION_ID} +ARG BASEIMAGE +FROM ${BASEIMAGE} +ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ wget \ ca-certificates \