public inbox for isar-users@googlegroups.com
 help / color / mirror / Atom feed
* [PATCH v3 00/10] Make rootfs build reproducible
@ 2023-01-16  3:35 Felix Moessbauer
  2023-01-16  3:35 ` [PATCH v3 01/10] image: make sure do_rootfs_finalize can run multiple times Felix Moessbauer
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Felix Moessbauer @ 2023-01-16  3:35 UTC (permalink / raw)
  To: isar-users
  Cc: jan.kiszka, daniel.bovensiepen, henning.schild, venkata.pyla,
	Felix Moessbauer

This series finally makes the rootfs generation bit-reproducible
from debian bullseye on. Parts of it have already been sent
as individual patches. However, image reproducibility can only
be achived once all parts are reproducible itself. By that,
these patches are included in this series as well.

With this series, the following parts are now fully reproducible.
This has been tested on the isar-image-base target.

- custom initramfs (creation and updates)
- debian initramfs (only updates are relevant)
- custom kernel (debian kernel is reproducible itself)
- rootfs itself
- tar file generation (<image>.tar)
- ext4 generation (only from bookworm on, more tests needed)

Other parts that are still not reproducible are:

- WIC (should be solved in OE already)
- containers (untested yet)
- SDK (note added in v3)

Changes since v2:

- fix issue issue when SOURCE_DATE_EPOCH is not defined
- replaced "fix rebuild of rootfs_finalize task" with Hennings version
- minor style fix in image-account-extension

Changes since v1:

- dropped patch "deb_add_changelog: use SOURCE_DATE_EPOCH"
- fixed typo in "generate deterministic clear-text password hash"
- added comment about why SOURCE_DATE_EPOCH must only be set for
  image rootfs but not for other rootfs'.

Best regards,
Felix Moessbauer
Siemens AG

Felix Moessbauer (8):
  rootfs postprocess: clean python cache
  remove non-portable ldconfig aux-cache
  generate deterministic clear-text password hash
  update debian initramfs in deterministic mode
  create custom initramfs in deterministic mode
  make deb_add_changelog idempotent
  deb_add_changelog: set timestamp to valid epoch
  make custom linux-image bit-by-bit reproducible

Henning Schild (1):
  image: make sure do_rootfs_finalize can run multiple times

venkata pyla (1):
  image.bbclass: fix non-reproducible file time-stamps inside rootfs

 meta-isar/conf/local.conf.sample              | 10 +++++
 meta/classes/debianize.bbclass                | 20 ++++++----
 meta/classes/image-account-extension.bbclass  | 10 ++++-
 meta/classes/image.bbclass                    | 39 +++++++++++++++----
 meta/classes/initramfs.bbclass                |  5 +++
 meta/classes/rootfs.bbclass                   | 13 +++++++
 .../linux/files/debian/isar/build.tmpl        |  1 +
 .../linux/files/debian/rules.tmpl             | 14 ++++++-
 meta/recipes-kernel/linux/linux-custom.inc    |  2 +
 9 files changed, 98 insertions(+), 16 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 01/10] image: make sure do_rootfs_finalize can run multiple times
  2023-01-16  3:35 [PATCH v3 00/10] Make rootfs build reproducible Felix Moessbauer
@ 2023-01-16  3:35 ` Felix Moessbauer
  2023-01-16  3:35 ` [PATCH v3 02/10] image.bbclass: fix non-reproducible file time-stamps inside rootfs Felix Moessbauer
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Felix Moessbauer @ 2023-01-16  3:35 UTC (permalink / raw)
  To: isar-users; +Cc: jan.kiszka, daniel.bovensiepen, henning.schild, venkata.pyla

From: Henning Schild <henning.schild@siemens.com>

There have been several places that would not work twice in a row. All
the test && not covering || have been moved to if. The rm at the end
tried to remove a file that was just moved. And that mv would not work a
second time because its source would be gone.

Signed-off-by: Henning Schild <henning.schild@siemens.com>
---
 meta/classes/image.bbclass | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
index 629a0c1..125eba1 100644
--- a/meta/classes/image.bbclass
+++ b/meta/classes/image.bbclass
@@ -396,13 +396,16 @@ addtask deploy before do_build after do_image
 do_rootfs_finalize() {
     sudo -s <<'EOSUDO'
         set -e
-        test -e "${ROOTFSDIR}/chroot-setup.sh" && \
+
+        if [ -e "${ROOTFSDIR}/chroot-setup.sh" ]; then
             "${ROOTFSDIR}/chroot-setup.sh" "cleanup" "${ROOTFSDIR}"
+        fi
         rm -f "${ROOTFSDIR}/chroot-setup.sh"
 
-        test ! -e "${ROOTFSDIR}/usr/share/doc/qemu-user-static" && \
+        if [ ! -e "${ROOTFSDIR}/usr/share/doc/qemu-user-static" ]; then
             find "${ROOTFSDIR}/usr/bin" \
                 -maxdepth 1 -name 'qemu-*-static' -type f -delete
+        fi
 
         mountpoint -q '${ROOTFSDIR}/isar-apt' && \
             umount -l ${ROOTFSDIR}/isar-apt && \
@@ -424,10 +427,10 @@ do_rootfs_finalize() {
         rm -f "${ROOTFSDIR}/etc/apt/sources.list.d/base-apt.list"
         rm -f "${ROOTFSDIR}/etc/apt/apt.conf.d/50isar"
 
-        mv "${ROOTFSDIR}/etc/apt/sources-list" \
-            "${ROOTFSDIR}/etc/apt/sources.list.d/bootstrap.list"
-
-        rm -f "${ROOTFSDIR}/etc/apt/sources-list"
+        if [ -e "${ROOTFSDIR}/etc/apt/sources-list" ]; then
+            mv "${ROOTFSDIR}/etc/apt/sources-list" \
+                "${ROOTFSDIR}/etc/apt/sources.list.d/bootstrap.list"
+        fi
 EOSUDO
 }
 addtask rootfs_finalize before do_rootfs after do_rootfs_postprocess
-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 02/10] image.bbclass: fix non-reproducible file time-stamps inside rootfs
  2023-01-16  3:35 [PATCH v3 00/10] Make rootfs build reproducible Felix Moessbauer
  2023-01-16  3:35 ` [PATCH v3 01/10] image: make sure do_rootfs_finalize can run multiple times Felix Moessbauer
