From bcab3d5da39685f0e50398978ced13b387766551 Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Sat, 7 Feb 2026 16:12:33 +0100 Subject: [PATCH] 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 --- lix/libstore/build/local-derivation-goal.cc | 18 ++++++++++++------ tests/functional2/build/test_ca.py | 10 +++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/lix/libstore/build/local-derivation-goal.cc b/lix/libstore/build/local-derivation-goal.cc index a7414fb1e..a31e50ca1 100644 --- a/lix/libstore/build/local-derivation-goal.cc +++ b/lix/libstore/build/local-derivation-goal.cc @@ -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 diff --git a/tests/functional2/build/test_ca.py b/tests/functional2/build/test_ca.py index cb1234676..b0162c4f9 100644 --- a/tests/functional2/build/test_ca.py +++ b/tests/functional2/build/test_ca.py @@ -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)