Diff of the two buildlogs: -- --- b1/build.log 2025-11-19 12:43:50.742923391 +0000 +++ b2/build.log 2025-11-19 12:44:35.114972704 +0000 @@ -1,6 +1,6 @@ I: pbuilder: network access will be disabled during build -I: Current time: Wed Nov 19 00:36:29 -12 2025 -I: pbuilder-time-stamp: 1763555789 +I: Current time: Wed Dec 23 09:06:53 +14 2026 +I: pbuilder-time-stamp: 1797966413 I: Building the build Environment I: extracting base tarball [/var/cache/pbuilder/unstable-reproducible-base.tgz] I: copying local configuration @@ -22,53 +22,85 @@ dpkg-source: info: unpacking ctdopts_1.5-6.debian.tar.xz I: using fakeroot in build. I: Installing the build-deps -I: user script /srv/workspace/pbuilder/387269/tmp/hooks/D02_print_environment starting +I: user script /srv/workspace/pbuilder/3052675/tmp/hooks/D01_modify_environment starting +debug: Running on codethink03-arm64. +I: Changing host+domainname to test build reproducibility +I: Adding a custom variable just for the fun of it... +I: Changing /bin/sh to bash +'/bin/sh' -> '/bin/bash' +lrwxrwxrwx 1 root root 9 Dec 22 19:07 /bin/sh -> /bin/bash +I: Setting pbuilder2's login shell to /bin/bash +I: Setting pbuilder2's GECOS to second user,second room,second work-phone,second home-phone,second other +I: user script /srv/workspace/pbuilder/3052675/tmp/hooks/D01_modify_environment finished +I: user script /srv/workspace/pbuilder/3052675/tmp/hooks/D02_print_environment starting I: set - BUILDDIR='/build/reproducible-path' - BUILDUSERGECOS='first user,first room,first work-phone,first home-phone,first other' - BUILDUSERNAME='pbuilder1' - BUILD_ARCH='arm64' - DEBIAN_FRONTEND='noninteractive' - DEB_BUILD_OPTIONS='buildinfo=+all reproducible=+all parallel=12 ' - DISTRIBUTION='unstable' - HOME='/root' - HOST_ARCH='arm64' + BASH=/bin/sh + BASHOPTS=checkwinsize:cmdhist:complete_fullquote:extquote:force_fignore:globasciiranges:globskipdots:hostcomplete:interactive_comments:patsub_replacement:progcomp:promptvars:sourcepath + BASH_ALIASES=() + BASH_ARGC=() + BASH_ARGV=() + BASH_CMDS=() + BASH_LINENO=([0]="12" [1]="0") + BASH_LOADABLES_PATH=/usr/local/lib/bash:/usr/lib/bash:/opt/local/lib/bash:/usr/pkg/lib/bash:/opt/pkg/lib/bash:. + BASH_SOURCE=([0]="/tmp/hooks/D02_print_environment" [1]="/tmp/hooks/D02_print_environment") + BASH_VERSINFO=([0]="5" [1]="3" [2]="3" [3]="1" [4]="release" [5]="aarch64-unknown-linux-gnu") + BASH_VERSION='5.3.3(1)-release' + BUILDDIR=/build/reproducible-path + BUILDUSERGECOS='second user,second room,second work-phone,second home-phone,second other' + BUILDUSERNAME=pbuilder2 + BUILD_ARCH=arm64 + DEBIAN_FRONTEND=noninteractive + DEB_BUILD_OPTIONS='buildinfo=+all reproducible=+all parallel=12 nocheck' + DIRSTACK=() + DISTRIBUTION=unstable + EUID=0 + FUNCNAME=([0]="Echo" [1]="main") + GROUPS=() + HOME=/root + HOSTNAME=i-capture-the-hostname + HOSTTYPE=aarch64 + HOST_ARCH=arm64 IFS=' ' - INVOCATION_ID='472e4304c7504feba61cc935bed44433' - LANG='C' - LANGUAGE='en_US:en' - LC_ALL='C' - MAIL='/var/mail/root' - OPTIND='1' - PATH='/usr/sbin:/usr/bin:/sbin:/bin:/usr/games' - PBCURRENTCOMMANDLINEOPERATION='build' - PBUILDER_OPERATION='build' - PBUILDER_PKGDATADIR='/usr/share/pbuilder' - PBUILDER_PKGLIBDIR='/usr/lib/pbuilder' - PBUILDER_SYSCONFDIR='/etc' - PPID='387269' - PS1='# ' - PS2='> ' + INVOCATION_ID=e7000054bcd4496188fed9d42b19bd76 + LANG=C + LANGUAGE=nl_BE:nl + LC_ALL=C + MACHTYPE=aarch64-unknown-linux-gnu + MAIL=/var/mail/root + OPTERR=1 + OPTIND=1 + OSTYPE=linux-gnu + PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path + PBCURRENTCOMMANDLINEOPERATION=build + PBUILDER_OPERATION=build + PBUILDER_PKGDATADIR=/usr/share/pbuilder + PBUILDER_PKGLIBDIR=/usr/lib/pbuilder + PBUILDER_SYSCONFDIR=/etc + PIPESTATUS=([0]="0") + POSIXLY_CORRECT=y + PPID=3052675 PS4='+ ' - PWD='/' - SHELL='/bin/bash' - SHLVL='2' - SUDO_COMMAND='/usr/bin/timeout -k 18.1h 18h /usr/bin/ionice -c 3 /usr/bin/nice /usr/sbin/pbuilder --build --configfile /srv/reproducible-results/rbuild-debian/r-b-build.dfVX4LpB/pbuilderrc_xvMo --distribution unstable --hookdir /etc/pbuilder/first-build-hooks --debbuildopts -b --basetgz /var/cache/pbuilder/unstable-reproducible-base.tgz --buildresult /srv/reproducible-results/rbuild-debian/r-b-build.dfVX4LpB/b1 --logfile b1/build.log ctdopts_1.5-6.dsc' - SUDO_GID='109' - SUDO_HOME='/var/lib/jenkins' - SUDO_UID='104' - SUDO_USER='jenkins' - TERM='unknown' - TZ='/usr/share/zoneinfo/Etc/GMT+12' - USER='root' - _='/usr/bin/systemd-run' - http_proxy='http://192.168.101.4:3128' + PWD=/ + SHELL=/bin/bash + SHELLOPTS=braceexpand:errexit:hashall:interactive-comments:posix + SHLVL=3 + SUDO_COMMAND='/usr/bin/timeout -k 24.1h 24h /usr/bin/ionice -c 3 /usr/bin/nice -n 11 /usr/bin/unshare --uts -- /usr/sbin/pbuilder --build --configfile /srv/reproducible-results/rbuild-debian/r-b-build.dfVX4LpB/pbuilderrc_sVEB --distribution unstable --hookdir /etc/pbuilder/rebuild-hooks --debbuildopts -b --basetgz /var/cache/pbuilder/unstable-reproducible-base.tgz --buildresult /srv/reproducible-results/rbuild-debian/r-b-build.dfVX4LpB/b2 --logfile b2/build.log ctdopts_1.5-6.dsc' + SUDO_GID=109 + SUDO_HOME=/var/lib/jenkins + SUDO_UID=104 + SUDO_USER=jenkins + TERM=unknown + TZ=/usr/share/zoneinfo/Etc/GMT-14 + UID=0 + USER=root + _='I: set' + http_proxy=http://192.168.101.4:3128 I: uname -a - Linux codethink04-arm64 6.12.57+deb13-cloud-arm64 #1 SMP Debian 6.12.57-1 (2025-11-05) aarch64 GNU/Linux + Linux i-capture-the-hostname 6.12.57+deb13-cloud-arm64 #1 SMP Debian 6.12.57-1 (2025-11-05) aarch64 GNU/Linux I: ls -l /bin - lrwxrwxrwx 1 root root 7 Aug 10 12:30 /bin -> usr/bin -I: user script /srv/workspace/pbuilder/387269/tmp/hooks/D02_print_environment finished + lrwxrwxrwx 1 root root 7 Aug 10 2025 /bin -> usr/bin +I: user script /srv/workspace/pbuilder/3052675/tmp/hooks/D02_print_environment finished -> Attempting to satisfy build-dependencies -> Creating pbuilder-satisfydepends-dummy package Package: pbuilder-satisfydepends-dummy @@ -165,7 +197,7 @@ Get: 53 http://deb.debian.org/debian unstable/main arm64 python3-zipp all 3.23.0-1 [11.0 kB] Get: 54 http://deb.debian.org/debian unstable/main arm64 python3-setuptools all 78.1.1-0.1 [738 kB] Get: 55 http://deb.debian.org/debian unstable/main arm64 python3-jaraco.context all 6.0.1-1 [8276 B] -Fetched 18.7 MB in 1s (25.9 MB/s) +Fetched 18.7 MB in 0s (139 MB/s) Preconfiguring packages ... Selecting previously unselected package libexpat1:arm64. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 19968 files and directories currently installed.) @@ -358,8 +390,8 @@ Setting up tzdata (2025b-5) ... Current default time zone: 'Etc/UTC' -Local time is now: Wed Nov 19 12:43:10 UTC 2025. -Universal Time is now: Wed Nov 19 12:43:10 UTC 2025. +Local time is now: Tue Dec 22 19:07:12 UTC 2026. +Universal Time is now: Tue Dec 22 19:07:12 UTC 2026. Run 'dpkg-reconfigure tzdata' if you wish to change it. Setting up autotools-dev (20240727.1) ... @@ -418,7 +450,11 @@ Solving dependencies... 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. I: Building the package -I: Running cd /build/reproducible-path/ctdopts-1.5/ && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" HOME="/nonexistent/first-build" dpkg-buildpackage -us -uc -b && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games" HOME="/nonexistent/first-build" dpkg-genchanges -S > ../ctdopts_1.5-6_source.changes +I: user script /srv/workspace/pbuilder/3052675/tmp/hooks/A99_set_merged_usr starting +Not re-configuring usrmerge for unstable +I: user script /srv/workspace/pbuilder/3052675/tmp/hooks/A99_set_merged_usr finished +hostname: Name or service not known +I: Running cd /build/reproducible-path/ctdopts-1.5/ && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path" HOME="/nonexistent/second-build" dpkg-buildpackage -us -uc -b && env PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/i/capture/the/path" HOME="/nonexistent/second-build" dpkg-genchanges -S > ../ctdopts_1.5-6_source.changes dpkg-buildpackage: info: source package ctdopts dpkg-buildpackage: info: source version 1.5-6 dpkg-buildpackage: info: source distribution unstable @@ -447,127 +483,6 @@ # not for every Python version sed 's#^print$#print()#' example.py > debian/example.py make[1]: Leaving directory '/build/reproducible-path/ctdopts-1.5' - debian/rules override_dh_auto_test -make[1]: Entering directory '/build/reproducible-path/ctdopts-1.5' -export PYBUILD_SYSTEM=custom; dh_auto_test -I: pybuild base:311: PYTHONPATH=/build/reproducible-path/ctdopts-1.5/.pybuild/cpython3_3.13_CTDopts/build python3.13 debian/example.py -/build/reproducible-path/ctdopts-1.5/.pybuild/cpython3_3.13_CTDopts/build/CTDopts/CTDopts.py:1071: UserWarning: Argument restrictions for positive_int violated. Restriction: 0:. Value: -5 - warnings.warn('Argument restrictions for %s violated. Restriction: %s. Value: %s' % -/build/reproducible-path/ctdopts-1.5/.pybuild/cpython3_3.13_CTDopts/build/CTDopts/CTDopts.py:1071: UserWarning: Argument restrictions for output violated. Restriction: *.fastq,*.fastq.gz. Value: - warnings.warn('Argument restrictions for %s violated. Restriction: %s. Value: %s' % -Model being written to exampleTool.ctd... - -Model loaded from exampleTool.ctd... - -For debugging purposes we can output a human readable representation of Parameter objects. Here's the first one: -PARAMETER positive_int - type: int - default: 5 - tags: advanced, magic - restrictions on numeric range: 0 to None - description: A positive integer parameter - -The following parameters were registered in the model: -['positive_int', 'input_files', 'output', 'this_that', 'param_1', 'param_2', 'param_3'] - -The same parameters with subgroup information, if they were registered under parameter groups: -['positive_int', 'input_files', 'output', 'this_that', 'subparams:param_1', 'subparams:param_2', 'subparams:subsubparam:param_3'] - -A dictionary of parameters with default values, returned by CTDModel.get_defaults(): -{ 'positive_int': 5, - 'subparams': { 'param_1': 5.5, - 'param_2': [0.0, 2.5, 5.0], - 'subsubparam': {'param_3': 2}}, - 'this_that': 'this'} - -As you can see, parameter values are usually stored in nested dictionaries. If you want a flat dictionary, you canget that using CTDopts.flatten_dict(). Flat keys can be either tuples of tree node (subgroup) names down to the parameter... -{ ('positive_int',): 5, - ('subparams', 'param_1'): 5.5, - ('subparams', 'param_2'): [0.0, 2.5, 5.0], - ('subparams', 'subsubparam', 'param_3'): 2, - ('this_that',): 'this'} - -...or they can be strings where nesing levels are separated by colons: -{ 'positive_int': 5, - 'subparams:param_1': 5.5, - 'subparams:param_2': [0.0, 2.5, 5.0], - 'subparams:subsubparam:param_3': 2, - 'this_that': 'this'} - -We can create dictionaries of arguments on our own that we want to validate against the model.CTDopts can read them from argument-storing CTD files or from the command line, but we can just define them in a nested dictionary on our own as well. We start with defining them explicitly. -{ 'input_files': ['file1.fastq', 'file2.fastq', 'file3.fastq'], - 'positive_int': 111, - 'subparams': {'param_1': '999.0'}} - -We can validate these arguments against the model, and get a dictionary with parameter types correctly casted and defaults set. Note that subparams:param_1 was casted from string to a floating point number because that's how it was defined in the model. -{ 'input_files': ['file1.fastq', 'file2.fastq', 'file3.fastq'], - 'positive_int': 111, - 'subparams': { 'param_1': 999.0, - 'param_2': [0.0, 2.5, 5.0], - 'subsubparam': {'param_3': 2}}, - 'this_that': 'this'} - -We can write a CTD file containing these validated argument values. Just call CTDModel.write_ctd() with an extra parameter: the nested argument dictionary containing the actual values. - -As mentioned earlier, CTDopts can load argument values from CTD files. Feel free to change some values in exampleTool_preset_params.ctd you've just written, and load it back. -{ 'input_files': ['file1.fastq', 'file2.fastq', 'file3.fastq'], - 'output': '', - 'positive_int': '111', - 'subparams': { 'param_1': '999.0', - 'param_2': ['0.0', '2.5', '5.0'], - 'subsubparam': {'param_3': '2'}}, - 'this_that': 'this'} - -Notice that all the argument values are strings now. This is because we didn't validate them against the model, just loaded some stuff from a file into a dictionary. If you want to cast them, call CTDModel.validate_args(): -{ 'input_files': ['file1.fastq', 'file2.fastq', 'file3.fastq'], - 'output': '', - 'positive_int': 111, - 'subparams': { 'param_1': 999.0, - 'param_2': [0.0, 2.5, 5.0], - 'subsubparam': {'param_3': 2}}, - 'this_that': 'this'} - -Now certain parameters may have restrictions that we might want to validate for as well. Let's set the parameter positive_int to a negative value, and try to validate it with a strictness level enforce_restrictions=1. This will register a warning, but still accept the value. - -Validation enforcement levels can be 0, 1 or 2 for type-casting, restriction-checking and required argument presence. They can be set with the keywords enforce_type, enforce_restrictions and enforce_required respectively. Let's increase strictness for restriction checking. CTDModel.validate_args() will now raise an exception that we'll catch: - -Argument restrictions for positive_int failed. Restriction: 0:. Value: -5 - -One might want to combine arguments loaded from a CTD file with arguments coming from elsewhere, like the command line.In that case, the method CTDopts.override_args(*arg_dicts) creates a combined argument dictionary where argument values are always taken from the rightmost (last) dictionary that has them. Let's override a few parameters: -{ 'input_files': ['file1.fastq', 'file2.fastq', 'file3.fastq'], - 'positive_int': 777, - 'subparams': { 'param_1': 999.0, - 'param_2': [0.0, 2.5, 5.0], - 'subsubparam': {'param_3': 2}}, - 'this_that': 'that'} - -So how to deal with command line arguments? If we have a model, we can look for its arguments. Call CTDModel.parse_cl_args() with either a string of the command line call or a list with the split words. By default, it will assume a '--' prefix before parameter names, but it can be overridden with prefix='-'.Grouped parameters are expected in --group:subgroup:param_x format. -{ 'input_files': ['a.fastq', 'b.fastq'], - 'output': 'out_dir/', - 'positive_int': '44', - 'subparams': { 'param_1': 5.5, - 'param_2': ['5.0', '5.5', '6.0'], - 'subsubparam': {'param_3': 2}}, - 'this_that': 'this'} - -Override other parameters with them, and validate it against the model: -{ 'input_files': ['a.fastq', 'b.fastq'], - 'output': 'out_dir/', - 'positive_int': 44, - 'subparams': { 'param_1': 5.5, - 'param_2': [5.0, 5.5, 6.0], - 'subsubparam': {'param_3': 2}}, - 'this_that': 'this'} - -One last thing: certain command line directives that are specific to CTD functionality can be parsed for, to help your script performing common tasks. These are CTD argument input, CTD model file writing and CTD argument file writing. CTDopts.parse_cl_directives() can also be customized as to what directives to look for if the defaults --input_ctd, --write_tool_ctd and --write_param_ctd respectively don't satisfy you. -{ 'input_ctd': 'exampleTool_preset_params.ctd', - 'write_param_ctd': 'new_preset_params.ctd', - 'write_tool_ctd': None} -{ 'input_ctd': 'exampleTool_preset_params_2.ctd', - 'write_param_ctd': None, - 'write_tool_ctd': True} -Finally, writing CTDs with logging information, passing a dictionarywith a 'log' keyword, using any or all of the fields shown below. -make[1]: Leaving directory '/build/reproducible-path/ctdopts-1.5' create-stamp debian/debhelper-build-stamp dh_testroot -O--buildsystem=pybuild dh_prep -O--buildsystem=pybuild @@ -610,12 +525,14 @@ dpkg-buildpackage: info: binary-only upload (no source included) dpkg-genchanges: info: not including original source code in upload I: copying local configuration +I: user script /srv/workspace/pbuilder/3052675/tmp/hooks/B01_cleanup starting +I: user script /srv/workspace/pbuilder/3052675/tmp/hooks/B01_cleanup finished I: unmounting dev/ptmx filesystem I: unmounting dev/pts filesystem I: unmounting dev/shm filesystem I: unmounting proc filesystem I: unmounting sys filesystem I: cleaning the build env -I: removing directory /srv/workspace/pbuilder/387269 and its subdirectories -I: Current time: Wed Nov 19 00:43:49 -12 2025 -I: pbuilder-time-stamp: 1763556229 +I: removing directory /srv/workspace/pbuilder/3052675 and its subdirectories +I: Current time: Wed Dec 23 09:07:34 +14 2026 +I: pbuilder-time-stamp: 1797966454