diff --git a/Dockerfile-builder.template b/Dockerfile-builder.template index 3205698c..68c81ef7 100644 --- a/Dockerfile-builder.template +++ b/Dockerfile-builder.template @@ -13,6 +13,8 @@ RUN set -eux; \ musl-dev \ patch \ tzdata \ +# busybox's tar ironically does not maintain mtime of directories correctly (which we need for SOURCE_DATE_EPOCH / reproducibility) + tar \ ; {{ ) else ( -}} FROM debian:bookworm-slim @@ -234,14 +236,28 @@ RUN set -eux; \ curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \ echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \ gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \ - mkdir -p /usr/src/busybox; \ - tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \ - rm busybox.tar.bz2* +# Alpine... 😅 + mkdir -p /usr/src; \ + tar -xf busybox.tar.bz2 -C /usr/src "busybox-$BUSYBOX_VERSION"; \ + mv "/usr/src/busybox-$BUSYBOX_VERSION" /usr/src/busybox; \ + rm busybox.tar.bz2*; \ + \ +# save the tarball's filesystem timestamp persistently (in case building busybox modifies it) so we can use it for reproducible rootfs later + SOURCE_DATE_EPOCH="$(stat -c '%Y' /usr/src/busybox | tee /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + date="$(date -d "@$SOURCE_DATE_EPOCH" '+%Y%m%d%H%M.%S')"; \ + touch -t "$date" /usr/src/busybox.SOURCE_DATE_EPOCH; \ +# for logging validation/edification + date --date "@$SOURCE_DATE_EPOCH" --rfc-2822 WORKDIR /usr/src/busybox RUN set -eux; \ \ +# build date/time gets embedded in the BusyBox binary -- SOURCE_DATE_EPOCH should override that + SOURCE_DATE_EPOCH="$(cat /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + export SOURCE_DATE_EPOCH; \ +# (has to be set in the config stage for making sure "AUTOCONF_TIMESTAMP" is embedded correctly) + \ setConfs=' \ CONFIG_AR=y \ CONFIG_FEATURE_AR_CREATE=y \ @@ -249,7 +265,7 @@ RUN set -eux; \ # CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input) CONFIG_LAST_SUPPORTED_WCHAR=0 \ {{ if env.variant == "glibc" then ( -}} -# As long as we rely on libnss (see below), we have to have libc.so anyhow, so we've removed CONFIG_STATIC here... :cry: +# As long as we rely on libnss (see below), we have to have libc.so anyhow, so we've removed CONFIG_STATIC here... 😭 {{ ) else ( -}} CONFIG_STATIC=y \ {{ ) end -}} @@ -361,6 +377,7 @@ RUN set -eux; \ {{ ) else "" end -}} chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \ \ +# TODO make this create symlinks instead so the output tarball is cleaner (but "-s" outputs absolute symlinks which is kind of annoying to deal with -- we should also consider letting busybox determine the "install paths"; see "busybox --list-full") chroot rootfs /bin/busybox --install /bin # install a few extra files from buildroot (/etc/passwd, etc) diff --git a/build.sh b/build.sh index 8943ff00..003d7627 100755 --- a/build.sh +++ b/build.sh @@ -13,7 +13,17 @@ for dir; do ( set -x docker build -t "$base-builder" -f "$dir/Dockerfile.builder" "$dir" - docker run --rm "$base-builder" tar cC rootfs . | xz -T0 -z9 > "$dir/busybox.tar.xz" + docker run --rm "$base-builder" \ + tar \ + --create \ + --directory rootfs \ + --numeric-owner \ + --transform 's,^./,,' \ + --sort name \ + --mtime /usr/src/busybox.SOURCE_DATE_EPOCH --clamp-mtime \ + . \ + | xz -T0 -z9 > "$dir/busybox.tar.xz" + sha256sum "$dir/busybox.tar.xz" docker build -t "$base-test" "$dir" docker run --rm "$base-test" sh -xec 'true' diff --git a/latest-1/glibc/Dockerfile.builder b/latest-1/glibc/Dockerfile.builder index 37033f48..5d676984 100644 --- a/latest-1/glibc/Dockerfile.builder +++ b/latest-1/glibc/Dockerfile.builder @@ -34,21 +34,35 @@ RUN set -eux; \ curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \ echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \ gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \ - mkdir -p /usr/src/busybox; \ - tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \ - rm busybox.tar.bz2* +# Alpine... 😅 + mkdir -p /usr/src; \ + tar -xf busybox.tar.bz2 -C /usr/src "busybox-$BUSYBOX_VERSION"; \ + mv "/usr/src/busybox-$BUSYBOX_VERSION" /usr/src/busybox; \ + rm busybox.tar.bz2*; \ + \ +# save the tarball's filesystem timestamp persistently (in case building busybox modifies it) so we can use it for reproducible rootfs later + SOURCE_DATE_EPOCH="$(stat -c '%Y' /usr/src/busybox | tee /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + date="$(date -d "@$SOURCE_DATE_EPOCH" '+%Y%m%d%H%M.%S')"; \ + touch -t "$date" /usr/src/busybox.SOURCE_DATE_EPOCH; \ +# for logging validation/edification + date --date "@$SOURCE_DATE_EPOCH" --rfc-2822 WORKDIR /usr/src/busybox RUN set -eux; \ \ +# build date/time gets embedded in the BusyBox binary -- SOURCE_DATE_EPOCH should override that + SOURCE_DATE_EPOCH="$(cat /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + export SOURCE_DATE_EPOCH; \ +# (has to be set in the config stage for making sure "AUTOCONF_TIMESTAMP" is embedded correctly) + \ setConfs=' \ CONFIG_AR=y \ CONFIG_FEATURE_AR_CREATE=y \ CONFIG_FEATURE_AR_LONG_FILENAMES=y \ # CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input) CONFIG_LAST_SUPPORTED_WCHAR=0 \ -# As long as we rely on libnss (see below), we have to have libc.so anyhow, so we've removed CONFIG_STATIC here... :cry: +# As long as we rely on libnss (see below), we have to have libc.so anyhow, so we've removed CONFIG_STATIC here... 😭 '; \ \ unsetConfs=' \ @@ -130,6 +144,7 @@ RUN set -eux; \ done; \ chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \ \ +# TODO make this create symlinks instead so the output tarball is cleaner (but "-s" outputs absolute symlinks which is kind of annoying to deal with -- we should also consider letting busybox determine the "install paths"; see "busybox --list-full") chroot rootfs /bin/busybox --install /bin # install a few extra files from buildroot (/etc/passwd, etc) diff --git a/latest-1/musl/Dockerfile.builder b/latest-1/musl/Dockerfile.builder index 06c60e07..3000924e 100644 --- a/latest-1/musl/Dockerfile.builder +++ b/latest-1/musl/Dockerfile.builder @@ -18,6 +18,8 @@ RUN set -eux; \ musl-dev \ patch \ tzdata \ +# busybox's tar ironically does not maintain mtime of directories correctly (which we need for SOURCE_DATE_EPOCH / reproducibility) + tar \ ; # pub 1024D/ACC9965B 2006-12-12 @@ -36,14 +38,28 @@ RUN set -eux; \ curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \ echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \ gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \ - mkdir -p /usr/src/busybox; \ - tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \ - rm busybox.tar.bz2* +# Alpine... 😅 + mkdir -p /usr/src; \ + tar -xf busybox.tar.bz2 -C /usr/src "busybox-$BUSYBOX_VERSION"; \ + mv "/usr/src/busybox-$BUSYBOX_VERSION" /usr/src/busybox; \ + rm busybox.tar.bz2*; \ + \ +# save the tarball's filesystem timestamp persistently (in case building busybox modifies it) so we can use it for reproducible rootfs later + SOURCE_DATE_EPOCH="$(stat -c '%Y' /usr/src/busybox | tee /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + date="$(date -d "@$SOURCE_DATE_EPOCH" '+%Y%m%d%H%M.%S')"; \ + touch -t "$date" /usr/src/busybox.SOURCE_DATE_EPOCH; \ +# for logging validation/edification + date --date "@$SOURCE_DATE_EPOCH" --rfc-2822 WORKDIR /usr/src/busybox RUN set -eux; \ \ +# build date/time gets embedded in the BusyBox binary -- SOURCE_DATE_EPOCH should override that + SOURCE_DATE_EPOCH="$(cat /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + export SOURCE_DATE_EPOCH; \ +# (has to be set in the config stage for making sure "AUTOCONF_TIMESTAMP" is embedded correctly) + \ setConfs=' \ CONFIG_AR=y \ CONFIG_FEATURE_AR_CREATE=y \ @@ -110,6 +126,7 @@ RUN set -eux; \ gcc -o rootfs/bin/getconf -static -Os /usr/src/getconf.c; \ chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \ \ +# TODO make this create symlinks instead so the output tarball is cleaner (but "-s" outputs absolute symlinks which is kind of annoying to deal with -- we should also consider letting busybox determine the "install paths"; see "busybox --list-full") chroot rootfs /bin/busybox --install /bin # install a few extra files from buildroot (/etc/passwd, etc) diff --git a/latest-1/uclibc/Dockerfile.builder b/latest-1/uclibc/Dockerfile.builder index 23f930fa..12a38938 100644 --- a/latest-1/uclibc/Dockerfile.builder +++ b/latest-1/uclibc/Dockerfile.builder @@ -220,14 +220,28 @@ RUN set -eux; \ curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \ echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \ gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \ - mkdir -p /usr/src/busybox; \ - tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \ - rm busybox.tar.bz2* +# Alpine... 😅 + mkdir -p /usr/src; \ + tar -xf busybox.tar.bz2 -C /usr/src "busybox-$BUSYBOX_VERSION"; \ + mv "/usr/src/busybox-$BUSYBOX_VERSION" /usr/src/busybox; \ + rm busybox.tar.bz2*; \ + \ +# save the tarball's filesystem timestamp persistently (in case building busybox modifies it) so we can use it for reproducible rootfs later + SOURCE_DATE_EPOCH="$(stat -c '%Y' /usr/src/busybox | tee /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + date="$(date -d "@$SOURCE_DATE_EPOCH" '+%Y%m%d%H%M.%S')"; \ + touch -t "$date" /usr/src/busybox.SOURCE_DATE_EPOCH; \ +# for logging validation/edification + date --date "@$SOURCE_DATE_EPOCH" --rfc-2822 WORKDIR /usr/src/busybox RUN set -eux; \ \ +# build date/time gets embedded in the BusyBox binary -- SOURCE_DATE_EPOCH should override that + SOURCE_DATE_EPOCH="$(cat /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + export SOURCE_DATE_EPOCH; \ +# (has to be set in the config stage for making sure "AUTOCONF_TIMESTAMP" is embedded correctly) + \ setConfs=' \ CONFIG_AR=y \ CONFIG_FEATURE_AR_CREATE=y \ @@ -285,6 +299,7 @@ RUN set -eux; \ ln -vL ../buildroot/output/target/usr/bin/getconf rootfs/bin/; \ chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \ \ +# TODO make this create symlinks instead so the output tarball is cleaner (but "-s" outputs absolute symlinks which is kind of annoying to deal with -- we should also consider letting busybox determine the "install paths"; see "busybox --list-full") chroot rootfs /bin/busybox --install /bin # install a few extra files from buildroot (/etc/passwd, etc) diff --git a/latest/glibc/Dockerfile.builder b/latest/glibc/Dockerfile.builder index c2333572..5e9323ef 100644 --- a/latest/glibc/Dockerfile.builder +++ b/latest/glibc/Dockerfile.builder @@ -34,21 +34,35 @@ RUN set -eux; \ curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \ echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \ gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \ - mkdir -p /usr/src/busybox; \ - tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \ - rm busybox.tar.bz2* +# Alpine... 😅 + mkdir -p /usr/src; \ + tar -xf busybox.tar.bz2 -C /usr/src "busybox-$BUSYBOX_VERSION"; \ + mv "/usr/src/busybox-$BUSYBOX_VERSION" /usr/src/busybox; \ + rm busybox.tar.bz2*; \ + \ +# save the tarball's filesystem timestamp persistently (in case building busybox modifies it) so we can use it for reproducible rootfs later + SOURCE_DATE_EPOCH="$(stat -c '%Y' /usr/src/busybox | tee /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + date="$(date -d "@$SOURCE_DATE_EPOCH" '+%Y%m%d%H%M.%S')"; \ + touch -t "$date" /usr/src/busybox.SOURCE_DATE_EPOCH; \ +# for logging validation/edification + date --date "@$SOURCE_DATE_EPOCH" --rfc-2822 WORKDIR /usr/src/busybox RUN set -eux; \ \ +# build date/time gets embedded in the BusyBox binary -- SOURCE_DATE_EPOCH should override that + SOURCE_DATE_EPOCH="$(cat /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + export SOURCE_DATE_EPOCH; \ +# (has to be set in the config stage for making sure "AUTOCONF_TIMESTAMP" is embedded correctly) + \ setConfs=' \ CONFIG_AR=y \ CONFIG_FEATURE_AR_CREATE=y \ CONFIG_FEATURE_AR_LONG_FILENAMES=y \ # CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input) CONFIG_LAST_SUPPORTED_WCHAR=0 \ -# As long as we rely on libnss (see below), we have to have libc.so anyhow, so we've removed CONFIG_STATIC here... :cry: +# As long as we rely on libnss (see below), we have to have libc.so anyhow, so we've removed CONFIG_STATIC here... 😭 '; \ \ unsetConfs=' \ @@ -128,6 +142,7 @@ RUN set -eux; \ done; \ chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \ \ +# TODO make this create symlinks instead so the output tarball is cleaner (but "-s" outputs absolute symlinks which is kind of annoying to deal with -- we should also consider letting busybox determine the "install paths"; see "busybox --list-full") chroot rootfs /bin/busybox --install /bin # install a few extra files from buildroot (/etc/passwd, etc) diff --git a/latest/musl/Dockerfile.builder b/latest/musl/Dockerfile.builder index 51881dfb..fe395ade 100644 --- a/latest/musl/Dockerfile.builder +++ b/latest/musl/Dockerfile.builder @@ -18,6 +18,8 @@ RUN set -eux; \ musl-dev \ patch \ tzdata \ +# busybox's tar ironically does not maintain mtime of directories correctly (which we need for SOURCE_DATE_EPOCH / reproducibility) + tar \ ; # pub 1024D/ACC9965B 2006-12-12 @@ -36,14 +38,28 @@ RUN set -eux; \ curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \ echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \ gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \ - mkdir -p /usr/src/busybox; \ - tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \ - rm busybox.tar.bz2* +# Alpine... 😅 + mkdir -p /usr/src; \ + tar -xf busybox.tar.bz2 -C /usr/src "busybox-$BUSYBOX_VERSION"; \ + mv "/usr/src/busybox-$BUSYBOX_VERSION" /usr/src/busybox; \ + rm busybox.tar.bz2*; \ + \ +# save the tarball's filesystem timestamp persistently (in case building busybox modifies it) so we can use it for reproducible rootfs later + SOURCE_DATE_EPOCH="$(stat -c '%Y' /usr/src/busybox | tee /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + date="$(date -d "@$SOURCE_DATE_EPOCH" '+%Y%m%d%H%M.%S')"; \ + touch -t "$date" /usr/src/busybox.SOURCE_DATE_EPOCH; \ +# for logging validation/edification + date --date "@$SOURCE_DATE_EPOCH" --rfc-2822 WORKDIR /usr/src/busybox RUN set -eux; \ \ +# build date/time gets embedded in the BusyBox binary -- SOURCE_DATE_EPOCH should override that + SOURCE_DATE_EPOCH="$(cat /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + export SOURCE_DATE_EPOCH; \ +# (has to be set in the config stage for making sure "AUTOCONF_TIMESTAMP" is embedded correctly) + \ setConfs=' \ CONFIG_AR=y \ CONFIG_FEATURE_AR_CREATE=y \ @@ -108,6 +124,7 @@ RUN set -eux; \ gcc -o rootfs/bin/getconf -static -Os /usr/src/getconf.c; \ chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \ \ +# TODO make this create symlinks instead so the output tarball is cleaner (but "-s" outputs absolute symlinks which is kind of annoying to deal with -- we should also consider letting busybox determine the "install paths"; see "busybox --list-full") chroot rootfs /bin/busybox --install /bin # install a few extra files from buildroot (/etc/passwd, etc) diff --git a/latest/uclibc/Dockerfile.builder b/latest/uclibc/Dockerfile.builder index 293eb8ca..89b806ec 100644 --- a/latest/uclibc/Dockerfile.builder +++ b/latest/uclibc/Dockerfile.builder @@ -220,14 +220,28 @@ RUN set -eux; \ curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \ echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \ gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \ - mkdir -p /usr/src/busybox; \ - tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \ - rm busybox.tar.bz2* +# Alpine... 😅 + mkdir -p /usr/src; \ + tar -xf busybox.tar.bz2 -C /usr/src "busybox-$BUSYBOX_VERSION"; \ + mv "/usr/src/busybox-$BUSYBOX_VERSION" /usr/src/busybox; \ + rm busybox.tar.bz2*; \ + \ +# save the tarball's filesystem timestamp persistently (in case building busybox modifies it) so we can use it for reproducible rootfs later + SOURCE_DATE_EPOCH="$(stat -c '%Y' /usr/src/busybox | tee /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + date="$(date -d "@$SOURCE_DATE_EPOCH" '+%Y%m%d%H%M.%S')"; \ + touch -t "$date" /usr/src/busybox.SOURCE_DATE_EPOCH; \ +# for logging validation/edification + date --date "@$SOURCE_DATE_EPOCH" --rfc-2822 WORKDIR /usr/src/busybox RUN set -eux; \ \ +# build date/time gets embedded in the BusyBox binary -- SOURCE_DATE_EPOCH should override that + SOURCE_DATE_EPOCH="$(cat /usr/src/busybox.SOURCE_DATE_EPOCH)"; \ + export SOURCE_DATE_EPOCH; \ +# (has to be set in the config stage for making sure "AUTOCONF_TIMESTAMP" is embedded correctly) + \ setConfs=' \ CONFIG_AR=y \ CONFIG_FEATURE_AR_CREATE=y \ @@ -283,6 +297,7 @@ RUN set -eux; \ ln -vL ../buildroot/output/target/usr/bin/getconf rootfs/bin/; \ chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \ \ +# TODO make this create symlinks instead so the output tarball is cleaner (but "-s" outputs absolute symlinks which is kind of annoying to deal with -- we should also consider letting busybox determine the "install paths"; see "busybox --list-full") chroot rootfs /bin/busybox --install /bin # install a few extra files from buildroot (/etc/passwd, etc)