@ 2023-01-16  3:35 ` Felix Moessbauer
  2023-01-16  3:35 ` [PATCH v3 03/10] rootfs postprocess: clean python cache Felix Moessbauer
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Felix Moessbauer @ 2023-01-16  3:35 UTC (permalink / raw)
  To: isar-users
  Cc: jan.kiszka, daniel.bovensiepen, henning.schild, venkata.pyla,
	Felix Moessbauer

From: venkata pyla <venkata.pyla@toshiba-tsip.com>

As part of reproducible-build work, the rootfs images generated on same
source should be identical between two builds.

In this commit it tries to solve one of the non-reproducible problem
i.e. the rootfs file time-stamps generated during build time are not
reproducible, it uses one of the solution provided in the debian
live-build image project (refer [1]), it fixes by finding all the
files/folders that are gernerated newly and set the time-stamp provided
by `SOURCE_DATE_EPOCH` environment variable.

[1] https://salsa.debian.org/live-team/live-build/-/merge_requests/218

Acked-by: Felix Moessbauer <felix.moessbauer@siemens.com>
Signed-off-by: venkata pyla <venkata.pyla@toshiba-tsip.com>
---
 meta-isar/conf/local.conf.sample | 10 ++++++++++
 meta/classes/image.bbclass       | 11 +++++++++++
 2 files changed, 21 insertions(+)

diff --git a/meta-isar/conf/local.conf.sample b/meta-isar/conf/local.conf.sample
index e1cd66e..6208623 100644
--- a/meta-isar/conf/local.conf.sample
+++ b/meta-isar/conf/local.conf.sample
@@ -248,3 +248,13 @@ USER_isar[flags] += "clear-text-password"
 #CCACHE_TOP_DIR ?= "${TMPDIR}/ccache"
 # Enable ccache debug mode
 #CCACHE_DEBUG = "1"
+
+# Uncommnet and add value to it to build images reproducibly
+#
+# The value for `SOURCE_DATE_EPOCH` should be latest source change time in
+# seconds since the Epoch.
+# Git repository users can use value from 'git log -1 --pretty=%ct'
+# Non git repository users can use value from 'stat -c%Y ChangeLog'
+# To know more details about this variable and how to set the value refer below
+# https://reproducible-builds.org/docs/source-date-epoch/
+#SOURCE_DATE_EPOCH =
diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
index 125eba1..9e0f5f7 100644
--- a/meta/classes/image.bbclass
+++ b/meta/classes/image.bbclass
@@ -432,6 +432,17 @@ do_rootfs_finalize() {
                 "${ROOTFSDIR}/etc/apt/sources.list.d/bootstrap.list"
         fi
 EOSUDO
+
+    # Set same time-stamps to the newly generated file/folders in the
+    # rootfs image for the purpose of reproducible builds.
+    if [ -n "${SOURCE_DATE_EPOCH}" ]; then
+        sudo find ${ROOTFSDIR} -newermt \
+            "$(date -d@${SOURCE_DATE_EPOCH} '+%Y-%m-%d %H:%M:%S')" \
+            -printf "%y %p\n" \
+            -exec touch '{}' -h -d@${SOURCE_DATE_EPOCH} ';' > ${DEPLOY_DIR_IMAGE}/files.modified_timestamps && \
+            bbwarn "$(grep ^f ${DEPLOY_DIR_IMAGE}/files.modified_timestamps) \nModified above file timestamps to build image reproducibly"
+    fi
+
 }
 addtask rootfs_finalize before do_rootfs after do_rootfs_postprocess
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 03/10] rootfs postprocess: clean python cache
  2023-01-16  3:35 [PATCH v3 00/10] Make rootfs build reproducible Felix Moessbauer
  2023-01-16  3:35 ` [PATCH v3 01/10] image: make sure do_rootfs_finalize can run multiple times Felix Moessbauer
  2023-01-16  3:35 ` [PATCH v3 02/10] image.bbclass: fix non-reproducible file time-stamps inside rootfs Felix Moessbauer
