libstore/build: set impure environment variables only if they are set

To stop spurious warnings, we will stop this bizarre behavior of setting
empty values to impure environment variables.

On the warning side, we verify that the presence of the environment
variable.

The corresponding test is updated to "there is a warning" to "there is
no warning".

Change-Id: I12f5c6445ef00a83d269488d7aed0b0f61aeec12
This commit is contained in:
Raito Bezarius
2026-02-26 15:33:22 +00:00
parent 72a6d5ff48
commit bcab3d5da3
2 changed files with 17 additions and 11 deletions
+12 -6
View File
@@ -1134,18 +1134,20 @@ void LocalDerivationGoal::setupConfiguredCertificateAuthority()
* set. */
auto impureVars = parsedDrv->getStringsAttr("impureEnvVars").value_or(Strings());
if (std::find(impureVars.begin(), impureVars.end(), "NIX_SSL_CERT_FILE") != impureVars.end()
&& env["NIX_SSL_CERT_FILE"] != settings.caFile)
&& env.contains("NIX_SSL_CERT_FILE") && env["NIX_SSL_CERT_FILE"] != settings.caFile)
{
printTaggedWarning(
"'NIX_SSL_CERT_FILE' is an impure environment variable of this "
"'NIX_SSL_CERT_FILE' is an impure environment variable (set to '%s') of this "
"derivation but a *DIFFERENT* `ssl-cert-file` was set in the settings "
"which takes precedence.\n"
"(set to '%s') which takes precedence.\n"
"If you use `ssl-cert-file`, the certificate gets copied in the builder "
"environment and the environment variables are set automatically.\n"
"If you set this environment variable to be an impure environment "
"variable, you need to ensure it is accessible to the sandbox via "
"`extra-sandbox-paths`.\n"
"This warning may become a hard error in the future version of Lix."
"This warning may become a hard error in the future version of Lix.",
env["NIX_SSL_CERT_FILE"],
settings.caFile
);
}
@@ -1216,8 +1218,12 @@ void LocalDerivationGoal::initEnv()
fixed-output derivations is by definition pure (since we
already know the cryptographic hash of the output). */
if (!derivationType->isSandboxed()) {
for (auto & i : parsedDrv->getStringsAttr("impureEnvVars").value_or(Strings()))
env[i] = getEnv(i).value_or("");
for (auto & i : parsedDrv->getStringsAttr("impureEnvVars").value_or(Strings())) {
auto value = getEnv(i);
if (value) {
env[i] = *value;
}
}
}
/* Currently structured log messages piggyback on stderr, but we
+5 -5
View File
@@ -136,15 +136,15 @@ class TestCertClobberingInFODs:
nix, "clobbering-impurities", sandboxed=sandboxed
).outcomes == ({"present", "present-env-var"} if sandboxed else {"present-env-var"})
def test_warning_presence(self, nix: Nix, sandboxed: bool):
def test_warning_absence(self, nix: Nix, sandboxed: bool):
warning_prefix = "'NIX_SSL_CERT_FILE' is an impure environment variable"
# Under impureEnvVars set, Lix will always make `NIX_SSL_CERT_FILE` exist in the environment
# of the builder with an empty value.
# This should cause the warning to be trigger because `"" != "/nowhere"`.
# Under impureEnvVars set, Lix will set `NIX_SSL_CERT_FILE` only if it existed in the environment
# of the builder.
# This should cause the warning to be absent.
nix.env.unset_env("NIX_SSL_CERT_FILE")
assessment = assess_cert_presence_in_builds(
nix, "clobbering-impurities", cert="cert", sandboxed=sandboxed
)
assert any(w.startswith(warning_prefix) for w in assessment.warnings)
assert not any(w.startswith(warning_prefix) for w in assessment.warnings)