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-setup: fix substituteAll with set -eu #28799

Merged
merged 3 commits into from
Sep 3, 2017

Conversation

orivej
Copy link
Contributor

@orivej orivej commented Aug 31, 2017

Motivation for this change

Environment variable filter in substituteAll was not precise and produced undefined and invalid variable names. Vladimír Čunát tried to fix that in [1], but env -0 did not work during Darwin bootstrap, so [2] reverted this change and replaced an error due to invalid variables with a warning. Recently in #28057 John Ericson added set -u to setup.sh and undefined variables made the setup fail during e.g. nix-build -A gnat with setup: line 519: !varName: unbound variable.

This patch fixes the cause of such warnings as [3]:

 WARNING: substitution variables should be valid bash names,
   "ccLDFlags+" isn't and therefore was skipped; it might be caused
   by multi-line phases in variables - see #14907 for details.

[1] 62fc885
[2] 81df035
[3] #14907 (comment)

Things done

Tested building some packages (e.g. nix) on NixOS and Darwin.

  • Tested using sandboxing
    (nix.useSandbox on NixOS,
    or option build-use-sandbox in nix.conf
    on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • Linux
  • 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/)
  • Fits CONTRIBUTING.md.

@orivej orivej requested a review from Ericson2314 as a code owner August 31, 2017 17:42
@mention-bot
Copy link

@orivej, thanks for your PR! By analyzing the history of the files in this pull request, we identified @Ericson2314, @vcunat and @domenkozar to be potential reviewers.

@orivej orivej force-pushed the stdenv-setup branch 2 times, most recently from d0704a8 to bd51c02 Compare August 31, 2017 17:54
@dezgeg
Copy link
Contributor

dezgeg commented Aug 31, 2017

Ugh, overriding a builtin feels dirty. Does env -0 work on Darwin? That should allow safe parsing even if the variable values contain newlines.

@orivej
Copy link
Contributor Author

orivej commented Aug 31, 2017

This is what 9e0d042 and [1] above tried to do, but env on Darwin does not understand -0.

@dezgeg
Copy link
Contributor

dezgeg commented Aug 31, 2017

How about awk 'BEGIN { for (v in ENVIRON) print v }' then?

I checked gawk is in Darwin bootstrap tools and ENVIRON is POSIX even (for stdenvNative).

@orivej
Copy link
Contributor Author

orivej commented Aug 31, 2017

Good idea!

@copumpkin
Copy link
Member

env -0 works fine on Darwin inside most Nix contexts, because we just use the standard Nix tooling (coreutils, bash) in any pure context. The only place to be worried is the occasional script that runs under /bin/sh, where we can no longer control the PATH and bash being used.

@orivej
Copy link
Contributor Author

orivej commented Aug 31, 2017

@copumpkin setup.sh is needed on Darwin before any bash or env from nixpkgs is available. See 81df035.

@orivej
Copy link
Contributor Author

orivej commented Aug 31, 2017

@dezgeg

overriding a builtin feels dirty

Actually, overriding builtins with functions is well defined:

 2. If the name does not match a function, the shell searches for it in the list of shell builtins.

https://www.gnu.org/software/bash/manual/html_node/Command-Search-and-Execution.html

Nevertheless, I'm going to continue with awk for now.

Could someone test this on hydra? I have successfully built some packages on Linux and Darwin with this pull request, but I don't know how to test properly without hydra.

@copumpkin
Copy link
Member

@orivej are you sure that's still true? I thought that was only true because nix-shell used the host bash, but now that we force it to use the Nix bash (and maybe coreutils?) we might be safer. If not, can we just force setup.sh to incorporate a fixed version of coreutils?

@orivej
Copy link
Contributor Author

orivej commented Aug 31, 2017

@copumpkin You are right, since 2bc7b4e Darwin always uses Bash from nixpkgs for setup.sh. However, over programs from bootstrap-tools (including env and awk) are not in PATH during early stages (when the shell is ${bootstrapTools}/bin/bash), e.g. env or awk 'BEGIN {}' at the beginning of setup.sh will cause failure, so it is not quite safe to use them at the moment… Currently bootstrap succeeds because early stages do not call substituteAll

@Ericson2314
Copy link
Member

err in nix-shell, the impure bash will be used---I've certainly learned that! If any dependency has a setup hook or similar using substitute, it will be run when the nix-shell is entered.

Copy link
Member

@Ericson2314 Ericson2314 left a comment

Choose a reason for hiding this comment

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

With or without awk seems fine to me. Thanks for fixing!

@@ -497,10 +497,8 @@ substitute() {
shift 2
# check if the used nix attribute name is a valid bash name
if ! [[ "$varName" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]]; then
echo "${FUNCNAME[0]}(): WARNING: substitution variables should be valid bash names," >&2
Copy link
Member

Choose a reason for hiding this comment

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

You could just hardcode substitute(): too. That is what was there before, IIRC.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not familiar with FUNCNAME. Why did you use it 5d693c8?

Copy link
Member

Choose a reason for hiding this comment

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

No great reason, just in-case the code was moved elsewhere / general principle of things not knowing their own name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you want to replace ${FUNCNAME[0]} with substitute, I can do this in this pull request.

Copy link
Member

Choose a reason for hiding this comment

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

I don't care which, I'd just like to have something saying what the function is.

Copy link
Member

Choose a reason for hiding this comment

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

(I'll merge it after that.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I did not get that you asked for the function name here too. Done.

echo " \"$varName\" isn't and therefore was skipped; it might be caused" >&2
echo " by multi-line phases in variables - see #14907 for details." >&2
continue
echo "substitution variables must be valid Bash names, \"$varName\" isn't."
Copy link
Member

Choose a reason for hiding this comment

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

The >&2 should also still be there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, didn't notice that.

@orivej orivej force-pushed the stdenv-setup branch 2 times, most recently from f2cd568 to 16761a3 Compare September 1, 2017 09:59
@Ericson2314 Ericson2314 added this to the 17.09 milestone Sep 1, 2017
@Ericson2314 Ericson2314 added the 9.needs: port to stable A PR needs a backport to the stable release. label Sep 1, 2017
Environment variable filter in substituteAll was not precise and produced
undefined and invalid variable names.  Vladimír Čunát tried to fix that in [1],
but `env -0` did not work during Darwin bootstrap, so [2] reverted this change
and replaced an error due to invalid variables with a warning.  Recently in NixOS#28057
John Ericson added `set -u` to `setup.sh` and undefined variables made the setup
fail during e.g. `nix-build -A gnat` with `setup: line 519: !varName: unbound
variable`.

[1] NixOS@62fc885
[2] NixOS@81df035
@Ericson2314 Ericson2314 merged commit b891d75 into NixOS:staging Sep 3, 2017
@Ericson2314
Copy link
Member

Thanks @orivej!

@orivej orivej deleted the stdenv-setup branch September 3, 2017 14:46
@Ericson2314 Ericson2314 added the 8.has: port to stable A PR already has a backport to the stable release. label Sep 3, 2017
@samueldr samueldr removed the 9.needs: port to stable A PR needs a backport to the stable release. label Apr 17, 2019
@orivej orivej mentioned this pull request Oct 20, 2021
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
8.has: port to stable A PR already has a backport to the stable release.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants