diff --git a/Makefile b/Makefile index 3d3d1ed9b..a7f78b5df 100644 --- a/Makefile +++ b/Makefile @@ -51,9 +51,9 @@ build: setup build-windows: setup CGO_ENABLED=0 GOOS=windows go build -a -ldflags ${LDFLAGS} -o _output/secrets-store-csi.exe ./cmd/secrets-store-csi-driver image: - docker buildx build --no-cache --build-arg LDFLAGS=${LDFLAGS} -t $(IMAGE_TAG) -f Dockerfile --platform="linux/amd64" --output "type=docker,push=false" . + docker buildx build --no-cache --build-arg LDFLAGS=${LDFLAGS} -t $(IMAGE_TAG) -f docker/Dockerfile --platform="linux/amd64" --output "type=docker,push=false" . image-windows: - docker buildx build --no-cache --build-arg LDFLAGS=${LDFLAGS} -t $(IMAGE_TAG) -f windows.Dockerfile --platform="windows/amd64" --output "type=docker,push=false" . + docker buildx build --no-cache --build-arg LDFLAGS=${LDFLAGS} -t $(IMAGE_TAG) -f docker/windows.Dockerfile --platform="windows/amd64" --output "type=docker,push=false" . clean: -rm -rf _output setup: clean diff --git a/docker/BASEIMAGE b/docker/BASEIMAGE new file mode 100644 index 000000000..aa426f0f0 --- /dev/null +++ b/docker/BASEIMAGE @@ -0,0 +1,4 @@ +linux/amd64=us.gcr.io/k8s-artifacts-prod/build-image/debian-base-amd64:v2.1.0 +windows/amd64/1809=mcr.microsoft.com/windows/nanoserver:1809 +windows/amd64/1903=mcr.microsoft.com/windows/nanoserver:1903 +windows/amd64/1909=mcr.microsoft.com/windows/nanoserver:1909 diff --git a/docker/BASEIMAGE_CORE b/docker/BASEIMAGE_CORE new file mode 100644 index 000000000..e6b992bd4 --- /dev/null +++ b/docker/BASEIMAGE_CORE @@ -0,0 +1,3 @@ +windows/amd64/1809=mcr.microsoft.com/windows/servercore:1809 +windows/amd64/1903=mcr.microsoft.com/windows/servercore:1903 +windows/amd64/1909=mcr.microsoft.com/windows/servercore:1909 diff --git a/Dockerfile b/docker/Dockerfile similarity index 85% rename from Dockerfile rename to docker/Dockerfile index 60438dc54..8c1d0b6ee 100644 --- a/Dockerfile +++ b/docker/Dockerfile @@ -1,3 +1,5 @@ +ARG BASEIMAGE=us.gcr.io/k8s-artifacts-prod/build-image/debian-base-amd64:v2.1.0 + FROM golang:1.13.10-alpine3.10 as builder WORKDIR /go/src/sigs.k8s.io/secrets-store-csi-driver ADD . . @@ -6,7 +8,7 @@ ARG TARGETOS ARG LDFLAGS RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -a -ldflags "${LDFLAGS}" -o _output/secrets-store-csi ./cmd/secrets-store-csi-driver -FROM us.gcr.io/k8s-artifacts-prod/build-image/debian-base-amd64:v2.1.0 +FROM $BASEIMAGE COPY --from=builder /go/src/sigs.k8s.io/secrets-store-csi-driver/_output/secrets-store-csi /secrets-store-csi RUN clean-install ca-certificates cifs-utils mount diff --git a/docker/Makefile b/docker/Makefile new file mode 100644 index 000000000..51c1eb4a5 --- /dev/null +++ b/docker/Makefile @@ -0,0 +1,30 @@ +# Copyright 2020 The Kubernetes Authors. +# +# 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. + +REGISTRY?=docker.io/deislabs +IMAGE_NAME=driver +IMAGE_VERSION?=v0.0.10 +IMAGE_TAG=$(REGISTRY)/$(IMAGE_NAME):$(IMAGE_VERSION) +export + +DOCKER_CLI_EXPERIMENTAL = enabled + +build-and-push: + bash -x ./build.sh build_and_push + +manifest: build-and-push + bash -x ./build.sh manifest + +.PHONY: build-and-push manifest + diff --git a/docker/build.sh b/docker/build.sh new file mode 100755 index 000000000..0f8b8f8c5 --- /dev/null +++ b/docker/build.sh @@ -0,0 +1,147 @@ +#!/usr/bin/env bash + +# Copyright 2020 The Kubernetes Authors. +# +# 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 -o errexit +set -o nounset +set -o pipefail + +TASK=$1 + +pushd `dirname "$0"` + +LDFLAGS="-X sigs.k8s.io/secrets-store-csi-driver/pkg/secrets-store.vendorVersion=${IMAGE_VERSION} -extldflags '-static'" + +# Returns list of all supported architectures from the BASEIMAGE file +listOsArchs() { + cut -d "=" -f 1 BASEIMAGE +} + +splitOsArch() { + os_arch=$1 + + if [[ $os_arch =~ .*/.*/.* ]]; then + # for Windows, we have to support both LTS and SAC channels, so we're building multiple Windows images. + # the format for this case is: OS/ARCH/OS_VERSION. + os_name=$(echo "$os_arch" | cut -d "/" -f 1) + arch=$(echo "$os_arch" | cut -d "/" -f 2) + os_version=$(echo "$os_arch" | cut -d "/" -f 3) + suffix="$os_name-$arch-$os_version" + elif [[ $os_arch =~ .*/.* ]]; then + os_name=$(echo "$os_arch" | cut -d "/" -f 1) + arch=$(echo "$os_arch" | cut -d "/" -f 2) + suffix="$os_name-$arch" + else + echo "The BASEIMAGE file is not properly formatted. Expected entries to start with 'os/arch', found '${os_arch}' instead." + exit 1 + fi +} + +# Returns baseimage need to used in Dockerfile for any given architecture +getBaseImage() { + os_arch=$1 + file=${2:-BASEIMAGE} + grep "${os_arch}=" "${file}" | cut -d= -f2 +} + +docker_version_check() { + # The reason for this version check is even though "docker manifest" command is available in 18.03, it does + # not work properly in that version. So we insist on 18.06.0 or higher. + # docker buildx has been introduced in 19.03, so we need to make sure we have it. + docker_version=$(docker version --format '{{.Client.Version}}' | cut -d"-" -f1) + if [[ ${docker_version} != 19.03.0 && ${docker_version} < 19.03.0 ]]; then + echo "Minimum docker version 19.03.0 is required for using docker buildx: ${docker_version}]" + exit 1 + fi +} + +# This function will build and push the image for all the architectures mentioned in BASEIMAGE file. +build_and_push() { + docker_version_check + + docker buildx create --name img-builder --use + trap "docker buildx rm img-builder" EXIT + + os_archs=$(listOsArchs) + for os_arch in ${os_archs}; do + splitOsArch "${os_arch}" + + echo "Building / pushing image for OS/ARCH: ${os_arch}..." + + dockerfile_name="Dockerfile" + if [[ "$os_name" = "windows" ]]; then + dockerfile_name="windows.Dockerfile" + fi + + BASEIMAGE=$(getBaseImage "${os_arch}") + + # We only have BASEIMAGE_CORE for Windows images. + BASEIMAGE_CORE=$(getBaseImage "${os_arch}" "BASEIMAGE_CORE") || true + + # NOTE(claudiub): docker buildx works for Windows images as long as there are no RUN commands in the Dockerfile. + docker buildx build --no-cache --pull --push --platform "${os_name}/${arch}" -t "${IMAGE_TAG}-${suffix}" \ + --build-arg BASEIMAGE="${BASEIMAGE}" --build-arg BASEIMAGE_CORE="${BASEIMAGE_CORE}" \ + --build-arg TARGETARCH="${arch}" --build-arg TARGETOS="${os_name}" --build-arg LDFLAGS="${LDFLAGS}" \ + -f "${dockerfile_name}" .. + done +} + +ensure_manifest_tool() { + if ! [[ -x "$(command -v manifest-tool)" ]]; then + wget "https://github.com/estesp/manifest-tool/releases/download/v1.0.2/manifest-tool-linux-amd64" -O /usr/bin/manifest-tool + chmod +x /usr/bin/manifest-tool + fi +} + +# This function will create and push the manifest list for the image +manifest() { + ensure_manifest_tool + + echo "Building manifest list .yaml file for ${IMAGE_TAG}" + echo "image: ${IMAGE_TAG}" > manifest.yaml + echo "manifests:" >> manifest.yaml + trap "rm manifest.yaml" EXIT + + os_archs=$(listOsArchs) + for os_arch in ${os_archs}; do + splitOsArch "${os_arch}" + + echo " +- image: ${IMAGE_TAG}-${suffix} + platform: + architecture: ${arch} + os: ${os_name}" >> manifest.yaml + + # For Windows images, we also need to include the "os.version" in the manifest list, so the Windows node + # can pull the proper image it needs. + if [[ "$os_name" = "windows" ]]; then + BASEIMAGE=$(getBaseImage "${os_arch}") + # Getting the full OS version from the original image. The manifest-tool output looks like: + # 1 - OS Vers: 10.0.17763.1217 + full_version=$(manifest-tool inspect ${BASEIMAGE} | grep 'OS Vers' | head -n 1 | awk '{print $5}') || true + + # manifest-tool handles osversion as os.version + echo " osversion: ${full_version}" >> manifest.yaml + fi + done + + echo "Manifest list .yaml file:" + cat manifest.yaml + + manifest-tool push from-spec manifest.yaml +} + +shift +eval "${TASK}" diff --git a/docker/cloudbuild.yaml b/docker/cloudbuild.yaml new file mode 100644 index 000000000..e268dfdd8 --- /dev/null +++ b/docker/cloudbuild.yaml @@ -0,0 +1,26 @@ +# See https://cloud.google.com/cloud-build/docs/build-config + +# this must be specified in seconds. If omitted, defaults to 600s (10 mins) +timeout: 1200s +# this prevents errors if you don't use both _GIT_TAG and _PULL_BASE_REF, +# or any new substitutions added in the future. +options: + substitution_option: ALLOW_LOOSE +steps: + - name: 'gcr.io/k8s-testimages/gcb-docker-gcloud:v20200422-b25d964' + entrypoint: make + dir: ./docker + env: + - DOCKER_CLI_EXPERIMENTAL=enabled + - TAG=$_GIT_TAG + - BASE_REF=$_PULL_BASE_REF + - REGISTRY=gcr.io/k8s-staging-csi-secrets-store + args: + - manifest +substitutions: + # _GIT_TAG will be filled with a git-based tag for the image, of the form vYYYYMMDD-hash, and + # can be used as a substitution + _GIT_TAG: '12345' + # _PULL_BASE_REF will contain the ref that was pushed to to trigger this build - + # a branch like 'master' or 'release-0.2', or a tag like 'v0.2'. + _PULL_BASE_REF: 'master' diff --git a/windows.Dockerfile b/docker/windows.Dockerfile similarity index 80% rename from windows.Dockerfile rename to docker/windows.Dockerfile index 6baa310e4..cb084a918 100644 --- a/windows.Dockerfile +++ b/docker/windows.Dockerfile @@ -1,3 +1,6 @@ +ARG BASEIMAGE=mcr.microsoft.com/windows/nanoserver:1809 +ARG BASEIMAGE_CORE=mcr.microsoft.com/windows/servercore:1809 + FROM --platform=$BUILDPLATFORM golang:1.13.10-alpine3.10 as builder WORKDIR /go/src/sigs.k8s.io/secrets-store-csi-driver ADD . . @@ -8,7 +11,8 @@ RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -a -ldflags "${LDFL FROM mcr.microsoft.com/windows/servercore:1809 as core -FROM mcr.microsoft.com/windows/nanoserver:1809 +FROM $BASEIMAGE_CORE as core +FROM $BASEIMAGE LABEL description="Secrets Store CSI Driver" COPY --from=builder /go/src/sigs.k8s.io/secrets-store-csi-driver/_output/secrets-store-csi.exe /secrets-store-csi.exe