Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gnutar: make reproducible by default #107251

Open
wants to merge 2 commits into
base: staging
Choose a base branch
from

Conversation

prusnak
Copy link
Member

@prusnak prusnak commented Dec 20, 2020

Motivation for this change

Fixes #106643

  1. by introducing wrapper which adds extra tar flags when GNUTAR_REPRODUCIBLE is set:
  • sort by name by default
  • set mtime to SOURCE_DATE_EPOCH
  • set owner/group to 0
  1. by setting GNUTAR_REPRODUCIBLE =1 in genericBuild() of pkgs/stdenv/generic/setup.sh
Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@stale
Copy link

stale bot commented Jul 20, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jul 20, 2021
@prusnak
Copy link
Member Author

prusnak commented Jul 20, 2021

Still relevant.

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jul 20, 2021
@stale
Copy link

stale bot commented Apr 19, 2022

I marked this as stale due to inactivity. → More info

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Apr 19, 2022
@raboof
Copy link
Member

raboof commented May 15, 2022

@prusnak you marked this as 'Draft' in december 2020 - why? Is there anything you'd like to do before we start reviewing this? Would you like help?

@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label May 15, 2022
@prusnak prusnak marked this pull request as ready for review May 15, 2022 12:37
@prusnak
Copy link
Member Author

prusnak commented May 15, 2022

@raboof No. I just wanted to gather more feedback before someone accidentally merges this. Since there was no feedback, I am marking this as ready.

@prusnak prusnak force-pushed the gnutar-repro-hook branch 2 times, most recently from b43561d to a3ad038 Compare May 15, 2022 12:44
Copy link
Member

@raboof raboof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested with nix-shell -p gnutar that the expected environment variable is set and behaves as expected:

$ tar -c -f foo.tar foo.txt
$ tar -v --list -f ./foo.tar
tar: Option --mtime: Treating date '@315532800' as 1980-01-01 01:00:00
-rw-r--r-- 0/0               0 1980-01-01 01:00 foo.txt

That 01:00 was suspicious to me: 315532800 is 1:00am in my timezone, so this is correct only assuming tar takes into account the current timezone when listing (not creating) the archive. I checked, and this is luckily the case: I switched timezones and the printed timestamp 'changed along' with it. So all good AFAICS 👍

pkgs/tools/archivers/gnutar/default.nix Outdated Show resolved Hide resolved
@xaverdh
Copy link
Contributor

xaverdh commented May 15, 2022

I think the issue with this that was mentioned by @FRidh, is that we still do not have nix shell as officially supported cli, but only nix-shell. This pr will make all users of nix-shell see this behaviour from tar, even those that just wanted a tar executable for their own use?

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jan 8, 2023
@prusnak
Copy link
Member Author

prusnak commented Mar 5, 2023

Anyone wants to take over this PR and rewrite it the way #209371 + #211948 are done?

@drupol
Copy link
Contributor

drupol commented Oct 20, 2023

@prusnak Any feedback on this?

@Artturin
Copy link
Member

Artturin commented Oct 20, 2023

$ tar --mtime="1" --owner=0 --group=0 --numeric-owner --sort=name xf
tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
Try 'tar --help' or 'tar --usage' for more information.
$ tar xf --mtime="1" --owner=0 --group=0 --numeric-owner --sort=name
tar: --mtime=1: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now
$ tar xf blah --mtime="1" --owner=0 --group=0 --numeric-owner --sort=name
tar: blah: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now
$ tar --mtime="1" --owner=0 --group=0 --numeric-owner --sort=name xf blah
tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
Try 'tar --help' or 'tar --usage' for more information.

tar seems to be very picky about it's arguments

Switched it to use --append-flags

if -xf was used then it could be at any point but we can't control all uses of tar

@Artturin Artturin force-pushed the gnutar-repro-hook branch 2 times, most recently from 12ea7ea to 8f31dc5 Compare October 20, 2023 20:23
@Artturin
Copy link
Member