@ 2023-01-16  3:35 ` Felix Moessbauer
  2023-01-16  3:35 ` [PATCH v3 04/10] remove non-portable ldconfig aux-cache Felix Moessbauer
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Felix Moessbauer @ 2023-01-16  3:35 UTC (permalink / raw)
  To: isar-users
  Cc: jan.kiszka, daniel.bovensiepen, henning.schild, venkata.pyla,
	Felix Moessbauer

When calling python scripts, python automatically creates cache files
to speedup future invocations of the same sources. This often happens
in postinst scripts, that directly run in the image chroot. The
created debian packages do not ship these files, as the debheper
scripts remove them before installing.

For the rootfs part, we manually have to do it to also not
include these in the final image. This patch implements this logic in
a custom cleanup postprocess step. As there might be situations where
shipping of a subset of the caches is desireable (e.g. readonly rootfs
images), we add support to control this logic using ROOTFS_FEATURES.

Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
---
 meta/classes/image.bbclass  | 2 +-
 meta/classes/rootfs.bbclass | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
index 9e0f5f7..6a3f99e 100644
--- a/meta/classes/image.bbclass
+++ b/meta/classes/image.bbclass
@@ -80,7 +80,7 @@ image_do_mounts() {
 }
 
 ROOTFSDIR = "${IMAGE_ROOTFS}"
-ROOTFS_FEATURES += "clean-package-cache generate-manifest export-dpkg-status clean-log-files clean-debconf-cache"
+ROOTFS_FEATURES += "clean-package-cache clean-pycache generate-manifest export-dpkg-status clean-log-files clean-debconf-cache"
 ROOTFS_PACKAGES += "${IMAGE_PREINSTALL} ${IMAGE_INSTALL}"
 ROOTFS_MANIFEST_DEPLOY_DIR ?= "${DEPLOY_DIR_IMAGE}"
 ROOTFS_DPKGSTATUS_DEPLOY_DIR ?= "${DEPLOY_DIR_IMAGE}"
diff --git a/meta/classes/rootfs.bbclass b/meta/classes/rootfs.bbclass
index 786682d..325e7ae 100644
--- a/meta/classes/rootfs.bbclass
+++ b/meta/classes/rootfs.bbclass
@@ -252,6 +252,12 @@ rootfs_postprocess_clean_debconf_cache() {
     sudo rm -rf "${ROOTFSDIR}/var/cache/debconf/"*
 }
 
+ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'clean-pycache', 'rootfs_postprocess_clean_pycache', '', d)}"
+rootfs_postprocess_clean_pycache() {
+    sudo find ${ROOTFSDIR}/usr -type f -name '*.pyc'       -delete -print
+    sudo find ${ROOTFSDIR}/usr -type d -name '__pycache__' -delete -print
+}
+
 ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'generate-manifest', 'rootfs_generate_manifest', '', d)}"
 rootfs_generate_manifest () {
     mkdir -p ${ROOTFS_MANIFEST_DEPLOY_DIR}
-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 04/10] remove non-portable ldconfig aux-cache
  2023-01-16  3:35 [PATCH v3 00/10] Make rootfs build reproducible Felix Moessbauer
                   ` (2 preceding siblings ...)
  2023-01-16  3:35 ` [PATCH v3 03/10] rootfs postprocess: clean python cache Felix Moessbauer
@ 2023-01-16  3:35 ` Felix Moessbauer
  2023-01-16  3:35 ` [PATCH v3 05/10] generate deterministic clear-text password hash Felix Moessbauer
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Felix Moessbauer @ 2023-01-16  3:35 UTC (permalink / raw)
  To: isar-users
  Cc: jan.kiszka, daniel.bovensiepen, henning.schild, venkata.pyla,
	Felix Moessbauer

