-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
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
buildEnv: break with a proper error if one path is actually a file #55372
buildEnv: break with a proper error if one path is actually a file #55372
Conversation
45d5183
to
1161e44
Compare
I noticed by creating `buildEnv` where I accidentally put a derivation from `pkgs.writeText` into `paths` and got a broken build with the following misleading error message: ``` Use of uninitialized value $stat1 in numeric ne (!=) at /nix/store/9g4wc31j7a2xp22xpgwr0qssfxahxdzl-builder.pl line 74. Use of uninitialized value $stat1 in bitwise and (&) at /nix/store/9g4wc31j7a2xp22xpgwr0qssfxahxdzl-builder.pl line 75. different permissions in `' and `/nix/store/0vy5ss91laxvwkyvrbld5hv27i88qk5w-noise': 0000 <-> 0444 at /nix/store/9g4wc31j7a2xp22xpgwr0qssfxahxdzl-builder.pl line 75. ``` It can be reproduced with an expression like this: ``` nix { pkgs ? import <nixpkgs> { } }: let file = pkgs.writeText "test" '' content ''; in pkgs.buildEnv { name = "test-env"; paths = [ /* ... */ file ]; } ```
1161e44
to
40f8546
Compare
@@ -84,6 +84,10 @@ sub checkCollision { | |||
sub findFiles { | |||
my ($relName, $target, $baseName, $ignoreCollisions, $checkCollisionContents, $priority) = @_; | |||
|
|||
if (-f $target) { | |||
die "Path $target is a file and can't be merged into an environment using pkgs.buildEnv!"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...but should it not be possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd say it shouldn't. If I understand the code right it never worked properly and merging a file with a directory feels wrong.
if you want to have a store path which contains the file from writeText
, you may want to use writeTextDir
instead.
are there any further concerns? :) |
BTW, does anyone know if the buildenv used by |
I see
I'm not sure if there are more; Hydra will show in time. |
Hmm... I'll take a look into this... |
@vcunat I'm currently investigating what's happening here. I'll hope that I can report back this afternoon. If this isn't fast enough, feel free to revert 😅 |
Today seems certainly fast enough for staging. |
I just had a look at the It seems as if a file is passed to diff --git a/pkgs/build-support/buildenv/builder.pl b/pkgs/build-support/buildenv/builder.pl
index 1f77edf86cb..98442216fcd 100755
--- a/pkgs/build-support/buildenv/builder.pl
+++ b/pkgs/build-support/buildenv/builder.pl
@@ -84,10 +84,6 @@ sub checkCollision {
sub findFiles {
my ($relName, $target, $baseName, $ignoreCollisions, $checkCollisionContents, $priority) = @_;
- if (-f $target) {
- die "Path $target is a file and can't be merged into an environment using pkgs.buildEnv!";
- }
-
# Urgh, hacky...
return if
$relName eq "/propagated-build-inputs" ||
@@ -107,6 +103,12 @@ sub findFiles {
return;
}
+ # If target is a file and the old target is defined and empty it means that a store
+ # path represented by $target is a file and can't be merged into the environment.
+ if (-f $target && defined $oldTarget && $oldTarget eq "") {
+ die "Path $target is a file and can't be merged into an environment using pkgs.buildEnv!";
+ }
+
# If target already exists as a symlink to a file (not a
# directory) in a higher-priority package, skip.
if (defined $oldTarget && $priority > $oldPriority && $oldTarget ne "" && ! -d $oldTarget) { If this seems fine for you @vcunat, I'd file a new patch :) |
The original change in NixOS#55372 was supposed to fix the case where a store path which is a file should be placed into `buildEnv` which broke with a fairly misleading Perl error. Unfortunately this introduced a regression, `findFiles` can have targets that are files if the file isn't a store path. Rather than adding more obscure checks with probably further regressions, I figured that it's better to replicate the behavior of `lib.isStorePath` and explicitly check if the store path is a file and break in this case only. This should also fix recent staging issues.
The original change in #55372 was supposed to fix the case where a store path which is a file should be placed into `buildEnv` which broke with a fairly misleading Perl error. Unfortunately this introduced a regression, `findFiles` can have targets that are files if the file isn't a store path. Rather than adding more obscure checks with probably further regressions, I figured that it's better to replicate the behavior of `lib.isStorePath` and explicitly check if the store path is a file and break in this case only. This should also fix recent staging issues.
Motivation for this change
I noticed by creating
buildEnv
where I accidentally put a derivationfrom
pkgs.writeText
intopaths
and got a broken build with thefollowing misleading error message:
It can be reproduced with an expression like this:
Things done
sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)nix path-info -S
before and after)