Artturin commented Oct 23, 2023

err from nix tests

ran test tests/tarball.sh... [FAIL]
    +++(/build/source/tests/common/vars-and-functions.sh:274) trap onError ERR
    ++(common.sh:8) [[ -n '' ]]
    +(tarball.sh:3) clearStore
    +(/build/source/tests/common/vars-and-functions.sh:74) echo 'clearing store...'
    clearing store...
    +(/build/source/tests/common/vars-and-functions.sh:75) chmod -R +w /build/nix-test/tests/tarball/store
    +(/build/source/tests/common/vars-and-functions.sh:76) rm -rf /build/nix-test/tests/tarball/store
    +(/build/source/tests/common/vars-and-functions.sh:77) mkdir /build/nix-test/tests/tarball/store
    +(/build/source/tests/common/vars-and-functions.sh:78) rm -rf /build/nix-test/tests/tarball/var/nix
    +(/build/source/tests/common/vars-and-functions.sh:79) mkdir /build/nix-test/tests/tarball/var/nix
    +(/build/source/tests/common/vars-and-functions.sh:80) clearProfiles
    +(/build/source/tests/common/vars-and-functions.sh:69) profiles=/build/nix-test/tests/tarball/test-home/.local/state/nix/profiles
    +(/build/source/tests/common/vars-and-functions.sh:70) rm -rf /build/nix-test/tests/tarball/test-home/.local/state/nix/profiles
    +(tarball.sh:5) rm -rf /build/nix-test/tests/tarball/test-home
    +(tarball.sh:7) tarroot=/build/nix-test/tests/tarball/tarball
    +(tarball.sh:8) rm -rf /build/nix-test/tests/tarball/tarball
    +(tarball.sh:9) mkdir -p /build/nix-test/tests/tarball/tarball
    +(tarball.sh:10) cp dependencies.nix /build/nix-test/tests/tarball/tarball/default.nix
    +(tarball.sh:11) cp config.nix dependencies.builder0.sh /build/nix-test/tests/tarball/tarball/
    +(tarball.sh:12) touch -d @1000000000 /build/nix-test/tests/tarball/tarball /build/nix-test/tests/tarball/tarball/config.nix /build/nix-test/tests/tarball/tarball/default.nix /build/nix-test/tests/tarball/tarball/dependencies.builder0.sh
    ++(tarball.sh:14) nix hash path /build/nix-test/tests/tarball/tarball
    warning: you don't have Internet access; disabling some network-dependent features
    +(tarball.sh:14) hash=sha256-zts680B4zdz/FcIC8nqXF6PmdshWUguYowsFKN0MydM=
    +(tarball.sh:57) test_tarball '' cat
    +(tarball.sh:17) local ext=
    +(tarball.sh:18) local compressor=cat
    +(tarball.sh:20) tarball=/build/nix-test/tests/tarball/tarball.tar
    +(tarball.sh:21) cd /build/nix-test/tests/tarball
    +(tarball.sh:21) tar cf - tarball
    +(tarball.sh:21) cat
    +(tarball.sh:23) nix-env -f file:///build/nix-test/tests/tarball/tarball.tar -qa --out-path
    +(tarball.sh:23) grepQuiet dependencies
    +(/build/source/tests/common/vars-and-functions.sh:266) grep dependencies
    +(tarball.sh:25) nix-build -o /build/nix-test/tests/tarball/result file:///build/nix-test/tests/tarball/tarball.tar
    these 5 derivations will be built:
      /build/nix-test/tests/tarball/store/0jni3i6ggyk6v3wh4sxs35n8frdlb3gj-dependencies-input-0.drv
      /build/nix-test/tests/tarball/store/9miqaqdpf1n4y7r5nc51f6d9vy2hivjk-dependencies-input-2.drv
      /build/nix-test/tests/tarball/store/hdqdzcdkwyfmaqw4pg01srm5my2asvly-fod-input.drv
      /build/nix-test/tests/tarball/store/zmrcfv242amjn4fskhjc0i497dcg45k4-dependencies-input-1.drv
      /build/nix-test/tests/tarball/store/a5yizcr8d1i6g0mlkcwp3j2r33xchnp4-dependencies-top.drv
    building '/build/nix-test/tests/tarball/store/0jni3i6ggyk6v3wh4sxs35n8frdlb3gj-dependencies-input-0.drv'...
    building '/build/nix-test/tests/tarball/store/zmrcfv242amjn4fskhjc0i497dcg45k4-dependencies-input-1.drv'...
    building '/build/nix-test/tests/tarball/store/9miqaqdpf1n4y7r5nc51f6d9vy2hivjk-dependencies-input-2.drv'...
    building '/build/nix-test/tests/tarball/store/hdqdzcdkwyfmaqw4pg01srm5my2asvly-fod-input.drv'...
    
    building '/build/nix-test/tests/tarball/store/a5yizcr8d1i6g0mlkcwp3j2r33xchnp4-dependencies-top.drv'...
    FOO
    /build/nix-test/tests/tarball/store/j6zxi4kfh87y05pqmr4v12gjxp66bqcb-dependencies-top
    +(tarball.sh:27) nix-build -o /build/nix-test/tests/tarball/result '<foo>' -I foo=file:///build/nix-test/tests/tarball/tarball.tar
    /build/nix-test/tests/tarball/store/j6zxi4kfh87y05pqmr4v12gjxp66bqcb-dependencies-top
    +(tarball.sh:29) nix-build -o /build/nix-test/tests/tarball/result -E 'import (fetchTarball file:///build/nix-test/tests/tarball/tarball.tar)'
    /build/nix-test/tests/tarball/store/j6zxi4kfh87y05pqmr4v12gjxp66bqcb-dependencies-top
    +(tarball.sh:31) nix-build -o /build/nix-test/tests/tarball/result -E 'import (fetchTarball { url = file:///does-not-exist/must-remain-unused//build/nix-test/tests/tarball/tarball.tar; sha256 = "sha256-zts680B4zdz/FcIC8nqXF6PmdshWUguYowsFKN0MydM="; })'
    /build/nix-test/tests/tarball/store/j6zxi4kfh87y05pqmr4v12gjxp66bqcb-dependencies-top
    +(tarball.sh:33) nix-build -o /build/nix-test/tests/tarball/result -E 'import (fetchTree file:///build/nix-test/tests/tarball/tarball.tar)'
    /build/nix-test/tests/tarball/store/j6zxi4kfh87y05pqmr4v12gjxp66bqcb-dependencies-top
    +(tarball.sh:34) nix-build -o /build/nix-test/tests/tarball/result -E 'import (fetchTree { type = "tarball"; url = file:///build/nix-test/tests/tarball/tarball.tar; })'
    /build/nix-test/tests/tarball/store/j6zxi4kfh87y05pqmr4v12gjxp66bqcb-dependencies-top
    +(tarball.sh:35) nix-build -o /build/nix-test/tests/tarball/result -E 'import (fetchTree { type = "tarball"; url = file:///build/nix-test/tests/tarball/tarball.tar; narHash = "sha256-zts680B4zdz/FcIC8nqXF6PmdshWUguYowsFKN0MydM="; })'
    /build/nix-test/tests/tarball/store/j6zxi4kfh87y05pqmr4v12gjxp66bqcb-dependencies-top
    +(tarball.sh:37) nix-build -o /build/nix-test/tests/tarball/result -E 'import (fetchTree { type = "tarball"; url = file:///does-not-exist/must-remain-unused//build/nix-test/tests/tarball/tarball.tar; narHash = "sha256-zts680B4zdz/FcIC8nqXF6PmdshWUguYowsFKN0MydM="; })'
    /build/nix-test/tests/tarball/store/j6zxi4kfh87y05pqmr4v12gjxp66bqcb-dependencies-top
    +(tarball.sh:38) expectStderr 102 nix-build -o /build/nix-test/tests/tarball/result -E 'import (fetchTree { type = "tarball"; url = file:///build/nix-test/tests/tarball/tarball.tar; narHash = "sha256-xdKv2pq/IiwLSnBBJXW8hNowI4MrdZfW+SYqDQs7Tzc="; })'
    +(/build/source/tests/common/vars-and-functions.sh:207) local expected res
    +(/build/source/tests/common/vars-and-functions.sh:208) expected=102
    +(/build/source/tests/common/vars-and-functions.sh:209) shift
    +(/build/source/tests/common/vars-and-functions.sh:210) nix-build -o /build/nix-test/tests/tarball/result -E 'import (fetchTree { type = "tarball"; url = file:///build/nix-test/tests/tarball/tarball.tar; narHash = "sha256-xdKv2pq/IiwLSnBBJXW8hNowI4MrdZfW+SYqDQs7Tzc="; })'
    +(tarball.sh:38) grep 'NAR hash mismatch in input'
    +(/build/source/tests/common/vars-and-functions.sh:210) res=102
    +(/build/source/tests/common/vars-and-functions.sh:211) [[ 102 -ne 102 ]]
    +(/build/source/tests/common/vars-and-functions.sh:215) return 0
           error: NAR hash mismatch in input 'file:///build/nix-test/tests/tarball/tarball.tar?narHash=sha256-xdKv2pq/IiwLSnBBJXW8hNowI4MrdZfW%2BSYqDQs7Tzc%3D' (/build/nix-test/tests/tarball/store/w5lmk41jdgih3ag0fm4sbgdgsswgxpz1-source), expected 'sha256-xdKv2pq/IiwLSnBBJXW8hNowI4MrdZfW+SYqDQs7Tzc=', got 'sha256-zts680B4zdz/FcIC8nqXF6PmdshWUguYowsFKN0MydM='
    ++(tarball.sh:40) nix eval --impure --expr '(fetchTree file:///build/nix-test/tests/tarball/tarball.tar).lastModified'
    warning: you don't have Internet access; disabling some network-dependent features
    +(tarball.sh:40) [[ 1689663323 = 1000000000 ]]