This patch removes the ldconfig aux-cache from the final rootfs.
The cache is both not portable across file systems, as well as non
reproducible.

Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
---
 meta/classes/rootfs.bbclass | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/meta/classes/rootfs.bbclass b/meta/classes/rootfs.bbclass
index 325e7ae..226fa8b 100644
--- a/meta/classes/rootfs.bbclass
+++ b/meta/classes/rootfs.bbclass
@@ -258,6 +258,13 @@ rootfs_postprocess_clean_pycache() {
     sudo find ${ROOTFSDIR}/usr -type d -name '__pycache__' -delete -print
 }
 
+ROOTFS_POSTPROCESS_COMMAND += "rootfs_postprocess_clean_ldconfig_cache"
+rootfs_postprocess_clean_ldconfig_cache() {
+    # the ldconfig aux-cache is not portable and breaks reproducability
+    # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=845034#49
+    sudo rm -f ${ROOTFSDIR}/var/cache/ldconfig/aux-cache
+}
+
 ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'generate-manifest', 'rootfs_generate_manifest', '', d)}"
 rootfs_generate_manifest () {
     mkdir -p ${ROOTFS_MANIFEST_DEPLOY_DIR}
-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 05/10] generate deterministic clear-text password hash
  2023-01-16  3:35 [PATCH v3 00/10] Make rootfs build reproducible Felix Moessbauer
                   ` (3 preceding siblings ...)
  2023-01-16  3:35 ` [PATCH v3 04/10] remove non-portable ldconfig aux-cache Felix Moessbauer
@ 2023-01-16  3:35 ` Felix Moessbauer
  2023-01-16  3:35 ` [PATCH v3 06/10] update debian initramfs in deterministic mode Felix Moessbauer
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Felix Moessbauer @ 2023-01-16  3:35 UTC (permalink / raw)
  To: isar-users
  Cc: jan.kiszka, daniel.bovensiepen, henning.schild, venkata.pyla,
	Felix Moessbauer

This patch changes how we derive the hashed password of a user that is
created using the clear-text-password flag. Previously, the clear-text
password was directly input into chpasswd. However, chpasswd internally
creates a 16-character random salt. This breaks the reproducability.

Instead of letting chpasswd create the hashed password string, we now
create it manually by deriving the salt from the SOURCE_DATE_EPOCH
variable. This is technically done using the host openssl tool. As
openssl is a transitive dependency of sbuild, we do not need to add
it explicitly to the host-tools.

In case SOURCE_DATE_EPOCH is not set, chpasswd is used
directly to create the salt.

Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
---
 meta/classes/image-account-extension.bbclass | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/meta/classes/image-account-extension.bbclass b/meta/classes/image-account-extension.bbclass
index 70950a7..cbc20a2 100644
--- a/meta/classes/image-account-extension.bbclass
+++ b/meta/classes/image-account-extension.bbclass
@@ -253,7 +253,15 @@ image_postprocess_accounts() {
         if [ -n "$password" -o "${flags}" != "${flags%*,allow-empty-password,*}" ]; then
             chpasswd_args="-e"
             if [ "${flags}" != "${flags%*,clear-text-password,*}" ]; then
-                chpasswd_args=""
+                # chpasswd adds a random salt when running against a clear-text password.
+                # For reproducible images, we manually generate the password and use the
+                # SOURCE_DATE_EPOCH to generate the salt in a deterministic way.
+                if [ -z "${SOURCE_DATE_EPOCH}" ]; then
+                    chpasswd_args=""
+                else
+                    salt="$(echo "${SOURCE_DATE_EPOCH}" | sha256sum -z | cut -c 1-15)"
+                    password="$(openssl passwd -6 -salt $salt "$password")"
+                fi
             fi
             printf '%s:%s' "$name" "$password" | sudo chroot '${ROOTFSDIR}' \
                 /usr/sbin/chpasswd $chpasswd_args
-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 06/10] update debian initramfs in deterministic mode
  2023-01-16  3:35 [PATCH v3 00/10] Make rootfs build reproducible Felix Moessbauer
                   ` (4 preceding siblings ...)
  2023-01-16  3:35 ` [PATCH v3 05/10] generate deterministic clear-text password hash Felix Moessbauer
@ 2023-01-16  3:35 ` Felix Moessbauer
  2023-01-16  3:35 ` [PATCH v3 07/10] create custom " Felix Moessbauer
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Felix Moessbauer @ 2023-01-16  3:35 UTC (permalink / raw)
  To: isar-users
  Cc: jan.kiszka, daniel.bovensiepen, henning.schild, venkata.pyla,
	Felix Moessbauer

