diff --git a/.github/container/Dockerfile.rust.aarch64-unknown-linux-gnu b/.github/container/aarch64-unknown-linux-gnu/Dockerfile similarity index 81% rename from .github/container/Dockerfile.rust.aarch64-unknown-linux-gnu rename to .github/container/aarch64-unknown-linux-gnu/Dockerfile index 6a4450d..178e43f 100644 --- a/.github/container/Dockerfile.rust.aarch64-unknown-linux-gnu +++ b/.github/container/aarch64-unknown-linux-gnu/Dockerfile @@ -4,8 +4,11 @@ FROM ghcr.io/cbs228/sameold/builder/rust:latest -RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \ +ARG SOURCE_DATE_EPOCH + +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ --mount=target=/var/cache/apt,type=cache,sharing=locked \ + --mount=destination=/var/log,type=tmpfs \ [ "$(dpkg --print-architecture)" != arm64 ] || exit 0; \ set -eux; \ apt-get update; \ @@ -14,7 +17,8 @@ RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \ gcc-aarch64-linux-gnu \ libc6-dev-arm64-cross \ libc6:arm64 \ - ; + ; \ + rm -f -- /etc/machine-id /var/cache/ldconfig/aux-cache ARG RUST_TARGET="aarch64-unknown-linux-gnu" diff --git a/.github/container/Dockerfile.rust.armv7-unknown-linux-gnueabihf b/.github/container/armv7-unknown-linux-gnueabihf/Dockerfile similarity index 81% rename from .github/container/Dockerfile.rust.armv7-unknown-linux-gnueabihf rename to .github/container/armv7-unknown-linux-gnueabihf/Dockerfile index 81e3d57..5740d43 100644 --- a/.github/container/Dockerfile.rust.armv7-unknown-linux-gnueabihf +++ b/.github/container/armv7-unknown-linux-gnueabihf/Dockerfile @@ -4,8 +4,11 @@ FROM ghcr.io/cbs228/sameold/builder/rust:latest -RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \ +ARG SOURCE_DATE_EPOCH + +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ --mount=target=/var/cache/apt,type=cache,sharing=locked \ + --mount=destination=/var/log,type=tmpfs \ [ "$(dpkg --print-architecture)" != armhf ] || exit 0; \ set -eux; \ apt-get update; \ @@ -14,7 +17,8 @@ RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \ gcc-arm-linux-gnueabihf \ libc6-dev-armhf-cross \ libc6:armhf \ - ; + ; \ + rm -f -- /etc/machine-id /var/cache/ldconfig/aux-cache ARG RUST_TARGET="armv7-unknown-linux-gnueabihf" diff --git a/.github/container/Dockerfile.base b/.github/container/base/Dockerfile similarity index 51% rename from .github/container/Dockerfile.base rename to .github/container/base/Dockerfile index fa1afff..592db44 100644 --- a/.github/container/Dockerfile.base +++ b/.github/container/base/Dockerfile @@ -2,23 +2,41 @@ # Debian base image # -ARG DEBIAN_SUITE=buster +# or buster-20240612-slim for a snapshot-capable, reproducible image +ARG DEBIAN_TAG=buster-slim -FROM docker.io/library/debian:${DEBIAN_SUITE}-slim +FROM docker.io/library/debian:${DEBIAN_TAG} + +ARG DEBIAN_TAG +ARG SOURCE_DATE_EPOCH # Create a non-root user for running builds # GHA wants uid 1001 ARG UID=1001 -RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \ +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ --mount=target=/var/cache/apt,type=cache,sharing=locked \ + --mount=destination=/var/log,type=tmpfs \ set -eux; \ # create an unprivileged user for builds - useradd -u "$UID" --create-home --user-group builder; \ + groupadd builder -g "$UID"; \ + useradd builder -u "$UID" -g "$UID" --create-home; \ # build directories for any user mkdir -m 1777 /src /install /cargo; \ # re-enable apt caching (we have a cache mount) rm -f /etc/apt/apt.conf.d/docker-clean; \ + # if tag contains numerics, like buster-20240612-slim, use the + # snapshot URL that's baked into the image + if echo "${DEBIAN_TAG}" | grep -q "[0-9]"; then \ + sed -i -r \ + -e 's/^deb/# deb/' \ + -e 's|^#\s*(.*http://snapshot\.)|\1|' \ + /etc/apt/sources.list; \ + cat >&2 /etc/apt/sources.list; \ + echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf.d/use-snapshot.conf; \ + echo 'Acquire::Retries "10";' >> /etc/apt/apt.conf.d/use-snapshot.conf; \ + echo 'Acquire::Retries::Delay::Maximum "600";' >> /etc/apt/apt.conf.d/use-snapshot.conf; \ + fi; \ # enable packages from multiple architectures dpkg --add-architecture amd64; \ dpkg --add-architecture armhf; \ @@ -36,8 +54,9 @@ RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \ qemu-user \ qemu-user-binfmt \ tar \ - zstd \ - ; + zstd; \ + git config --system --add safe.directory '*'; \ + rm -f -- /etc/machine-id /var/cache/ldconfig/aux-cache # Directories for sources and installed binaries VOLUME ["/src", "/install"] diff --git a/.github/container/build.sh b/.github/container/build.sh index a2cff58..55f1844 100755 --- a/.github/container/build.sh +++ b/.github/container/build.sh @@ -4,11 +4,12 @@ # # run with --push to push the images. -now="$(date -u +'%Y-%m-%d')" +# set to disable cache +NO_CACHE="${NO_CACHE:-}" +DEBIAN_TAG="buster-20240612-slim" CONTAINER_PREFIX="ghcr.io/cbs228" CONTAINER_FQNAME="${CONTAINER_PREFIX}/sameold/builder/%s" -CONTAINER_TAGS=("$now" "latest") RUST_VERSIONS=("1.84.0") @@ -60,6 +61,28 @@ container_name() { printf "$CONTAINER_FQNAME" "$1" } +buildcontainer() { + # Usage: buildcontainer ARGS + # + # Run the $BUILDER to build a container image. Some standardized + # arguments are passed to every build. + + if [[ $BUILDER =~ podman$ ]]; then + run "$BUILDER" build \ + --build-arg SOURCE_DATE_EPOCH="$SOURCE_DATE_EPOCH" \ + --timestamp "$SOURCE_DATE_EPOCH" \ + ${NO_CACHE:+--no-cache} \ + "$@" + else + # docker mode; 100% untested + run "$BUILDER" buildx build \ + --build-arg SOURCE_DATE_EPOCH="$SOURCE_DATE_EPOCH" \ + --output type=docker,rewrite-timestamp=true \ + ${NO_CACHE:+--no-cache} \ + "$@" + fi +} + tagall() { # Usage: tagall SHORTNAME TAG0 TAG1 ... # @@ -115,54 +138,59 @@ while true; do done BUILDER="$(container_builder)" -selfdir="$(dirname "${0?}")" +selfdir="$(dirname "$(realpath -e "${0?}")")" + +# set SOURCE_DATE_EPOCH if possible +SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(git log -1 --pretty=%ct -- "$selfdir" || date +%s)}" +export SOURCE_DATE_EPOCH + +# tag with "latest" and SOURCE_DATE_EPOCH +CONTAINER_TAGS=("latest" "$(date --date '@'"$SOURCE_DATE_EPOCH" +'%Y-%m-%d')") # build the base image base_tag="$(container_name base):${CONTAINER_TAGS[0]}" -run "$BUILDER" build \ - -f "${selfdir?}/Dockerfile.base" \ +buildcontainer \ + --build-arg DEBIAN_TAG="$DEBIAN_TAG" \ --tag "$base_tag" \ - "${selfdir?}" + "${selfdir?}/base" # add rust to the base image rust_tag="$(container_name rust):${CONTAINER_TAGS[0]}" -run "$BUILDER" build \ - -f "${selfdir?}/Dockerfile.rust" \ +buildcontainer \ --from "$base_tag" \ --build-arg RUST_VERSIONS="${RUST_VERSIONS[*]}" \ --tag "$rust_tag" \ - "${selfdir?}" + "${selfdir?}/rust" # build architecture-specific images -for containerfile in "${selfdir}/"Dockerfile.rust.*; do - platform_triple="${containerfile##*.}" +for containerdir in "${selfdir?}/"*-*-*; do + [ -d "$containerdir" ] || continue + + platform_triple="$(basename ${containerdir})" cur_tag="$(container_name "$platform_triple"):${CONTAINER_TAGS[0]}" - run "$BUILDER" build \ + buildcontainer \ --from "$rust_tag" \ - -f "${containerfile}" \ --tag "${cur_tag}" \ - "${selfdir?}" + "${containerdir}" done # if all builds succeed, apply remaining tags... tagall base "${CONTAINER_TAGS[@]}" tagall rust "${CONTAINER_TAGS[@]}" -for containerfile in "${selfdir}/"Dockerfile.rust.*; do - platform_triple="${containerfile##*.}" +for containerdir in "${selfdir?}/"*-*-*; do + [ -d "$containerdir" ] || continue - tagall "$platform_triple" "${CONTAINER_TAGS[@]}" + tagall "$(basename "$containerdir")" "${CONTAINER_TAGS[@]}" done [ -n "${push_images:-}" ] || exit 0 # ... and push -pushall base "${CONTAINER_TAGS[@]}" -pushall rust "${CONTAINER_TAGS[@]}" -for containerfile in "${selfdir}/"Dockerfile.rust.*; do - platform_triple="${containerfile##*.}" +for containerdir in "${selfdir?}/"*; do + [ -d "$containerdir" ] || continue - pushall "$platform_triple" "${CONTAINER_TAGS[@]}" + pushall "$(basename "$containerdir")" "${CONTAINER_TAGS[@]}" done diff --git a/.github/container/Dockerfile.rust.i686-unknown-linux-gnu b/.github/container/i686-unknown-linux-gnu/Dockerfile similarity index 80% rename from .github/container/Dockerfile.rust.i686-unknown-linux-gnu rename to .github/container/i686-unknown-linux-gnu/Dockerfile index 4a46bda..0ac2347 100644 --- a/.github/container/Dockerfile.rust.i686-unknown-linux-gnu +++ b/.github/container/i686-unknown-linux-gnu/Dockerfile @@ -4,8 +4,11 @@ FROM ghcr.io/cbs228/sameold/builder/rust:latest -RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \ +ARG SOURCE_DATE_EPOCH + +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ --mount=target=/var/cache/apt,type=cache,sharing=locked \ + --mount=destination=/var/log,type=tmpfs \ [ "$(dpkg --print-architecture)" != i386 ] || exit 0; \ set -eux; \ apt-get update; \ @@ -14,7 +17,8 @@ RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \ gcc-i686-linux-gnu \ libc6-dev-i386-cross \ libc6:i386 \ - ; + ; \ + rm -f -- /etc/machine-id /var/cache/ldconfig/aux-cache ARG RUST_TARGET="i686-unknown-linux-gnu" diff --git a/.github/container/Dockerfile.rust b/.github/container/rust/Dockerfile similarity index 98% rename from .github/container/Dockerfile.rust rename to .github/container/rust/Dockerfile index bf3d0a1..b694e14 100644 --- a/.github/container/Dockerfile.rust +++ b/.github/container/rust/Dockerfile @@ -4,6 +4,8 @@ FROM ghcr.io/cbs228/sameold/builder/base:latest +ARG SOURCE_DATE_EPOCH + # Install rustup and platform-native target # # RUST_VERSIONS: list of version numbers or strings @@ -52,6 +54,6 @@ RUN set -eux; \ (umask 022 && echo "$RUSTUP_ARCH" >/etc/rust-native-arch) # Install scripts -COPY rootfiles/ / +COPY rootfiles / LABEL org.opencontainers.image.description="A pinned Rust toolchain with rustup." diff --git a/.github/container/rootfiles/usr/local/bin/qemu-run-maybe b/.github/container/rust/rootfiles/usr/local/bin/qemu-run-maybe similarity index 100% rename from .github/container/rootfiles/usr/local/bin/qemu-run-maybe rename to .github/container/rust/rootfiles/usr/local/bin/qemu-run-maybe diff --git a/.github/container/Dockerfile.rust.x86_64-unknown-linux-gnu b/.github/container/x86_64-unknown-linux-gnu/Dockerfile similarity index 80% rename from .github/container/Dockerfile.rust.x86_64-unknown-linux-gnu rename to .github/container/x86_64-unknown-linux-gnu/Dockerfile index 07433a7..0d003d2 100644 --- a/.github/container/Dockerfile.rust.x86_64-unknown-linux-gnu +++ b/.github/container/x86_64-unknown-linux-gnu/Dockerfile @@ -4,8 +4,11 @@ FROM ghcr.io/cbs228/sameold/builder/rust:latest -RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \ +ARG SOURCE_DATE_EPOCH + +RUN --mount=target=/var/lib/apt,type=cache,sharing=locked \ --mount=target=/var/cache/apt,type=cache,sharing=locked \ + --mount=destination=/var/log,type=tmpfs \ [ "$(dpkg --print-architecture)" != amd64 ] || exit 0; \ set -eux; \ apt-get update; \ @@ -14,7 +17,8 @@ RUN --mount=target=/var/lib/apt/lists,type=cache,sharing=locked \ gcc-x86-64-linux-gnu \ libc6-dev-amd64-cross \ libc6:amd64 \ - ; + ; \ + rm -f -- /etc/machine-id /var/cache/ldconfig/aux-cache ARG RUST_TARGET="x86_64-unknown-linux-gnu"