make: *** [mk/lib.mk:125: tests/tarball.sh.test] Error 1
make: *** Waiting for unfinished jobs....

adding the reproducible flags and updating the narHash should fix it https://github.com/NixOS/nix/blob/c7c5d370e0f07cbc985323f30cd99e0bf913f323/tests/functional/tarball.sh#L21

@iFreilicht
Copy link
Contributor

iFreilicht commented Oct 27, 2023

Tested and confirmed to work if PR in nix is merged, see NixOS/nix#9225 (review)

@drupol
Copy link
Contributor

drupol commented Nov 6, 2023

@GrahamcOfBorg eval

@RaitoBezarius
Copy link
Member

@drupol can I let you adopt this PR?

@prusnak
Copy link
Member Author

prusnak commented Jan 12, 2024

@prusnak Any feedback on this?

No comments, LGTM 👍

@drupol
Copy link
Contributor

drupol commented Jan 12, 2024

@RaitoBezarius I wish I could help on this, but I really don't know how to fix the remaining issues.

@RaitoBezarius
Copy link
Member

@prusnak could I bother you with a rebase for this PR? I will try to see it to the finish line.

@prusnak
Copy link
Member Author

prusnak commented Jan 12, 2024

@prusnak could I bother you with a rebase for this PR? I will try to see it to the finish line.