This patch exports the SOURCE_DATE_EPOCH variable in the image install
task. By that, update-initramfs is switched into reproducible mode.
Before this patch, each trigger of update-initramfs created a new
non-deterministic version of the initramfs.

Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
---
 meta/classes/image.bbclass | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
index 6a3f99e..e59767e 100644
--- a/meta/classes/image.bbclass
+++ b/meta/classes/image.bbclass
@@ -304,6 +304,17 @@ python() {
 }
 
 
+# make generation of initramfs reproducible
+# note: this function is shared across multiple rootfs, but we only want to make the
+#       image rootfs reproducible. Otherwise changes of SOURCE_DATE_EPOCH would
+#       invalidate the SSTATE entries for most packages, even if they don't use the
+#       global SOURCE_DATE_EPOCH variable.
+rootfs_install_pkgs_install_prepend() {
+    if [ ! -z "${SOURCE_DATE_EPOCH}" ]; then
+        export SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH}"
+    fi
+}
+
 # here we call a command that should describe your whole build system,
 # this could be "git describe" or something similar.
 # set ISAR_RELEASE_CMD to customize, or override do_mark_rootfs to do something
-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 07/10] create custom initramfs in deterministic mode
  2023-01-16  3:35 [PATCH v3 00/10] Make rootfs build reproducible Felix Moessbauer
                   ` (5 preceding siblings ...)
  2023-01-16  3:35 ` [PATCH v3 06/10] update debian initramfs in deterministic mode Felix Moessbauer
@ 2023-01-16  3:35 ` Felix Moessbauer
  2023-01-16  3:35 ` [PATCH v3 08/10] make deb_add_changelog idempotent Felix Moessbauer
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Felix Moessbauer @ 2023-01-16  3:35 UTC (permalink / raw)
  To: isar-users
  Cc: jan.kiszka, daniel.bovensiepen, henning.schild, venkata.pyla,
	Felix Moessbauer

This patch enables the deterministic mode of update-initramfs for custom
initramfs versions, in case SOURCE_DATE_EPOCH is defined.

Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
---
 meta/classes/initramfs.bbclass | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/meta/classes/initramfs.bbclass b/meta/classes/initramfs.bbclass
index 2cec85d..db28334 100644
--- a/meta/classes/initramfs.bbclass
+++ b/meta/classes/initramfs.bbclass
@@ -32,6 +32,11 @@ do_generate_initramfs() {
     rootfs_do_mounts
     rootfs_do_qemu
 
+    # generate reproducible initrd if requested
+    if [ ! -z "${SOURCE_DATE_EPOCH}" ]; then
+        export SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH}"
+    fi
+
     sudo -E chroot "${INITRAMFS_ROOTFS}" \
         update-initramfs -u -v
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 08/10] make deb_add_changelog idempotent
  2023-01-16  3:35 [PATCH v3 00/10] Make rootfs build reproducible Felix Moessbauer
                   ` (6 preceding siblings ...)
  2023-01-16  3:35 ` [PATCH v3 07/10] create custom " Felix Moessbauer
@ 2023-01-16  3:35 ` Felix Moessbauer
  2023-01-16  3:35 ` [PATCH v3 09/10] deb_add_changelog: set timestamp to valid epoch Felix Moessbauer
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Felix Moessbauer @ 2023-01-16  3:35 UTC (permalink / raw)
  To: isar-users
  Cc: jan.kiszka, daniel.bovensiepen, henning.schild, venkata.pyla,
	Felix Moessbauer

Previously, the deb_add_changelog function considered an auto-generated
changelog as a base to add changes on top. This behavior is not
idempontent on subsequent invocations of the function (e.g. on partial
rebuilds). This lead to both reproducability issues, as well as unclean
changelog files having multiple "generated by ISAR" entries.

This patch changes this implementation in a way to always create a
(possibly empty) orig changelog on the first invocation. On subequent
invocations, the orig changelog is only considered as provided by the
user, if it is not empty.

Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
---
 meta/classes/debianize.bbclass | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/meta/classes/debianize.bbclass b/meta/classes/debianize.bbclass
