aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2022-06-22 22:43:53 +0200
committerEelco Dolstra <edolstra@gmail.com>2022-06-23 01:32:46 +0200
commitd3176ce076407ef3e63667c0436bccf8be317ae4 (patch)
tree8dcaaab834d6afa14948239e6e6c864ba025e8e6 /src
parent3c48c4b4f7a8d5a7b045b9dbee1310d20ca7750b (diff)
Fix build-remote in nix-static
'build-remote' is now executed via /proc/self/exe so it always works.
Diffstat (limited to 'src')
-rw-r--r--src/libstore/build/hook-instance.cc25
-rw-r--r--src/libstore/globals.cc5
-rw-r--r--src/libstore/globals.hh2
-rw-r--r--src/libutil/util.cc14
-rw-r--r--src/libutil/util.hh6
-rw-r--r--src/nix/main.cc5
-rw-r--r--src/nix/run.cc2
7 files changed, 47 insertions, 12 deletions
diff --git a/src/libstore/build/hook-instance.cc b/src/libstore/build/hook-instance.cc
index 0f6f580be..1f19ddccc 100644
--- a/src/libstore/build/hook-instance.cc
+++ b/src/libstore/build/hook-instance.cc
@@ -7,6 +7,22 @@ HookInstance::HookInstance()
{
debug("starting build hook '%s'", settings.buildHook);
+ auto buildHookArgs = tokenizeString<std::list<std::string>>(settings.buildHook.get());
+
+ if (buildHookArgs.empty())
+ throw Error("'build-hook' setting is empty");
+
+ auto buildHook = buildHookArgs.front();
+ buildHookArgs.pop_front();
+
+ Strings args;
+
+ for (auto & arg : buildHookArgs)
+ args.push_back(arg);
+
+ args.push_back(std::string(baseNameOf(settings.buildHook.get())));
+ args.push_back(std::to_string(verbosity));
+
/* Create a pipe to get the output of the child. */
fromHook.create();
@@ -36,14 +52,9 @@ HookInstance::HookInstance()
if (dup2(builderOut.readSide.get(), 5) == -1)
throw SysError("dupping builder's stdout/stderr");
- Strings args = {
- std::string(baseNameOf(settings.buildHook.get())),
- std::to_string(verbosity),
- };
-
- execv(settings.buildHook.get().c_str(), stringsToCharPtrs(args).data());
+ execv(buildHook.c_str(), stringsToCharPtrs(args).data());
- throw SysError("executing '%s'", settings.buildHook);
+ throw SysError("executing '%s'", buildHook);
});
pid.setSeparatePG(true);
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index cc009a026..1d7f65135 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -67,12 +67,13 @@ Settings::Settings()
sandboxPaths = tokenizeString<StringSet>("/bin/sh=" SANDBOX_SHELL);
#endif
-
-/* chroot-like behavior from Apple's sandbox */
+ /* chroot-like behavior from Apple's sandbox */
#if __APPLE__
sandboxPaths = tokenizeString<StringSet>("/System/Library/Frameworks /System/Library/PrivateFrameworks /bin/sh /bin/bash /private/tmp /private/var/tmp /usr/lib");
allowedImpureHostPrefixes = tokenizeString<StringSet>("/System/Library /usr/lib /dev /bin/sh");
#endif
+
+ buildHook = getSelfExe().value_or("nix") + " __build-remote";
}
void loadConfFile()
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index 0ee27ecb6..9df1c999c 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -195,7 +195,7 @@ public:
)",
{"build-timeout"}};
- PathSetting buildHook{this, true, nixLibexecDir + "/nix/build-remote", "build-hook",
+ PathSetting buildHook{this, true, "", "build-hook",
"The path of the helper program that executes builds to remote machines."};
Setting<std::string> builders{
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index aabd23427..82628461c 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -633,6 +633,20 @@ Path getDataDir()
}
+std::optional<Path> getSelfExe()
+{
+ static std::optional<Path> cached = []()
+ {
+ #if __linux__
+ return readLink("/proc/self/exe");
+ #else
+ return std::nullopt;
+ #endif
+ }();
+ return cached;
+}
+
+
Paths createDirs(const Path & path)
{
Paths created;
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 90418b04d..d3ed15b0b 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -149,10 +149,14 @@ std::vector<Path> getConfigDirs();
/* Return $XDG_DATA_HOME or $HOME/.local/share. */
Path getDataDir();
+/* Return the path of the current executable. */
+std::optional<Path> getSelfExe();
+
/* Create a directory and all its parents, if necessary. Returns the
list of created directories, in order of creation. */
Paths createDirs(const Path & path);
-inline Paths createDirs(PathView path) {
+inline Paths createDirs(PathView path)
+{
return createDirs(Path(path));
}
diff --git a/src/nix/main.cc b/src/nix/main.cc
index f398e3118..17c92ebc6 100644
--- a/src/nix/main.cc
+++ b/src/nix/main.cc
@@ -266,6 +266,11 @@ void mainWrapped(int argc, char * * argv)
programPath = argv[0];
auto programName = std::string(baseNameOf(programPath));
+ if (argc > 0 && std::string_view(argv[0]) == "__build-remote") {
+ programName = "build-remote";
+ argv++; argc--;
+ }
+
{
auto legacy = (*RegisterLegacyCommand::commands)[programName];
if (legacy) return legacy(argc, argv);
diff --git a/src/nix/run.cc b/src/nix/run.cc
index 25a8fa8d3..45d2dfd0d 100644
--- a/src/nix/run.cc
+++ b/src/nix/run.cc
@@ -47,7 +47,7 @@ void runProgramInStore(ref<Store> store,
Strings helperArgs = { chrootHelperName, store->storeDir, store2->getRealStoreDir(), program };
for (auto & arg : args) helperArgs.push_back(arg);
- execv(readLink("/proc/self/exe").c_str(), stringsToCharPtrs(helperArgs).data());
+ execv(getSelfExe().value_or("nix").c_str(), stringsToCharPtrs(helperArgs).data());
throw SysError("could not execute chroot helper");
}