Done. Rebased on top of current staging.

@drupol drupol force-pushed the gnutar-repro-hook branch 3 times, most recently from 95ae68a to b4a89d0 Compare January 12, 2024 20:47
@drupol
Copy link
Contributor

drupol commented Jan 12, 2024

I pushed an extra commit to refactor the file and switch to finalAttrs pattern. Let me know if you prefer to do it in a follow-up PR or it is fine to keep it here.

pkgs/tools/archivers/gnutar/default.nix Outdated Show resolved Hide resolved
pkgs/tools/archivers/gnutar/default.nix Outdated Show resolved Hide resolved
@drupol drupol force-pushed the gnutar-repro-hook branch 2 times, most recently from 08a0de7 to b5cf705 Compare January 12, 2024 21:23
@prusnak
Copy link
Member Author

prusnak commented Jan 12, 2024

I restructured the PR to contain two commits:

  • af1d3d3 containing the minimal change required to achieve reproducibility (goal of this PR)
  • 1a574f9 containing cosmetic refactors by @drupol

@prusnak
Copy link
Member Author

prusnak commented Jan 12, 2024

I did it in the meantime, based on @RaitoBezarius 's feedback on Matrix.

No, you don't understand. I took your changes and restructured them. Basically I took some of your cosmetic changes you did to my first commit and moved them to your second commit.