index d125256..ca7b520 100644
--- a/meta/classes/debianize.bbclass
+++ b/meta/classes/debianize.bbclass
@@ -19,11 +19,14 @@ deb_add_changelog() {
 		if [ ! -f ${WORKDIR}/changelog.orig ]; then
 			cp ${S}/debian/changelog ${WORKDIR}/changelog.orig
 		fi
-		orig_version=$(dpkg-parsechangelog -l ${WORKDIR}/changelog.orig -S Version)
-		changelog_v=$(echo "${changelog_v}" | sed 's/<orig-version>/'${orig_version}'/')
-		orig_date=$(dpkg-parsechangelog -l ${WORKDIR}/changelog.orig -S Date)
-		orig_seconds=$(date --date="${orig_date}" +'%s')
-		timestamp=$(expr ${orig_seconds} + 42)
+		# we have a non auto-generated original changelog
+		if [ -s ${WORKDIR}/changelog.orig ]; then
+			orig_version=$(dpkg-parsechangelog -l ${WORKDIR}/changelog.orig -S Version)
+			changelog_v=$(echo "${changelog_v}" | sed 's/<orig-version>/'${orig_version}'/')
+			orig_date=$(dpkg-parsechangelog -l ${WORKDIR}/changelog.orig -S Date)
+			orig_seconds=$(date --date="${orig_date}" +'%s')
+			timestamp=$(expr ${orig_seconds} + 42)
+		fi
 	fi
 
 	date=$(LANG=C date -R -d @${timestamp})
@@ -34,7 +37,10 @@ ${PN} (${changelog_v}) UNRELEASED; urgency=low
 
  -- ${MAINTAINER}  ${date}
 EOF
-	if [ -f ${WORKDIR}/changelog.orig ]; then
+	# ensure that we always start with the orig version of the
+	# changelog on repeated invocations (e.g. on partial rebuilds)
+	touch ${WORKDIR}/changelog.orig
+	if [ -s ${WORKDIR}/changelog.orig ]; then
 		# prepend our entry to the original changelog
 		echo >> ${S}/debian/changelog
 		cat ${WORKDIR}/changelog.orig >> ${S}/debian/changelog
-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 09/10] deb_add_changelog: set timestamp to valid epoch
  2023-01-16  3:35 [PATCH v3 00/10] Make rootfs build reproducible Felix Moessbauer
                   ` (7 preceding siblings ...)
  2023-01-16  3:35 ` [PATCH v3 08/10] make deb_add_changelog idempotent Felix Moessbauer
