mirror of
https://github.com/coder/coder.git
synced 2025-03-14 10:09:57 +00:00
This PR fixes the SBOM filename generation in the Docker build script to properly handle image tags that contain slashes. The current implementation only replaces colons with underscores, but fails when image tags include slashes (common in registry paths). The fix updates the string replacement to handle both colons and slashes in the image tag when generating the SBOM filename. Change-Id: Ifd7bad6d165393e11202e5bf070a4cb26eaa6a6a Signed-off-by: Thomas Kosiewski <tk@coder.com> Signed-off-by: Thomas Kosiewski <tk@coder.com>
170 lines
4.0 KiB
Bash
Executable File
170 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# This script builds a Docker image of Coder containing the given binary, for
|
|
# the given architecture. Only linux binaries are supported at this time.
|
|
#
|
|
# Usage: ./build_docker.sh --arch amd64 [--version 1.2.3] [--target image_tag] [--build-base image_tag] [--push] path/to/coder
|
|
#
|
|
# The --arch parameter is required and accepts a Golang arch specification. It
|
|
# will be automatically mapped to a suitable architecture that Docker accepts
|
|
# before being passed to `docker buildx build`.
|
|
#
|
|
# The --build-base parameter is optional and specifies to build the base image
|
|
# in Dockerfile.base instead of pulling a copy from the registry. The string
|
|
# value is the tag to use for the built image (not pushed). This also consumes
|
|
# $CODER_IMAGE_BUILD_BASE_TAG for easily forcing a fresh build in CI.
|
|
#
|
|
# The default base image can be controlled via $CODER_BASE_IMAGE_TAG.
|
|
#
|
|
# The image will be built and tagged against the image tag returned by
|
|
# ./image_tag.sh unless a --target parameter is supplied.
|
|
#
|
|
# If no version is specified, defaults to the version from ./version.sh.
|
|
#
|
|
# If the --push parameter is supplied, the image will be pushed.
|
|
#
|
|
# Prints the image tag on success.
|
|
|
|
set -euo pipefail
|
|
# shellcheck source=scripts/lib.sh
|
|
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
|
|
|
DEFAULT_BASE="${CODER_BASE_IMAGE_TAG:-ghcr.io/coder/coder-base:latest}"
|
|
|
|
arch=""
|
|
image_tag=""
|
|
build_base="${CODER_IMAGE_BUILD_BASE_TAG:-}"
|
|
version=""
|
|
push=0
|
|
|
|
args="$(getopt -o "" -l arch:,target:,build-base:,version:,push -- "$@")"
|
|
eval set -- "$args"
|
|
while true; do
|
|
case "$1" in
|
|
--arch)
|
|
arch="$2"
|
|
shift 2
|
|
;;
|
|
--target)
|
|
image_tag="$2"
|
|
shift 2
|
|
;;
|
|
--version)
|
|
version="$2"
|
|
shift 2
|
|
;;
|
|
--build-base)
|
|
build_base="$2"
|
|
shift 2
|
|
;;
|
|
--push)
|
|
push=1
|
|
shift
|
|
;;
|
|
--)
|
|
shift
|
|
break
|
|
;;
|
|
*)
|
|
error "Unrecognized option: $1"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [[ "$arch" == "" ]]; then
|
|
error "The --arch parameter is required"
|
|
fi
|
|
|
|
# Check dependencies
|
|
dependencies docker
|
|
|
|
# Remove the "v" prefix.
|
|
version="${version#v}"
|
|
if [[ "$version" == "" ]]; then
|
|
version="$(execrelative ./version.sh)"
|
|
fi
|
|
|
|
if [[ "$image_tag" == "" ]]; then
|
|
image_tag="$(execrelative ./image_tag.sh --arch "$arch" --version="$version")"
|
|
fi
|
|
|
|
if [[ "$#" != 1 ]]; then
|
|
error "Exactly one argument must be provided to this script, $# were supplied"
|
|
fi
|
|
if [[ ! -f "$1" ]]; then
|
|
error "File '$1' does not exist or is not a regular file"
|
|
fi
|
|
input_file="$(realpath "$1")"
|
|
|
|
# Remap the arch from Golang to Docker.
|
|
declare -A arch_map=(
|
|
[amd64]="linux/amd64"
|
|
[arm64]="linux/arm64"
|
|
[arm]="linux/arm/v7"
|
|
[armv7]="linux/arm/v7"
|
|
)
|
|
if [[ "${arch_map[$arch]+exists}" != "" ]]; then
|
|
arch="${arch_map[$arch]}"
|
|
fi
|
|
|
|
# Make temporary dir where all source files intended to be in the image will be
|
|
# hardlinked from.
|
|
cdroot
|
|
temp_dir="$(TMPDIR="$(dirname "$input_file")" mktemp -d)"
|
|
ln "$input_file" "$temp_dir/coder"
|
|
ln ./scripts/Dockerfile.base "$temp_dir/"
|
|
ln ./scripts/Dockerfile "$temp_dir/"
|
|
|
|
cd "$temp_dir"
|
|
|
|
export DOCKER_BUILDKIT=1
|
|
|
|
base_image="$DEFAULT_BASE"
|
|
if [[ "$build_base" != "" ]]; then
|
|
log "--- Building base Docker image for $arch ($build_base)"
|
|
docker build \
|
|
--platform "$arch" \
|
|
--tag "$build_base" \
|
|
--no-cache \
|
|
-f Dockerfile.base \
|
|
. 1>&2
|
|
|
|
base_image="$build_base"
|
|
else
|
|
docker pull --platform "$arch" "$base_image" 1>&2
|
|
fi
|
|
|
|
log "--- Building Docker image for $arch ($image_tag)"
|
|
|
|
docker build \
|
|
--platform "$arch" \
|
|
--build-arg "BASE_IMAGE=$base_image" \
|
|
--build-arg "CODER_VERSION=$version" \
|
|
--no-cache \
|
|
--tag "$image_tag" \
|
|
-f Dockerfile \
|
|
. 1>&2
|
|
|
|
cdroot
|
|
rm -rf "$temp_dir"
|
|
|
|
if [[ "$push" == 1 ]]; then
|
|
log "--- Pushing Docker image for $arch ($image_tag)"
|
|
docker push "$image_tag" 1>&2
|
|
fi
|
|
|
|
log "--- Generating SBOM for Docker image ($image_tag)"
|
|
syft "$image_tag" -o spdx-json >"${image_tag//[:\/]/_}.spdx.json"
|
|
|
|
if [[ "$push" == 1 ]]; then
|
|
log "--- Attesting SBOM to Docker image for $arch ($image_tag)"
|
|
COSIGN_EXPERIMENTAL=1 cosign clean "$image_tag"
|
|
|
|
COSIGN_EXPERIMENTAL=1 cosign attest --type spdxjson \
|
|
--predicate "${image_tag//[:\/]/_}.spdx.json" \
|
|
--yes \
|
|
"$image_tag"
|
|
fi
|
|
|
|
echo "$image_tag"
|