Package: python3-distro-info Version: 1.9 Severity: wishlist Tags: patch User: reproducible-bui...@lists.alioth.debian.org Usertags: timestamps Control: affects -1 developers-reference
Dear Maintainer, I'm an occasional volunteer contributor to the Reproducible Builds[1] project, and recently noticed that the developers-reference package failed to build deterministically on the test build infrastructure for Debian. The difference in the build output appears in Debian release codenames retrieved using the distro_info module in the python3-distro-info package. In particular, varying system clock times during comparative builds can cause the release codenames returned by distro-info to differ, due to date-based filtering logic that uses datetime.date.today (system clock date) as a default value. Please find attached a patch to begin using the stable SOURCE_DATE_EPOCH[3] build timestamp, when configured, as a source of the default date filter, enabling repeatable and deterministic build output. (I'll also offer this as a merge request on Salsa) Regards, James [1] - https://reproducible-builds.org [2] - https://sources.debian.org/src/distro-info/1.9/python/distro_info.py/#L129 [3] - https://reproducible-builds.org/docs/source-date-epoch/
>From 2807fa377f4192c2bc5d3e384e3e7ec4a9c018ea Mon Sep 17 00:00:00 2001 From: James Addison <j...@jp-hosting.net> Date: Mon, 14 Oct 2024 21:10:32 +0100 Subject: [PATCH] python: add release filtering by SOURCE_DATE_EPOCH --- python/distro_info.py | 6 +++++- python/distro_info_test/test_distro_info.py | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/python/distro_info.py b/python/distro_info.py index 34f1299..5822580 100644 --- a/python/distro_info.py +++ b/python/distro_info.py @@ -124,7 +124,11 @@ class DistroInfo: _get_date(row, "eol-server"), ) self._releases.append(release) - self._date = datetime.date.today() + source_date_epoch = os.environ.get("SOURCE_DATE_EPOCH") + if source_date_epoch is not None: + self._date = datetime.date.fromtimestamp(int(source_date_epoch)) + else: + self._date = datetime.date.today() @property def all(self) -> list[str]: diff --git a/python/distro_info_test/test_distro_info.py b/python/distro_info_test/test_distro_info.py index b9e1cc1..d2d1fd1 100644 --- a/python/distro_info_test/test_distro_info.py +++ b/python/distro_info_test/test_distro_info.py @@ -18,6 +18,7 @@ import datetime import unittest +from unittest.mock import patch from distro_info import DebianDistroInfo, UbuntuDistroInfo @@ -91,6 +92,14 @@ class DebianDistroInfoTestCase(unittest.TestCase): # pylint: disable=too-many-p unsupported = ["buzz", "rex", "bo", "hamm", "slink", "potato", "woody", "sarge", "etch"] self.assertEqual(self._distro_info.unsupported(self._date), unsupported) + @patch.dict("os.environ", {"SOURCE_DATE_EPOCH": "1500000000"}) + def test_date_filtering(self) -> None: + """Test: filter supported Debian releases based on build date""" + supported = ['jessie', 'stretch', 'buster', 'sid', 'experimental'] + + distro_info = DebianDistroInfo() + self.assertEqual(distro_info.supported(), supported) + def test_codename(self) -> None: """Test: Codename decoding""" self.assertIsNone(self._distro_info.codename("foobar")) @@ -171,6 +180,14 @@ class UbuntuDistroInfoTestCase(unittest.TestCase): # pylint: disable=too-many-p unsupported = ["warty", "hoary", "breezy", "edgy", "feisty", "gutsy", "intrepid", "jaunty"] self.assertEqual(self._distro_info.unsupported(self._date), unsupported) + @patch.dict("os.environ", {"SOURCE_DATE_EPOCH": "1500000000"}) + def test_date_filtering(self) -> None: + """Test: filter supported Ubuntu releases based on build date""" + supported = ['trusty', 'xenial', 'yakkety', 'zesty', 'artful'] + + distro_info = UbuntuDistroInfo() + self.assertEqual(distro_info.supported(), supported) + def test_current_unsupported(self) -> None: """Test: List all unsupported Ubuntu distributions today.""" unsupported = {"warty", "hoary", "breezy", "edgy", "feisty", "gutsy", "intrepid", "jaunty"} -- 2.45.2