@ 2023-01-16  3:35 ` Felix Moessbauer
  2023-01-16  3:35 ` [PATCH v3 10/10] make custom linux-image bit-by-bit reproducible Felix Moessbauer
  2023-01-25  7:16 ` [PATCH v3 00/10] Make rootfs build reproducible Uladzimir Bely
  10 siblings, 0 replies; 12+ messages in thread
From: Felix Moessbauer @ 2023-01-16  3:35 UTC (permalink / raw)
  To: isar-users
  Cc: jan.kiszka, daniel.bovensiepen, henning.schild, venkata.pyla,
	Felix Moessbauer

A changelog date of 0 (unix timestamp) is not considered a valid
timestamp for the SOURCE_DATE_EPOCH. By that, the debhelper scripts
set the SOURCE_DATE_EPOCH variable to the current time of the build,
breaking reproducability. By that, we get an inconsistency between the
debian changelog timestamp and the timestamp that the build tools encode
into the binary and the file timestamps.

Without having support to control the SOURCE_DATE_EPOCH variable
externally via bitbake, this always led to non-reproducible packages.
To fix this, we simply set the default timestamp to 1h later.

Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
---
 meta/classes/debianize.bbclass | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meta/classes/debianize.bbclass b/meta/classes/debianize.bbclass
index ca7b520..a6694a0 100644
--- a/meta/classes/debianize.bbclass
+++ b/meta/classes/debianize.bbclass
@@ -14,7 +14,7 @@ MAINTAINER ??= "Unknown maintainer <unknown@example.com>"
 
 deb_add_changelog() {
 	changelog_v="${CHANGELOG_V}"
-	timestamp=0
+	timestamp=3600
 	if [ -f ${S}/debian/changelog ]; then
 		if [ ! -f ${WORKDIR}/changelog.orig ]; then
 			cp ${S}/debian/changelog ${WORKDIR}/changelog.orig
-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 10/10] make custom linux-image bit-by-bit reproducible
  2023-01-16  3:35 [PATCH v3 00/10] Make rootfs build reproducible Felix Moessbauer
                   ` (8 preceding siblings ...)
  2023-01-16  3:35 ` [PATCH v3 09/10] deb_add_changelog: set timestamp to valid epoch Felix Moessbauer
@ 2023-01-16  3:35 ` Felix Moessbauer
  2023-01-25  7:16 ` [PATCH v3 00/10] Make rootfs build reproducible Uladzimir Bely
  10 siblings, 0 replies; 12+ messages in thread
From: Felix Moessbauer @ 2023-01-16  3:35 UTC (permalink / raw)
  To: isar-users
  Cc: jan.kiszka, daniel.bovensiepen, henning.schild, venkata.pyla,
	Felix Moessbauer

This patch makes the build of custom linux kernels bit-by-bit
reproducible. By that, we can remove the dh_strip_nondeterminism step,
which significantly reduces the kernel build time.

The implementation is similar to how upstream debian builds their kernel
images and extracts all information from the changelog. As the
DISTRIBUTOR field is not part of the changelog, we inject it via a bb
variable which is defaulted to ISAR.

Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
---
 .../linux/files/debian/isar/build.tmpl             |  1 +
 meta/recipes-kernel/linux/files/debian/rules.tmpl  | 14 +++++++++++++-
 meta/recipes-kernel/linux/linux-custom.inc         |  2 ++
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/meta/recipes-kernel/linux/files/debian/isar/build.tmpl b/meta/recipes-kernel/linux/files/debian/isar/build.tmpl
index 94cfbe0..e7e0479 100644
--- a/meta/recipes-kernel/linux/files/debian/isar/build.tmpl
+++ b/meta/recipes-kernel/linux/files/debian/isar/build.tmpl
@@ -34,6 +34,7 @@ print_settings() {
 # ---------------
 # ARCH=${ARCH}
 # CROSS_COMPILE=${CROSS_COMPILE}
+# KBUILD_BUILD_TIMESTAMP=${KBUILD_BUILD_TIMESTAMP}
 EOF
 }
 
diff --git a/meta/recipes-kernel/linux/files/debian/rules.tmpl b/meta/recipes-kernel/linux/files/debian/rules.tmpl
index 8063c49..e8ae3da 100755
--- a/meta/recipes-kernel/linux/files/debian/rules.tmpl
+++ b/meta/recipes-kernel/linux/files/debian/rules.tmpl
@@ -2,6 +2,11 @@
 
 CROSS_COMPILE:=$(DEB_HOST_GNU_TYPE)-
 
+MAINTAINER := $(shell sed -ne 's,^Maintainer: .[^<]*<\([^>]*\)>,\1,p' debian/control)
+DISTRIBUTOR := ${DISTRIBUTOR}
+SOURCE_DATE := $(shell dpkg-parsechangelog -SDate)
+SOURCE_DATE_UTC_ISO := $(shell date -u -d '$(SOURCE_DATE)' +%Y-%m-%d)
+
 O:=$(CURDIR)/${KERNEL_BUILD_DIR}
 S:=$(CURDIR)
 deb_top_dir:=$(S)/debian
@@ -14,7 +19,11 @@ isar_env=$(strip \
 	export MAKE='$(MAKE)' && \
 	export O='${O}' && \
 	export S='${S}' && \
-	export CURDIR='$(CURDIR)' \
+	export CURDIR='$(CURDIR)' && \
+	export KBUILD_BUILD_TIMESTAMP='$(SOURCE_DATE)' && \
+	export KBUILD_BUILD_VERSION_TIMESTAMP='$(DISTRIBUTOR) $(DEB_VERSION_UPSTREAM) ($(SOURCE_DATE_UTC_ISO))' && \
+	export KBUILD_BUILD_USER='$(word 1,$(subst @, ,$(MAINTAINER)))' && \
+	export KBUILD_BUILD_HOST='$(word 2,$(subst @, ,$(MAINTAINER)))' \
 )
 
 %:
@@ -35,5 +44,8 @@ override_dh_auto_install:
 override_dh_auto_test:
 	true
 
+override_dh_strip_nondeterminism:
+	true
+
 override_dh_strip:
 	unset DEB_HOST_GNU_TYPE && dh_strip -Xvmlinu --no-automatic-dbgsym
diff --git a/meta/recipes-kernel/linux/linux-custom.inc b/meta/recipes-kernel/linux/linux-custom.inc
index 447d4e8..6c539c0 100644
--- a/meta/recipes-kernel/linux/linux-custom.inc
+++ b/meta/recipes-kernel/linux/linux-custom.inc
@@ -12,6 +12,7 @@
 CHANGELOG_V = "${PV}+${PR}"
 DESCRIPTION ?= "Custom kernel"
 MAINTAINER ?= "isar-users <isar-users@googlegroups.com>"
+DISTRIBUTOR ?= "ISAR"
 
 KBUILD_DEPENDS ?= "build-essential:native, \
                    libelf-dev:native, \
@@ -79,6 +80,7 @@ TEMPLATE_VARS += "                \
     KERNEL_NAME_PROVIDED          \
     KERNEL_CONFIG_FRAGMENTS       \
     KCFLAGS                       \
+    DISTRIBUTOR                   \
 "
 
 inherit dpkg
-- 
2.34.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 00/10] Make rootfs build reproducible
  2023-01-16  3:35 [PATCH v3 00/10] Make rootfs build reproducible Felix Moessbauer
                   ` (9 preceding siblings ...)
  2023-01-16  3:35 ` [PATCH v3 10/10] make custom linux-image bit-by-bit reproducible Felix Moessbauer
@ 2023-01-25  7:16 ` Uladzimir Bely
  10 siblings, 0 replies; 12+ messages in thread
