From 82ddae427503f3e6fa155e9f14bc52ff182a9fa6 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Sun, 25 Feb 2024 18:46:00 +0100 Subject: [PATCH] scripts: Add scripts for building and reproducing kas containers Provide a script to build container images reproducibly. This will also be used by CI soon. A wrapper script around this allows to rebuild a specified image and check its identity. Signed-off-by: Jan Kiszka --- scripts/build-container.sh | 142 +++++++++++++++++++++++++++++++++ scripts/checkcode.sh | 7 +- scripts/reproduce-container.sh | 61 ++++++++++++++ 3 files changed, 209 insertions(+), 1 deletion(-) create mode 100755 scripts/build-container.sh create mode 100755 scripts/reproduce-container.sh diff --git a/scripts/build-container.sh b/scripts/build-container.sh new file mode 100755 index 00000000..04ac46c2 --- /dev/null +++ b/scripts/build-container.sh @@ -0,0 +1,142 @@ +#!/bin/sh +# +# kas - setup tool for bitbake based projects +# +# Copyright (c) Siemens AG, 2024 +# +# Authors: +# Jan Kiszka +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +usage() +{ + DEFAULT_DEBIAN_TAG=$(grep -m 1 'ARG DEBIAN_TAG=' "$(dirname "$0")/../Dockerfile" | + sed 's/.*DEBIAN_TAG=\(.*\)-\(.*\)/\1--\2/') + + printf "%b" "Usage: $0 [OPTIONS]\n" + printf "%b" "\nOptional arguments:\n" + printf "%b" "--arch\t\tBuild for specified architecture, rather than the native one\n" + printf "%b" "--clean\t\tRemove local images (ghcr.io/siemens/kas/TARGET:TAG) before\n" \ + "\t\tstarting the build and do not use image cache\n" + printf "%b" "--debian-tag\tUse specified tag for Debian base image\n" \ + "\t\t(default=$DEFAULT_DEBIAN_TAG)\n" + printf "%b" "--tag\t\tTag container with specified name (default=next)\n" + printf "%b" "--target\tBuild specified target(s) (default=\"kas kas-isar\")\n" +} + +build_image() +{ + IMAGE_NAME="ghcr.io/siemens/kas/$1:$TAG" + + OLD_IMAGE_ID=$(docker images -q "$IMAGE_NAME" 2>/dev/null) + + ARCH_OPT= + if [ -n "$ARCH" ]; then + ARCH_OPT=--arch $ARCH + fi + NOCHACHE_OPT= + if [ "$CLEAN" = y ]; then + NOCHACHE_OPT="--no-cache" + fi + # shellcheck disable=SC2086 + if ! docker buildx build --build-arg SOURCE_DATE_EPOCH="$(git log -1 --pretty=%ct)" \ + --output type=docker,rewrite-timestamp=true \ + --tag "$IMAGE_NAME" --build-arg DEBIAN_TAG="$DEBIAN_TAG" \ + --target "$1" $ARCH_OPT $NOCHACHE_OPT .; then + echo "Build failed!" + return 1 + fi + + if [ -n "$OLD_IMAGE_ID" ]; then + if [ "$(docker images -q "$IMAGE_NAME")" = "$OLD_IMAGE_ID" ]; then + echo "Reproduced identical image $IMAGE_NAME $OLD_IMAGE_ID" + else + echo "Deleting old image $OLD_IMAGE_ID" + docker rmi "$OLD_IMAGE_ID" + fi + fi + + return 0 +} + +ARCH= +CLEAN= +DEBIAN_TAG= +TARGETS= +TAG=next +while [ $# -gt 0 ]; do + case "$1" in + --arch) + shift + ARCH="$1" + ;; + --clean) + CLEAN=y + ;; + --debian-tag) + shift + DEBIAN_TAG="$1" + ;; + --tag) + shift + TAG="$1" + ;; + --target) + shift + TARGETS="$TARGETS $1" + ;; + *) + usage + exit 1 + esac + shift +done + +TARGETS="${TARGETS:-kas kas-isar}" + +if [ -z "$DEBIAN_TAG" ]; then + DEBIAN_RELEASE=$(grep -m 1 'ARG DEBIAN_TAG=' "$(dirname "$0")/../Dockerfile" | + sed 's/.*DEBIAN_TAG=\(.*\)-.*/\1/') + DEBIAN_TAG=$(podman image search --list-tags debian --limit 1000000000 | \ + grep "$DEBIAN_RELEASE-.*-slim" | sort -r | head -1 | sed 's/.*[ ]\+//') +fi + +if [ "$CLEAN" = y ]; then + for TARGET in $TARGETS; do + docker rmi "ghcr.io/siemens/kas/$TARGET:$TAG" 2>/dev/null + done +fi + +KAS_CLONE=$(mktemp -d --tmpdir kas-tmp.XXXXXXXXXX) +git clone . "$KAS_CLONE" +cd "$KAS_CLONE" || exit 1 + +RESULT=0 +for TARGET in $TARGETS; do + if ! build_image "$TARGET"; then + RESULT=1 + break + fi +done + +cd - >/dev/null || exit 1 +rm -rf "$KAS_CLONE" + +exit $RESULT diff --git a/scripts/checkcode.sh b/scripts/checkcode.sh index d37f6a91..1b18aae5 100755 --- a/scripts/checkcode.sh +++ b/scripts/checkcode.sh @@ -18,6 +18,11 @@ echo "Checking with doc8" doc8 "$SRCDIR"/docs --ignore-path "$SRCDIR"/docs/_build || ERROR=$((ERROR + 4)) echo "Checking with shellcheck" -shellcheck "$SRCDIR"/kas-container "$SRCDIR"/scripts/release.sh "$SRCDIR"/scripts/checkcode.sh "$SRCDIR"/container-entrypoint || ERROR=$((ERROR + 8)) +shellcheck "$SRCDIR"/kas-container \ + "$SRCDIR"/scripts/release.sh \ + "$SRCDIR"/scripts/checkcode.sh \ + "$SRCDIR"/scripts/build-container.sh \ + "$SRCDIR"/scripts/reproduce-container.sh \ + "$SRCDIR"/container-entrypoint || ERROR=$((ERROR + 8)) exit $ERROR diff --git a/scripts/reproduce-container.sh b/scripts/reproduce-container.sh new file mode 100755 index 00000000..242a01e4 --- /dev/null +++ b/scripts/reproduce-container.sh @@ -0,0 +1,61 @@ +#!/bin/sh +# +# kas - setup tool for bitbake based projects +# +# Copyright (c) Siemens AG, 2024 +# +# Authors: +# Jan Kiszka +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +if [ -z "$1" ] || [ "$1" = "--help" ]; then + echo "Usage: $0 kas[-isar]: [architecture]" + exit 0 +fi + +TARGET=$(echo "$1" | sed 's/:.*//') +TAG=$(echo "$1" | sed 's/.*://') +ARCH=$2 + +DEBIAN_TAG=$(docker run --entrypoint "" --rm -t "ghcr.io/siemens/kas/$TARGET:$TAG" \ + sh -c 'printf "%b" $DEBIAN_BASE_IMAGE_TAG') +if [ -z "$DEBIAN_TAG" ]; then + echo "Cannot determine base image of ghcr.io/siemens/kas/$TARGET:$TAG" + exit 1 +fi + +ARCH_OPT= +if [ -n "$ARCH" ]; then + ARCH_OPT="--arch $ARCH" +fi +# shellcheck disable=SC2086 +"$(dirname "$0")/build-container.sh" $ARCH_OPT --target "$TARGET" \ + --tag repro-test --debian-tag "$DEBIAN_TAG" --clean || exit 1 + +echo "" + +docker images --digests | grep "^REPOSITORY\|^ghcr.io/siemens/kas/${TARGET}[ ]*\($TAG\|repro-test\)" +printf "%b" "\nReproduction test " +if [ "$(docker images -q "ghcr.io/siemens/kas/$1")" = "$(docker images -q "ghcr.io/siemens/kas/$TARGET:repro-test")" ]; then + printf "%b" "SUCCEEDED\n" + docker rmi "ghcr.io/siemens/kas/$TARGET:repro-test" >/dev/null +else + printf "%b" "FAILED\n" +fi