@drupol
Copy link
Contributor

drupol commented Jan 12, 2024

Yep, sorry I've been too hasty for replying :)
All good for me now.

@drupol
Copy link
Contributor

drupol commented Jan 13, 2024

I'm trying to fix the issue locally.

The issue is with autoconf-archive (nix build .#autoconf-archive -L).

When using makeWrapper in place of makeBinaryWrapper, the issue is:

gnutar> shrinking RPATHs of ELF executables and libraries in /nix/store/zk773yn6dww40qqgba17m0kp46s82a5d-gnutar-1.35
gnutar> shrinking /nix/store/zk773yn6dww40qqgba17m0kp46s82a5d-gnutar-1.35/bin/.tar-wrapped
gnutar> shrinking /nix/store/zk773yn6dww40qqgba17m0kp46s82a5d-gnutar-1.35/libexec/rmt
gnutar> checking for references to /build/ in /nix/store/zk773yn6dww40qqgba17m0kp46s82a5d-gnutar-1.35...
gnutar> gzipping man pages under /nix/store/zk773yn6dww40qqgba17m0kp46s82a5d-gnutar-1.35/share/man/
gnutar> stripping (with command strip and flags -S -p) in  /nix/store/zk773yn6dww40qqgba17m0kp46s82a5d-gnutar-1.35/libexec /nix/store/zk773yn6dww40qqgba17m0kp46s82a5d-gnutar-1.35/bin
gnutar> shrinking RPATHs of ELF executables and libraries in /nix/store/z7sscamigcy0znb0dajzmaq1q1gc9ayp-gnutar-1.35-info
gnutar> checking for references to /build/ in /nix/store/z7sscamigcy0znb0dajzmaq1q1gc9ayp-gnutar-1.35-info...
autoconf-archive> Running phase: unpackPhase
autoconf-archive> unpacking source archive /nix/store/pq4bmqcrz01fmb601qkmfk49454dv5m9-autoconf-archive-2023.02.20.tar.xz
autoconf-archive> /nix/store/zk773yn6dww40qqgba17m0kp46s82a5d-gnutar-1.35/bin/tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
autoconf-archive> Try '/nix/store/zk773yn6dww40qqgba17m0kp46s82a5d-gnutar-1.35/bin/tar --help' or
autoconf-archive> '/nix/store/zk773yn6dww40qqgba17m0kp46s82a5d-gnutar-1.35/bin/tar --usage' for
autoconf-archive> more information.
autoconf-archive> do not know how to unpack source archive /nix/store/pq4bmqcrz01fmb601qkmfk49454dv5m9-autoconf-archive-2023.02.20.tar.xz
error: builder for '/nix/store/jajnmfz72h271v866hzrm52sy8bhlxmx-autoconf-archive-2023.02.20.drv' failed with exit code 1;
       last 7 log lines:
       > Running phase: unpackPhase
       > unpacking source archive /nix/store/pq4bmqcrz01fmb601qkmfk49454dv5m9-autoconf-archive-2023.02.20.tar.xz
       > /nix/store/zk773yn6dww40qqgba17m0kp46s82a5d-gnutar-1.35/bin/tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
       > Try '/nix/store/zk773yn6dww40qqgba17m0kp46s82a5d-gnutar-1.35/bin/tar --help' or
       > '/nix/store/zk773yn6dww40qqgba17m0kp46s82a5d-gnutar-1.35/bin/tar --usage' for
       > more information.
       > do not know how to unpack source archive /nix/store/pq4bmqcrz01fmb601qkmfk49454dv5m9-autoconf-archive-2023.02.20.tar.xz
       For full logs, run 'nix log /nix/store/jajnmfz72h271v866hzrm52sy8bhlxmx-autoconf-archive-2023.02.20.drv'.
~/C/N/nixpkgs > gnutar-repro-hook +3 -2 [!] ✘

For some reason, there's an issue with the GNUTAR_REPRODUCIBLE environment variable. If anyone has a clue, let me know.

@drupol
Copy link
Contributor

drupol commented Jan 16, 2024

I made further investigations.

Currently, in this PR, there's an issue when doing the following:

$ nix build .#gnutar
$ ./result/bin/tar --help
./result/bin/tar: invalid option -- '$'
Try 'tar --help' or 'tar --usage' for more information.

When replacing makeBinaryWrapper with makeWrapper, the issue is gone, however, there's still an issue to build autoconf-archive, here are some debugging infos:

autoconf-archive> ++ declare -F _defaultUnpack
autoconf-archive> ++ _defaultUnpack /nix/store/pq4bmqcrz01fmb601qkmfk49454dv5m9-autoconf-archive-2023.02.20.tar.xz
autoconf-archive> ++ local fn=/nix/store/pq4bmqcrz01fmb601qkmfk49454dv5m9-autoconf-archive-2023.02.20.tar.xz
autoconf-archive> ++ local destination
autoconf-archive> ++ '[' -d /nix/store/pq4bmqcrz01fmb601qkmfk49454dv5m9-autoconf-archive-2023.02.20.tar.xz ']'
autoconf-archive> ++ case "$fn" in
autoconf-archive> ++ XZ_OPT=--threads=8
autoconf-archive> ++ xz -d
autoconf-archive> ++ tar xf - --warning=no-timestamp
autoconf-archive> /nix/store/45dz1pdhrp17gha35va4fvg3hksyhnw5-gnutar-1.35/bin/tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
autoconf-archive> Try '/nix/store/45dz1pdhrp17gha35va4fvg3hksyhnw5-gnutar-1.35/bin/tar --help' or
autoconf-archive> '/nix/store/45dz1pdhrp17gha35va4fvg3hksyhnw5-gnutar-1.35/bin/tar --usage' for
autoconf-archive> more information.
autoconf-archive> ++ return 1
autoconf-archive> ++ echo 'do not know how to unpack source archive /nix/store/pq4bmqcrz01fmb601qkmfk49454dv5m9-autoconf-archive-2023.02.20.tar.xz'
autoconf-archive> do not know how to unpack source archive /nix/store/pq4bmqcrz01fmb601qkmfk49454dv5m9-autoconf-archive-2023.02.20.tar.xz
autoconf-archive> ++ exit 1
autoconf-archive> + exitHandler
autoconf-archive> + exitCode=1

(The decompressing part is done in https://github.com/NixOS/nixpkgs/blame/b5cf705fc77b75f762ce1cb3c5391e5f373e34fa/pkgs/stdenv/generic/setup.sh#L1051)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

gnutar: reproducible by default?
10 participants