From: Uladzimir Bely @ 2023-01-25  7:16 UTC (permalink / raw)
  To: isar-users

In mail from понедельник, 16 января 2023 г. 06:35:42 +03 user Felix Moessbauer 
wrote:
> This series finally makes the rootfs generation bit-reproducible
> from debian bullseye on. Parts of it have already been sent
> as individual patches. However, image reproducibility can only
> be achived once all parts are reproducible itself. By that,
> these patches are included in this series as well.
> 
> With this series, the following parts are now fully reproducible.
> This has been tested on the isar-image-base target.
> 
> - custom initramfs (creation and updates)
> - debian initramfs (only updates are relevant)
> - custom kernel (debian kernel is reproducible itself)
> - rootfs itself
> - tar file generation (<image>.tar)
> - ext4 generation (only from bookworm on, more tests needed)
> 
> Other parts that are still not reproducible are:
> 
> - WIC (should be solved in OE already)
> - containers (untested yet)
> - SDK (note added in v3)
> 
> Changes since v2:
> 
> - fix issue issue when SOURCE_DATE_EPOCH is not defined
> - replaced "fix rebuild of rootfs_finalize task" with Hennings version
> - minor style fix in image-account-extension
> 
> Changes since v1:
> 
> - dropped patch "deb_add_changelog: use SOURCE_DATE_EPOCH"
> - fixed typo in "generate deterministic clear-text password hash"
> - added comment about why SOURCE_DATE_EPOCH must only be set for
>   image rootfs but not for other rootfs'.
> 
> Best regards,
> Felix Moessbauer
> Siemens AG
> 
> Felix Moessbauer (8):
>   rootfs postprocess: clean python cache
>   remove non-portable ldconfig aux-cache
>   generate deterministic clear-text password hash
>   update debian initramfs in deterministic mode
>   create custom initramfs in deterministic mode
>   make deb_add_changelog idempotent
>   deb_add_changelog: set timestamp to valid epoch
>   make custom linux-image bit-by-bit reproducible
> 
> Henning Schild (1):
>   image: make sure do_rootfs_finalize can run multiple times
> 
> venkata pyla (1):
>   image.bbclass: fix non-reproducible file time-stamps inside rootfs
> 
>  meta-isar/conf/local.conf.sample              | 10 +++++
>  meta/classes/debianize.bbclass                | 20 ++++++----
>  meta/classes/image-account-extension.bbclass  | 10 ++++-
>  meta/classes/image.bbclass                    | 39 +++++++++++++++----
>  meta/classes/initramfs.bbclass                |  5 +++
>  meta/classes/rootfs.bbclass                   | 13 +++++++
>  .../linux/files/debian/isar/build.tmpl        |  1 +
>  .../linux/files/debian/rules.tmpl             | 14 ++++++-
>  meta/recipes-kernel/linux/linux-custom.inc    |  2 +
>  9 files changed, 98 insertions(+), 16 deletions(-)

Applied to next, thanks.





^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2023-01-25  7:16 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-16  3:35 [PATCH v3 00/10] Make rootfs build reproducible Felix Moessbauer
2023-01-16  3:35 ` [PATCH v3 01/10] image: make sure do_rootfs_finalize can run multiple times Felix Moessbauer
2023-01-16  3:35 ` [PATCH v3 02/10] image.bbclass: fix non-reproducible file time-stamps inside rootfs Felix Moessbauer
2023-01-16  3:35 ` [PATCH v3 03/10] rootfs postprocess: clean python cache Felix Moessbauer
2023-01-16  3:35 ` [PATCH v3 04/10] remove non-portable ldconfig aux-cache Felix Moessbauer
2023-01-16  3:35 ` [PATCH v3 05/10] generate deterministic clear-text password hash Felix Moessbauer
2023-01-16  3:35 ` [PATCH v3 06/10] update debian initramfs in deterministic mode Felix Moessbauer
2023-01-16  3:35 ` [PATCH v3 07/10] create custom " Felix Moessbauer
2023-01-16  3:35 ` [PATCH v3 08/10] make deb_add_changelog idempotent Felix Moessbauer
2023-01-16  3:35 ` [PATCH v3 09/10] deb_add_changelog: set timestamp to valid epoch Felix Moessbauer
2023-01-16  3:35 ` [PATCH v3 10/10] make custom linux-image bit-by-bit reproducible Felix Moessbauer
2023-01-25  7:16 ` [PATCH v3 00/10] Make rootfs build reproducible Uladzimir Bely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox