Merge branch 'repro' into 'master'

Add a new `repro` image version / tag providing a bit for bit reproducible image

Closes #44

See merge request archlinux/archlinux-docker!96
This commit is contained in:
hashworks 2026-04-19 17:54:32 +02:00
commit 09a5aed161
7 changed files with 364 additions and 21 deletions

View File

@ -6,6 +6,7 @@ stages:
- lint
- rootfs
- image
- repro
- test
- pre-release
- release
@ -61,7 +62,7 @@ get_version:
stage: rootfs
parallel:
matrix:
- GROUP: [base, base-devel, multilib-devel]
- GROUP: [base, base-devel, multilib-devel, repro]
before_script:
- pacman -Syu --noconfirm git make fakechroot fakeroot
- pacman -Sdd --noconfirm devtools
@ -98,16 +99,25 @@ rootfs:secure:
stage: image
parallel:
matrix:
- GROUP: [base, base-devel, multilib-devel]
- GROUP: [base, base-devel, multilib-devel, repro]
tags:
- vm
id_tokens:
SIGSTORE_ID_TOKEN:
aud: sigstore
script:
- podman build
-f "$CI_PROJECT_DIR/output/Dockerfile.$GROUP"
-t "$CI_REGISTRY_IMAGE:$GROUP-$CI_COMMIT_REF_SLUG"
- |
if [[ "$GROUP" == "repro" ]]; then
SOURCE_DATE_EPOCH=$(date -u -d "today 00:00:00" +%s)
REPRO_ARGS=(
--source-date-epoch=${SOURCE_DATE_EPOCH}
--rewrite-timestamp
)
fi
podman build \
"${REPRO_ARGS[@]}" \
-f "$CI_PROJECT_DIR/output/Dockerfile.$GROUP" \
-t "$CI_REGISTRY_IMAGE:$GROUP-$CI_COMMIT_REF_SLUG" \
"$CI_PROJECT_DIR/output"
- podman push --sign-by-sigstore=<(sed "s/TEMPLATE_OIDC_ID_TOKEN/${SIGSTORE_ID_TOKEN}/" sigstore-param-file.yaml) "$CI_REGISTRY_IMAGE:$GROUP-$CI_COMMIT_REF_SLUG"
@ -138,6 +148,61 @@ image:build:secure:
- podman login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
- 'echo -e "default-docker:\n use-sigstore-attachments: true" > /etc/containers/registries.d/sigstore.yaml'
.test_repro:
stage: repro
before_script:
- pacman -Syu --noconfirm git make fakechroot fakeroot podman diffoscope diffoci
- pacman -Sdd --noconfirm devtools
script:
- make BUILDDIR="$PWD/repro-build" OUTPUTDIR="$PWD/repro-output" $PWD/repro-output/Dockerfile.repro
- echo "The sha256 hash of the original rootFS is:"
- cat output/repro.tar.zst.SHA256
- echo "The sha256 hash of the rebuilt rootFS is:"
- cat repro-output/repro.tar.zst.SHA256
- diffoscope output/repro.tar.zst repro-output/repro.tar.zst
- echo "RootFS is reproducible!"
- |
SOURCE_DATE_EPOCH=$(date -u -d "today 00:00:00" +%s)
podman build \
--no-cache \
--source-date-epoch=${SOURCE_DATE_EPOCH} \
--rewrite-timestamp \
-f "$CI_PROJECT_DIR/repro-output/Dockerfile.repro" \
-t "archlinux-docker:repro-$CI_COMMIT_REF_SLUG" \
"$CI_PROJECT_DIR/repro-output"
- podman pull $CI_REGISTRY_IMAGE:repro-$CI_COMMIT_REF_SLUG
- echo "Digest of the original image is:"
- podman inspect --format '{{.Digest}}' "$CI_REGISTRY_IMAGE:repro-$CI_COMMIT_REF_SLUG"
- echo "Digest of the rebuilt image is:"
- podman inspect --format '{{.Digest}}' "localhost/archlinux-docker:repro-$CI_COMMIT_REF_SLUG"
- diffoci diff --semantic --verbose podman://$CI_REGISTRY_IMAGE:repro-$CI_COMMIT_REF_SLUG podman://localhost/archlinux-docker:repro-$CI_COMMIT_REF_SLUG
- echo "Image is reproducible!"
artifacts:
paths:
- repro-output/*
exclude:
- repro-output/*.tar
expire_in: 2h
test-repro:
extends: .test_repro
tags:
- vm
except:
- master@archlinux/archlinux-docker
- releases@archlinux/archlinux-docker
- schedules@archlinux/archlinux-docker
- tags@archlinux/archlinux-docker
test-repro:secure:
extends: .test_repro
tags:
- secure
- vm
only:
- master@archlinux/archlinux-docker
- schedules@archlinux/archlinux-docker
# Build and publish to the Arch Linux group namespaces:
# https://hub.docker.com/r/archlinux/archlinux
# https://quay.io/repository/archlinux/archlinux
@ -209,6 +274,16 @@ test:base-devel:
- test -u /usr/bin/sudo # issue 70
- test -u /usr/bin/passwd
test:repro:
extends: .test
image: $CI_REGISTRY_IMAGE:repro-$CI_COMMIT_REF_SLUG
script:
- pacman-key --init
- pacman-key --populate archlinux
- pacman -Syu --noconfirm arch-repro-status
- arch-repro-status
- *test-script
pre-release:
stage: pre-release
image: registry.gitlab.com/gitlab-org/release-cli:latest
@ -234,7 +309,7 @@ pre-release:
-d "{\"full_description\": $(cat README.md | jq -sR .)}"
# Upload rootfs to the Generic Packages Repository
for group in base base-devel multilib-devel; do
for group in base base-devel multilib-devel repro; do
rootfs_file="${group}-${BUILD_VERSION}.tar.zst"
mv "output/${group}.tar.zst" "output/${rootfs_file}"
mv "output/${group}.tar.zst.SHA256" "output/${rootfs_file}.SHA256"
@ -246,7 +321,7 @@ pre-release:
done
# Create the Dockerfiles, commit to the release branch
for group in base base-devel multilib-devel; do
for group in base base-devel multilib-devel repro; do
rootfs_file="${group}-${BUILD_VERSION}.tar.zst"
./scripts/make-dockerfile.sh "${rootfs_file}" "${group}" "output" "curl -sOJL \"${PACKAGE_REGISTRY_URL}/${rootfs_file}\"" "${group}"
sed -i "/^COPY ${rootfs_file} \/$/d" output/Dockerfile.${group}
@ -267,6 +342,9 @@ pre-release:
--form "actions[][file_path]=Dockerfile.multilib-devel"
--form "actions[][content]=<output/Dockerfile.multilib-devel"
--form "actions[][action]=update"
--form "actions[][file_path]=Dockerfile.repro"
--form "actions[][content]=<output/Dockerfile.repro"
--form "actions[][action]=update"
--form "actions[][file_path]=.gitlab-ci.yml"
--form "actions[][content]=<.gitlab-ci.yml"
--form "actions[][action]=update"
@ -313,6 +391,10 @@ release:
url: '${PACKAGE_REGISTRY_URL}/multilib-devel-${BUILD_VERSION}.tar.zst'
- name: 'multilib-devel-${BUILD_VERSION}.tar.zst.SHA256'
url: '${PACKAGE_REGISTRY_URL}/multilib-devel-${BUILD_VERSION}.tar.zst.SHA256'
- name: 'repro-${BUILD_VERSION}.tar.zst'
url: '${PACKAGE_REGISTRY_URL}/repro-${BUILD_VERSION}.tar.zst'
- name: 'repro-${BUILD_VERSION}.tar.zst.SHA256'
url: '${PACKAGE_REGISTRY_URL}/repro-${BUILD_VERSION}.tar.zst.SHA256'
# Publish to the official Docker namespace: https://hub.docker.com/_/archlinux
# Note: The description is maintained here: https://github.com/docker-library/docs/tree/master/archlinux
@ -347,7 +429,7 @@ publish-dockerhub:
- git checkout -b "$head"
- cp ../docker-library.template library/archlinux
- |
for group in base base-devel multilib-devel; do
for group in base base-devel multilib-devel repro; do
test "${group}" = "base" && extra="latest, " || extra=""
echo "Tags: ${extra}${group}, ${group}-${BUILD_VERSION}" >> library/archlinux
echo "GitCommit: ${BUILD_COMMIT}" >> library/archlinux

View File

@ -37,7 +37,8 @@ LABEL org.opencontainers.image.created="TEMPLATE_CREATED"
COPY --from=verify /rootfs/ /
RUN ldconfig && \
sed -i '/BUILD_ID/a VERSION_ID=TEMPLATE_VERSION_ID' /etc/os-release
sed -i '/BUILD_ID/a VERSION_ID=TEMPLATE_VERSION_ID' /etc/os-release && \
LDCONFIG_AUX_CACHE
ENV LANG=C.UTF-8
CMD ["/usr/bin/bash"]

View File

@ -1,6 +1,8 @@
OCITOOL=podman # or docker
BUILDDIR=$(shell pwd)/build
OUTPUTDIR=$(shell pwd)/output
ARCHIVE_SNAPSHOT=$(shell date -d "-1 day" +"%Y/%m/%d")
SOURCE_DATE_EPOCH=$(shell date -u -d "today 00:00:00" +"%s")
.PHONY: clean
clean:
@ -8,14 +10,14 @@ clean:
.PRECIOUS: $(OUTPUTDIR)/%.tar.zst
$(OUTPUTDIR)/%.tar.zst:
scripts/make-rootfs.sh $(*) $(BUILDDIR) $(OUTPUTDIR)
scripts/make-rootfs.sh $(*) $(BUILDDIR) $(OUTPUTDIR) $(ARCHIVE_SNAPSHOT) $(SOURCE_DATE_EPOCH)
.PRECIOUS: $(OUTPUTDIR)/Dockerfile.%
$(OUTPUTDIR)/Dockerfile.%: $(OUTPUTDIR)/%.tar.zst
scripts/make-dockerfile.sh "$(*).tar.zst" $(*) $(OUTPUTDIR) "true" "Dev"
scripts/make-dockerfile.sh "$(*).tar.zst" $(*) $(OUTPUTDIR) "true" "Dev" $(SOURCE_DATE_EPOCH)
# The following is for local builds only, it is not used by the CI/CD pipeline
all: image-base image-base-devel image-multilib-devel
all: image-base image-base-devel image-multilib-devel image-repro
image-%: $(OUTPUTDIR)/Dockerfile.%
${OCITOOL} build -f $(OUTPUTDIR)/Dockerfile.$(*) -t archlinux/archlinux:$(*) $(OUTPUTDIR)

View File

@ -12,11 +12,16 @@ Arch Linux provides OCI-Compliant container images in multiple repositories:
* [Daily in our ghcr.io repository][ghcr-containers]:
`podman pull ghcr.io/archlinux/archlinux:latest` or `docker pull ghcr.io/archlinux/archlinux:latest`
Three versions of the image are provided: `base` (approx. 150 MiB), `base-devel`
Four versions of the image are provided: `base` (approx. 150 MiB), `base-devel`
(approx. 260 MiB) and `multilib-devel` (approx. 300MiB) containing the
respective meta package. All of them are available as
tags with `latest` pointing to `base`. Additionally, images are tagged with their
date and build job number, f.e. `base-devel-20201118.0.9436`.
respective meta package; and `repro` which is a bit for bit reproducible version
of the `base` image (note that, to ensure reproducibility, the pacman keys
are stripped from this image so you're expected to run
`pacman-key --init && pacman-key --populate archlinux` before being able to update
the system and install packages via `pacman`).
All of them are available as tags with `latest` pointing to `base`.
Additionally, images are tagged with their date and build job number,
f.e. `base-devel-20201118.0.9436`.
While the images are regularly kept up to date it is strongly recommended
running `pacman -Syu` right after starting a container due to the rolling
@ -35,7 +40,7 @@ $ cosign verify ghcr.io/archlinux/archlinux:latest --certificate-identity-regexp
* Provide the Arch experience in a Docker image
* Provide the simplest but complete image to `base`, `base-devel` and
`multilib-devel` on a regular basis
* `pacman` needs to work out of the box
* `pacman` needs to work out of the box (with the exception of the `repro` image, while we are working on technical contstrains)
* All installed packages have to be kept unmodified
>>>
@ -67,7 +72,12 @@ Make sure your user can directly interact with Podman (i.e. `podman info` works)
### Usage
There are multiple `make image-XXX` targets, where each creates the
respective `archlinux:XXX` image based on the corresponding meta package.
Currently those include `base`, `base-devel` and `multilib-devel`.
Currently those include `base`, `base-devel`, `multilib-devel` and `repro`.
### Reproducing a `repro` image
To reproduce a `repro` image locally, follow the instructions
in [REPRO.md](https://gitlab.archlinux.org/archlinux/archlinux-docker/-/blob/master/REPRO.md).
## Pipeline
@ -118,4 +128,4 @@ Every year in June the content of the protected `GITLAB_PROJECT_TOKEN` variable
[self-container-registry]: https://gitlab.archlinux.org/archlinux/archlinux-docker/container_registry
[access-tokens]: https://gitlab.archlinux.org/archlinux/archlinux-docker/-/settings/access_tokens
[access-tokens]: https://gitlab.archlinux.org/archlinux/archlinux-docker/-/settings/access_tokens

207
REPRO.md Normal file
View File

@ -0,0 +1,207 @@
# Reproducing a `repro` image locally
The `repro` image provides a bit for bit [reproducible build](https://reproducible-builds.org)
of the `base` image.
Note that, to ensure reproducibility, the pacman keys are stripped from this
image, so you're expected to run `pacman-key --init && pacman-key --populate archlinux`
before being able to update the system and install packages via `pacman` when using this image.
To reproduce the `repro` image locally, follow the below instructions.
## Disclaimer
Reproducible builds [expect the same build environment across builds](https://reproducible-builds.org/docs/definition/).
While it *should* be fine in most cases, this means we cannot guarantee that you will always be able
to successfully reproduce a specific image locally over time.
Technically speaking, the older the image you're trying to reproduce is, the more chance there is
to have more or less significant differences between your build environment
and the one used to build the original image (for instance in terms of packages versions).
Such differences can affect the build (and the resulting artifacts). Please note that failing to
reproduce an image locally does not necessarily mean that it isn't reproducible per se, but can
just be the result of significant enough differences between your build environment and the one
used to build the original image.
You can avoid (or mitigate) eventual issues due to such differences by restoring all packages
of your build environment to the build date of the original image (see the [related instructions
from the Arch Wiki](https://wiki.archlinux.org/title/Arch_Linux_Archive#Restore_all_packages_to_a_specific_date)).
## Dependencies
Install the following Arch Linux packages:
* make
* devtools
* git
* podman
* fakechroot
* fakeroot
* diffoscope (to optionally check the reproducibility of the rootFS)
* diffoci
## Prepare the build environment
Prepare the build environment by setting the following environment variables:
* `BUILD_VERSION`: The build version of the `repro` image you want to reproduce.
For instance, if you're aiming to reproduce the `repro-20260331.0.508794` image:
```bash
export BUILD_VERSION="20260331.0.508794"
```
* `ARCHIVE_SNAPSHOT`: The date of the Arch Linux repository archive snaphot to build
the image against. This is based on the date included in the image's `BUILD_VERSION`:
```bash
export ARCHIVE_SNAPSHOT=$(date -d "${BUILD_VERSION%%.*} -1 day" +"%Y/%m/%d")
```
* `SOURCE_DATE_EPOCH`: The value to normalize timestamps with during the build.
This is based on the date included in the image's `BUILD_VERSION`:
```bash
export SOURCE_DATE_EPOCH=$(date -u -d "${BUILD_VERSION%%.*} 00:00:00" +"%s")
```
Then clone the [archlinux-docker](https://gitlab.archlinux.org/archlinux/archlinux-docker)
repository and move into it:
```bash
git clone https://gitlab.archlinux.org/archlinux/archlinux-docker.git
cd archlinux-docker
```
Note that all the following instructions assume that you are at the root of the
archlinux-docker repository cloned above.
## Build the rootFS and generate the Dockerfile
Build the rootFS with the required parameters:
```bash
make \
ARCHIVE_SNAPSHOT="$ARCHIVE_SNAPSHOT" \
SOURCE_DATE_EPOCH="$SOURCE_DATE_EPOCH" \
$PWD/output/Dockerfile.repro
```
The following resulting artifacts will be located in `$PWD/output`:
* repro.tar.zst (the rootFS)
* repro.tar.zst.SHA256 (sha256 hash of the rootFS)
* Dockerfile.repro (the generated Dockerfile)
## Optional - Check the rootFS reproducibility
At that point, if the artifacts built for the image you're aiming to reproduce
are still available for download from the rootfs stage of the corresponding
[archlinux-docker pipeline](https://gitlab.archlinux.org/archlinux/archlinux-docker/-/pipelines)
, you can optionally compare the content of the `repro.tar.zst.SHA256`
file from the pipeline to the one generated during your local build (which
should be the same, indicating that the rootFS has been successfully reproduced).
Additionally, you can check differences between the `repro.tar.zst` tarball from
the pipeline and the one built during your local build with `diffoscope`
*(where `/tmp/repro.tar.zst` is the rootFS tarball downloaded from the pipeline and
`$PWD/output/repro.tar.zst` is the rootFS tarball built during your local build in the following example)*:
```bash
diffoscope /tmp/repro.tar.zst $PWD/output/repro.tar.zst
```
This should return no difference, acting as additional indicator that the rootFS has been
successfully reproduced.
## Build the image
You can now (re)build the image against the rootFS and the Dockerfile generated in the previous step.
To do so, build the image with the required parameters:
```bash
podman build \
--no-cache \
--source-date-epoch=$SOURCE_DATE_EPOCH \
--rewrite-timestamp \
-f "$PWD/output/Dockerfile.repro" \
-t "archlinux:repro-$BUILD_VERSION" \
"$PWD/output"
```
The built image will be accessible in your local podman container storage under the name:
`localhost/archlinux:repro-$BUILD_VERSION`.
## Check the image reproducibility
Pull the image you're aiming to reproduce from Docker Hub:
```bash
podman pull docker.io/archlinux/archlinux:repro-$BUILD_VERSION
```
Compare the digest of the image pulled from Docker Hub to the digest of the image you built
locally:
```bash
podman inspect --format '{{.Digest}}' docker.io/archlinux/archlinux:repro-$BUILD_VERSION
podman inspect --format '{{.Digest}}' localhost/archlinux:repro-$BUILD_VERSION
```
Both digests should be identical, indicating that the image has been successfully reproduced.
Additionally, you can check difference between the image pulled from Docker Hub and
the image you built locally with `diffoci`:
```bash
diffoci diff --semantic --verbose podman://docker.io/archlinux/archlinux:repro-$BUILD_VERSION podman://localhost/archlinux:repro-$BUILD_VERSION
```
This should show no difference, acting as additional indicator that the image has been
successfully reproduced *(see the following section about the `--semantic` flag requirement)*.
### Note about `diffoci` requiring the `--semantic` flag (a.k.a "non-strict" mode)
Docker / Podman does not allow to have two images with the same name & tag combination stored
locally, [making it impossible to compare two images with the same name with
`diffoci`](https://github.com/reproducible-containers/diffoci/issues/74).
To work around this limitation, one of the two image has to be named differently, whether by
setting a different name / tag combination at build time (as done in this guide) or by renaming
it post-build with e.g. `podman tag`.
However, the image name & tag combination is automatically reported (and updated in the case
of a renaming) in the image annotations / metadata and it's apparently not possible to fully overwrite
it during build or update it post-build in a straightforward way.
This introduces unavoidable differences
in the image annotations / metadata that `diffoci` will therefore systematically report by default.
See for instance the following `diffoci` output reporting a difference in the image name annotation:
```
Event: "DescriptorMismatch" (field "Annotations")
map[string]string{
"io.containerd.image.name": strings.Join({
- "docker.io/archlinux/archlinux:repro-20260331.0.508794",
+ "localhost/archlinux:repro-20260331.0.508794",
}, ""),
```
Given that it's currently not possible to have two images with the same name & tag
combination stored locally and that it's also not possible to "normalize" the related
annotations / metadata during (or after) the build, we are not aware of a way to get a
fully successful `diffoci` output in default / strict mode (i.e., with *absolutely* no
reported differences, see the [related upstream report](https://github.com/reproducible-containers/diffoci/issues/266)).
This is why we are "forced" to run `diffoci` with the `--semantic` flag
([a.k.a "non-strict" mode](https://github.com/reproducible-containers/diffoci?tab=readme-ov-file#non-strict-aka-semantic-mode)),
which ignores some attributes, including image name annotations.
While having to run `diffoci` with the `--semantic` flag (for the lack of another option)
just to workaround this technical constraint is unfortunate, we can attest that:
* This limitation is specific to metadata handling in container tooling and does not
affect the actual filesystem contents or runtime behavior of the image.
* The reported difference in the image name annotation when running `diffoci` in default / strict mode
is (or is supposed to be, at least) the **only** difference being reported when comparing the two images.
* This image name annotation is not part of the hashed object when generating the image digest,
meaning that this difference does not prevent digest equality between the two images (allowing
us to claim bit for bit reproducibility regardless).

View File

@ -7,16 +7,27 @@ declare -r GROUP="$2"
declare -r OUTPUTDIR="$3"
declare -r DOWNLOAD="$4"
declare -r TITLE="$5"
declare -rx SOURCE_DATE_EPOCH="$6"
# Do not use these directly in the sed below - it will mask git failures
BUILD_VERSION="${BUILD_VERSION:-dev}"
CI_COMMIT_SHA="${CI_COMMIT_SHA:-$(git rev-parse HEAD)}"
# Honor SOURCE_DATE_EPOCH and delete non-determistic ldconfig auxiliary cache file for the repro GROUP
if [[ "$GROUP" == "repro" ]]; then
CREATED_TIMESTAMP=$(date -u -d "@$SOURCE_DATE_EPOCH" +%Y-%m-%dT%H:%M:%SZ)
LDCONFIG_AUX_CACHE="rm -f /var/cache/ldconfig/aux-cache"
else
CREATED_TIMESTAMP=$(date -Is)
LDCONFIG_AUX_CACHE="true"
fi
sed -e "s|TEMPLATE_ROOTFS_FILE|$ROOTFS_FILE|" \
-e "s|TEMPLATE_ROOTFS_DOWNLOAD|$DOWNLOAD|" \
-e "s|TEMPLATE_ROOTFS_HASH|$(cat $OUTPUTDIR/$ROOTFS_FILE.SHA256)|" \
-e "s|TEMPLATE_TITLE|Arch Linux $TITLE Image|" \
-e "s|TEMPLATE_VERSION_ID|$BUILD_VERSION|" \
-e "s|TEMPLATE_REVISION|$CI_COMMIT_SHA|" \
-e "s|TEMPLATE_CREATED|$(date -Is)|" \
-e "s|TEMPLATE_CREATED|$CREATED_TIMESTAMP|" \
-e "s|LDCONFIG_AUX_CACHE|$LDCONFIG_AUX_CACHE|" \
Dockerfile.template > "$OUTPUTDIR/Dockerfile.$GROUP"

View File

@ -7,6 +7,8 @@ declare -r WRAPPER="fakechroot -- fakeroot"
declare -r GROUP="$1"
declare -r BUILDDIR="$2"
declare -r OUTPUTDIR="$3"
declare -r ARCHIVE_SNAPSHOT="$4"
declare -rx SOURCE_DATE_EPOCH="$5"
mkdir -vp "$BUILDDIR/alpm-hooks/usr/share/libalpm/hooks"
find /usr/share/libalpm/hooks -exec ln -sf /dev/null "$BUILDDIR/alpm-hooks"{} \;
@ -33,24 +35,51 @@ fi
cp --recursive --preserve=timestamps rootfs/* "$BUILDDIR/"
ln -fs /usr/lib/os-release "$BUILDDIR/etc/os-release"
# Use archived repo snapshot from archive.archlinux.org for reproducible builds
if [[ "$GROUP" == "repro" ]]; then
sed -i "1iServer = https://archive.archlinux.org/repos/$ARCHIVE_SNAPSHOT/\\\$repo/os/\\\$arch" "$BUILDDIR/etc/pacman.d/mirrorlist"
repro_pacman_options=(
--logfile /dev/null
)
fi
$WRAPPER -- \
pacman -Sy -r "$BUILDDIR" \
--disable-sandbox-filesystem \
--noconfirm --dbpath "$BUILDDIR/var/lib/pacman" \
--config pacman.conf \
--noscriptlet \
--hookdir "$BUILDDIR/alpm-hooks/usr/share/libalpm/hooks/" base "$GROUP"
"${repro_pacman_options[@]}" \
--hookdir "$BUILDDIR/alpm-hooks/usr/share/libalpm/hooks/" base ${GROUP:+${GROUP/repro/}} # repro is not a package
$WRAPPER -- chroot "$BUILDDIR" update-ca-trust
$WRAPPER -- chroot "$BUILDDIR" pacman-key --init
$WRAPPER -- chroot "$BUILDDIR" pacman-key --populate
if [[ "$GROUP" == "repro" ]]; then
# Remove archived repo snapshot from the mirrorlist
sed -i '1d' "$BUILDDIR/etc/pacman.d/mirrorlist"
# Clear pacman keyring for reproducible builds
rm -rf "$BUILDDIR"/etc/pacman.d/gnupg/*
# Normalize mtimes
find "$BUILDDIR" -exec touch --no-dereference --date="@$SOURCE_DATE_EPOCH" {} +
fi
# add system users
$WRAPPER -- chroot "$BUILDDIR" /usr/bin/systemd-sysusers --root "/"
# remove passwordless login for root (see CVE-2019-5021 for reference)
sed -i -e 's/^root::/root:!:/' "$BUILDDIR/etc/shadow"
if [[ "$GROUP" == "repro" ]]; then
repro_tar_options=(
--mtime="@$SOURCE_DATE_EPOCH"
--clamp-mtime
--sort=name
--pax-option=delete=atime,delete=ctime
)
fi
# fakeroot to map the gid/uid of the builder process to root
# fixes #22
fakeroot -- \
@ -58,6 +87,7 @@ fakeroot -- \
--numeric-owner \
--xattrs \
--acls \
"${repro_tar_options[@]}" \
--exclude-from=exclude \
-C "$BUILDDIR" \
-c . \