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

stdenv/generic/setup.sh: More robust unpacking #50961

Closed
wants to merge 1 commit into from

Conversation

woehr
Copy link
Contributor

@woehr woehr commented Nov 23, 2018

Motivation for this change

This commit makes it so the unpack phase can unpack tar files containing directories that do not have their execute bit set. This most commonly seems to happen to archives created on Windows. Two changes are required to make this work:

  1. The --delay-directory-restore flag needs to be set on the tar command, otherwise tar cannot enter newly created directories (that don't have their x bit set) and fails.
  2. After tar is run, directories need their execute bit set because tar restores the permissions once the extraction is complete.

The --mode flag of tar isn't used because that would affect every file instead of only directories. I'm not a tar expert, but the other flag that seems like it might help (--no-same-permissions), applies the user's umask, thus doesn't set the x bit.

I've rebuilt my entire NixOS system with this change successfully. Please let me know what other testing is required and I'll be happy to run it.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • 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 nox --run "nox-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)
  • Assured whether relevant documentation is up to date
  • Fits CONTRIBUTING.md.

…es that do not have their execute bit set.
@GrahamcOfBorg GrahamcOfBorg added the 6.topic: stdenv Standard environment label Nov 23, 2018
@grahamc
Copy link
Member

grahamc commented Nov 23, 2018

@GrahamcOfBorg eval

@matthewbauer
Copy link
Member

Just for reference, here is a discussion on --delay-directory-restore from Fedora:

https://bugzilla.redhat.com/show_bug.cgi?id=1206020

@woehr
Copy link
Contributor Author

woehr commented Nov 26, 2018

Just to summarise what I've learned from the previous comment and further perusal of the man pages.

  1. --delay-directory-restore may cause high memory usage for large tarbals (many files/directories, not physical size) because the meta-data of all files is retained in memory so the restore can happen once unpacking complete.

  2. The default behaviour of tar is good enough to work for a lot of files, but not all, particularly when directories in the archive are read-only or don't have their execute bit set (on a related note, this PR may resolve issue fetchzip doesn't like tarballs containing read-only directories #15527, but I haven't tried it).

    • By default tar assumes the files in an archive are ordered, and can therefore restore directory metadata once all the contents of a directory have been unpacked. In this case, tar will succeed even when directories are read-only. However, the chmod +x on directories is still required, otherwise the "make sources writable" step of the unpack phase will fail.

    • The second case is when files in an archive are not ordered; for example, a directory is unpacked, it's metadata restored, then tar encounters another file later in the archive belonging to the previous directory. In this case, --delay-directory-restore is required to delay permission restoration so the latter file can be added. Without the delayed restore, tar fails.

  3. As far as I can tell, tar does not provide a means of modifying the contents of an archive before unpacking. This answer (https://unix.stackexchange.com/a/125487) provides a couple of suggestions. Mounting the archive as a filesystem is one way to modify permissions before unpacking. Presumably that incurs a lot of overhead, especially if a compressed archive is modified.

For reference, the same issue isaacs/node-tar#7

@woehr
Copy link
Contributor Author

woehr commented Dec 21, 2018

@Ericson2314 @matthewbauer @infinisil Any feedback on this change? I've been bit by this edge case and I think it'd be great if nixpkgs could handle these types of broken tar files.

@veprbl
Copy link
Member

veprbl commented Dec 23, 2018

@woehr It appears that the --delay-directory-restore option exists there because that mode should not be the default. Yet this PR makes it enabled by default and unconditionally. Even if it fixes your issue, it will invite breakage for someone else (perhaps somebody working with large tarballs). I don't think anybody wants that. So have you considered options that don't require modifying stdenv? In your derivation you could set TAR_OPTIONS = "--delay-directory-restore";. If that doesn't work, one could always make a derivation to wrap around fetchurl to implement a custom tar unpacker or have this logic put in overridden unpackPhase of your derivation.

@Mic92 Mic92 closed this Dec 23, 2018
@veprbl
Copy link
Member

veprbl commented Dec 24, 2018

@Mic92 Closed by accident?

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.

None yet

6 participants