Merge changes I75b828ae,I4baa5721,I68798300 into main

* changes:
  fix: pre-build-hook did not run when useChroot == false
  libstore/build: say what was failing when pre/post build hooks fail
  daemon: complain much louder about unknown std::exception instances falling out
This commit is contained in:
jade
2025-02-18 17:02:09 +00:00
committed by Gerrit Code Review
6 changed files with 81 additions and 7 deletions
+14 -2
View File
@@ -947,7 +947,8 @@ void runPostBuildHook(
PushActivity pact(act.id);
std::map<std::string, std::string> hookEnvironment = getEnv();
hookEnvironment.emplace("DRV_PATH", store.printStorePath(drvPath));
auto drvPathPretty = store.printStorePath(drvPath);
hookEnvironment.emplace("DRV_PATH", drvPathPretty);
hookEnvironment.emplace("OUT_PATHS", chomp(concatStringsSep(" ", store.printStorePathSet(outputPaths))));
hookEnvironment.emplace("NIX_CONFIG", globalConfig.toKeyValue());
@@ -987,7 +988,18 @@ void runPostBuildHook(
.captureStdout = true,
.mergeStderrToStdout = true,
});
Finally const _wait([&] { proc.wait(); });
Finally const _wait([&] {
try {
proc.wait();
} catch (nix::Error & e) {
e.addTrace(nullptr,
"while running the post-build-hook %s for derivation %s",
settings.postBuildHook,
drvPathPretty
);
throw;
}
});
// FIXME just process the data, without a wrapper sink class
proc.getStdout()->drainInto(sink);
+25 -4
View File
@@ -663,16 +663,37 @@ try {
if (needsHashRewrite() && pathExists(homeDir))
throw Error("home directory '%1%' exists; please remove it to assure purity of builds without sandboxing", homeDir);
if (useChroot && settings.preBuildHook != "" && dynamic_cast<Derivation *>(drv.get())) {
// Note that the derivation may or may not exist when running the
// pre-build-hook. In the past this was *supposed* to not run the
// hook in such cases, but at some intermediate point (since this->drv
// became always an instance of Derivation rather than BasicDerivation), it
// started being run in all cases on systems using the sandbox.
// https://git.lix.systems/lix-project/lix/commit/7f5b750b401e98e9e2a346552aba5bd2e0a9203f
//
// As such, we just run it every time. It might be reasonable (and more
// helpful behaviour for users) in the future to write out the derivation
// to disk if pre-build-hook is in use.
if (settings.preBuildHook != "") {
printMsg(lvlChatty, "executing pre-build hook '%1%'", settings.preBuildHook);
auto args = useChroot ? Strings({worker.store.printStorePath(drvPath), chrootRootDir}) :
Strings({ worker.store.printStorePath(drvPath) });
auto drvPathPretty = worker.store.printStorePath(drvPath);
auto args = useChroot ? Strings({ drvPathPretty, chrootRootDir}) :
Strings({ drvPathPretty });
enum BuildHookState {
stBegin,
stExtraChrootDirs
};
auto state = stBegin;
auto lines = runProgram(settings.preBuildHook, false, args);
std::string lines;
try {
runProgram(settings.preBuildHook, false, args);
} catch (nix::Error & e) {
e.addTrace(nullptr,
"while running pre-build-hook %s for derivation %s",
settings.preBuildHook,
drvPathPretty
);
throw;
}
auto lastPos = std::string::size_type{0};
for (auto nlPos = lines.find('\n'); nlPos != std::string::npos;
nlPos = lines.find('\n', lastPos))
+8 -1
View File
@@ -15,6 +15,7 @@
#include "lix/libutil/strings.hh"
#include "lix/libutil/args.hh"
#include <boost/core/demangle.hpp>
#include <sstream>
namespace nix::daemon {
@@ -1100,9 +1101,15 @@ void processConnection(
to.flush();
return;
} catch (std::exception & e) {
auto ex = Error(e.what());
auto ex = Error(
"Unexpected exception on the Lix daemon; this is a bug in Lix.\nWe would appreciate a report of the circumstances it happened in at https://git.lix.systems/lix-project/lix.\n%s: %s",
Uncolored(boost::core::demangle(typeid(e).name())),
e.what()
);
tunnelLogger->stopWork(&ex);
to.flush();
// Crash for good measure, so something winds up in system logs and a core dump is generated as well.
std::terminate();
return;
}
}
+2
View File
@@ -9,6 +9,8 @@ settings for this system. This is used for settings that can't be
captured by the derivation model itself and are too variable between
different versions of the same system to be hard-coded into nix.
At the time of running the hook, the derivation may or may not exist on disk (and, e.g. won't exist in the case of many remote builds).
The hook is passed the derivation path and, if sandboxes are
enabled, the sandbox directory. It can then modify the sandbox and
send a series of commands to modify various settings to stdout. The
+1
View File
@@ -163,6 +163,7 @@ functional_tests_scripts = [
'compression-levels.sh',
'nix-copy-ssh.sh',
'nix-copy-ssh-ng.sh',
'pre-hook.sh',
'post-hook.sh',
'function-trace.sh',
'flakes/config.sh',
+31
View File
@@ -0,0 +1,31 @@
source common.sh
clearStore
rm -f "$TEST_ROOT/result"
cat > "$TEST_ROOT/pre-hook.sh" <<-'EOF'
#!/bin/sh
# log the drvs that have been pre-hooked
echo "$1" >> "$(dirname "$0")"/drvs.txt
# sandbox: we have a sandbox path as second arg
if [[ $# == 2 ]]; then
# FIXME: verify this is actually present inside the derivation builder
# where sandbox is available.
echo extra-sandbox-paths
echo /foo=/bin/sh
echo
else
echo
fi
EOF
chmod +x "$TEST_ROOT/pre-hook.sh"
drvPath="$(nix eval --raw -f dependencies.nix drvPath)"
nix-store -r "$drvPath" --pre-build-hook "$TEST_ROOT/pre-hook.sh"
# We expect that the pre build hook got called on all the derivations in the closure we built
numDrvs="$(nix-store --query --requisites "$drvPath" | grep -c '\.drv$')"
[[ "$numDrvs" -gt 1 ]]
[[ "$numDrvs" == "$(< "$TEST_ROOT/drvs.txt" wc -l)" ]]