mirror of
https://github.com/NixOS/nix
synced 2025-06-25 14:51:16 +02:00
Merge pull request #13047 from obsidiansystems/derivation-building-2
Remove double indirection from `DerivationBuilder` params
This commit is contained in:
commit
f186491db9
3 changed files with 104 additions and 97 deletions
|
@ -472,16 +472,16 @@ void DerivationBuilderImpl::killSandbox(bool getStats)
|
||||||
bool DerivationBuilderImpl::prepareBuild()
|
bool DerivationBuilderImpl::prepareBuild()
|
||||||
{
|
{
|
||||||
/* Cache this */
|
/* Cache this */
|
||||||
derivationType = drv->type();
|
derivationType = drv.type();
|
||||||
|
|
||||||
/* Are we doing a chroot build? */
|
/* Are we doing a chroot build? */
|
||||||
{
|
{
|
||||||
if (settings.sandboxMode == smEnabled) {
|
if (settings.sandboxMode == smEnabled) {
|
||||||
if (drvOptions->noChroot)
|
if (drvOptions.noChroot)
|
||||||
throw Error("derivation '%s' has '__noChroot' set, "
|
throw Error("derivation '%s' has '__noChroot' set, "
|
||||||
"but that's not allowed when 'sandbox' is 'true'", store.printStorePath(drvPath));
|
"but that's not allowed when 'sandbox' is 'true'", store.printStorePath(drvPath));
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (drvOptions->additionalSandboxProfile != "")
|
if (drvOptions.additionalSandboxProfile != "")
|
||||||
throw Error("derivation '%s' specifies a sandbox profile, "
|
throw Error("derivation '%s' specifies a sandbox profile, "
|
||||||
"but this is only allowed when 'sandbox' is 'relaxed'", store.printStorePath(drvPath));
|
"but this is only allowed when 'sandbox' is 'relaxed'", store.printStorePath(drvPath));
|
||||||
#endif
|
#endif
|
||||||
|
@ -490,7 +490,7 @@ bool DerivationBuilderImpl::prepareBuild()
|
||||||
else if (settings.sandboxMode == smDisabled)
|
else if (settings.sandboxMode == smDisabled)
|
||||||
useChroot = false;
|
useChroot = false;
|
||||||
else if (settings.sandboxMode == smRelaxed)
|
else if (settings.sandboxMode == smRelaxed)
|
||||||
useChroot = derivationType->isSandboxed() && !drvOptions->noChroot;
|
useChroot = derivationType->isSandboxed() && !drvOptions.noChroot;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto & localStore = getLocalStore();
|
auto & localStore = getLocalStore();
|
||||||
|
@ -515,7 +515,7 @@ bool DerivationBuilderImpl::prepareBuild()
|
||||||
|
|
||||||
if (useBuildUsers()) {
|
if (useBuildUsers()) {
|
||||||
if (!buildUser)
|
if (!buildUser)
|
||||||
buildUser = acquireUserLock(drvOptions->useUidRange(*drv) ? 65536 : 1, useChroot);
|
buildUser = acquireUserLock(drvOptions.useUidRange(drv) ? 65536 : 1, useChroot);
|
||||||
|
|
||||||
if (!buildUser) {
|
if (!buildUser) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -832,14 +832,14 @@ void DerivationBuilderImpl::startBuilder()
|
||||||
killSandbox(false);
|
killSandbox(false);
|
||||||
|
|
||||||
/* Right platform? */
|
/* Right platform? */
|
||||||
if (!drvOptions->canBuildLocally(store, *drv)) {
|
if (!drvOptions.canBuildLocally(store, drv)) {
|
||||||
// since aarch64-darwin has Rosetta 2, this user can actually run x86_64-darwin on their hardware - we should tell them to run the command to install Darwin 2
|
// since aarch64-darwin has Rosetta 2, this user can actually run x86_64-darwin on their hardware - we should tell them to run the command to install Darwin 2
|
||||||
if (drv->platform == "x86_64-darwin" && settings.thisSystem == "aarch64-darwin") {
|
if (drv.platform == "x86_64-darwin" && settings.thisSystem == "aarch64-darwin") {
|
||||||
throw Error("run `/usr/sbin/softwareupdate --install-rosetta` to enable your %s to run programs for %s", settings.thisSystem, drv->platform);
|
throw Error("run `/usr/sbin/softwareupdate --install-rosetta` to enable your %s to run programs for %s", settings.thisSystem, drv.platform);
|
||||||
} else {
|
} else {
|
||||||
throw Error("a '%s' with features {%s} is required to build '%s', but I am a '%s' with features {%s}",
|
throw Error("a '%s' with features {%s} is required to build '%s', but I am a '%s' with features {%s}",
|
||||||
drv->platform,
|
drv.platform,
|
||||||
concatStringsSep(", ", drvOptions->getRequiredSystemFeatures(*drv)),
|
concatStringsSep(", ", drvOptions.getRequiredSystemFeatures(drv)),
|
||||||
store.printStorePath(drvPath),
|
store.printStorePath(drvPath),
|
||||||
settings.thisSystem,
|
settings.thisSystem,
|
||||||
concatStringsSep<StringSet>(", ", store.systemFeatures));
|
concatStringsSep<StringSet>(", ", store.systemFeatures));
|
||||||
|
@ -930,7 +930,7 @@ void DerivationBuilderImpl::startBuilder()
|
||||||
|
|
||||||
/* Handle exportReferencesGraph(), if set. */
|
/* Handle exportReferencesGraph(), if set. */
|
||||||
if (!parsedDrv) {
|
if (!parsedDrv) {
|
||||||
for (auto & [fileName, ss] : drvOptions->exportReferencesGraph) {
|
for (auto & [fileName, ss] : drvOptions.exportReferencesGraph) {
|
||||||
StorePathSet storePathSet;
|
StorePathSet storePathSet;
|
||||||
for (auto & storePathS : ss) {
|
for (auto & storePathS : ss) {
|
||||||
if (!store.isInStore(storePathS))
|
if (!store.isInStore(storePathS))
|
||||||
|
@ -988,7 +988,7 @@ void DerivationBuilderImpl::startBuilder()
|
||||||
PathSet allowedPaths = settings.allowedImpureHostPrefixes;
|
PathSet allowedPaths = settings.allowedImpureHostPrefixes;
|
||||||
|
|
||||||
/* This works like the above, except on a per-derivation level */
|
/* This works like the above, except on a per-derivation level */
|
||||||
auto impurePaths = drvOptions->impureHostDeps;
|
auto impurePaths = drvOptions.impureHostDeps;
|
||||||
|
|
||||||
for (auto & i : impurePaths) {
|
for (auto & i : impurePaths) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
@ -1008,7 +1008,7 @@ void DerivationBuilderImpl::startBuilder()
|
||||||
throw Error("derivation '%s' requested impure path '%s', but it was not in allowed-impure-host-deps",
|
throw Error("derivation '%s' requested impure path '%s', but it was not in allowed-impure-host-deps",
|
||||||
store.printStorePath(drvPath), i);
|
store.printStorePath(drvPath), i);
|
||||||
|
|
||||||
/* Allow files in drvOptions->impureHostDeps to be missing; e.g.
|
/* Allow files in drvOptions.impureHostDeps to be missing; e.g.
|
||||||
macOS 11+ has no /usr/lib/libSystem*.dylib */
|
macOS 11+ has no /usr/lib/libSystem*.dylib */
|
||||||
pathsInChroot[i] = {i, true};
|
pathsInChroot[i] = {i, true};
|
||||||
}
|
}
|
||||||
|
@ -1048,10 +1048,10 @@ void DerivationBuilderImpl::startBuilder()
|
||||||
nobody account. The latter is kind of a hack to support
|
nobody account. The latter is kind of a hack to support
|
||||||
Samba-in-QEMU. */
|
Samba-in-QEMU. */
|
||||||
createDirs(chrootRootDir + "/etc");
|
createDirs(chrootRootDir + "/etc");
|
||||||
if (drvOptions->useUidRange(*drv))
|
if (drvOptions.useUidRange(drv))
|
||||||
chownToBuilder(chrootRootDir + "/etc");
|
chownToBuilder(chrootRootDir + "/etc");
|
||||||
|
|
||||||
if (drvOptions->useUidRange(*drv) && (!buildUser || buildUser->getUIDCount() < 65536))
|
if (drvOptions.useUidRange(drv) && (!buildUser || buildUser->getUIDCount() < 65536))
|
||||||
throw Error("feature 'uid-range' requires the setting '%s' to be enabled", settings.autoAllocateUids.name);
|
throw Error("feature 'uid-range' requires the setting '%s' to be enabled", settings.autoAllocateUids.name);
|
||||||
|
|
||||||
/* Declare the build user's group so that programs get a consistent
|
/* Declare the build user's group so that programs get a consistent
|
||||||
|
@ -1090,7 +1090,7 @@ void DerivationBuilderImpl::startBuilder()
|
||||||
rebuilding a path that is in settings.sandbox-paths
|
rebuilding a path that is in settings.sandbox-paths
|
||||||
(typically the dependencies of /bin/sh). Throw them
|
(typically the dependencies of /bin/sh). Throw them
|
||||||
out. */
|
out. */
|
||||||
for (auto & i : drv->outputsAndOptPaths(store)) {
|
for (auto & i : drv.outputsAndOptPaths(store)) {
|
||||||
/* If the name isn't known a priori (i.e. floating
|
/* If the name isn't known a priori (i.e. floating
|
||||||
content-addressing derivation), the temporary location we use
|
content-addressing derivation), the temporary location we use
|
||||||
should be fresh. Freshness means it is impossible that the path
|
should be fresh. Freshness means it is impossible that the path
|
||||||
|
@ -1110,7 +1110,7 @@ void DerivationBuilderImpl::startBuilder()
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
if (drvOptions->useUidRange(*drv))
|
if (drvOptions.useUidRange(drv))
|
||||||
throw Error("feature 'uid-range' is not supported on this platform");
|
throw Error("feature 'uid-range' is not supported on this platform");
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
/* We don't really have any parent prep work to do (yet?)
|
/* We don't really have any parent prep work to do (yet?)
|
||||||
|
@ -1120,14 +1120,14 @@ void DerivationBuilderImpl::startBuilder()
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (drvOptions->useUidRange(*drv))
|
if (drvOptions.useUidRange(drv))
|
||||||
throw Error("feature 'uid-range' is only supported in sandboxed builds");
|
throw Error("feature 'uid-range' is only supported in sandboxed builds");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsHashRewrite() && pathExists(homeDir))
|
if (needsHashRewrite() && pathExists(homeDir))
|
||||||
throw Error("home directory '%1%' exists; please remove it to assure purity of builds without sandboxing", 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())) {
|
if (useChroot && settings.preBuildHook != "" && dynamic_cast<const Derivation *>(&drv)) {
|
||||||
printMsg(lvlChatty, "executing pre-build hook '%1%'", settings.preBuildHook);
|
printMsg(lvlChatty, "executing pre-build hook '%1%'", settings.preBuildHook);
|
||||||
auto args = useChroot ? Strings({store.printStorePath(drvPath), chrootRootDir}) :
|
auto args = useChroot ? Strings({store.printStorePath(drvPath), chrootRootDir}) :
|
||||||
Strings({ store.printStorePath(drvPath) });
|
Strings({ store.printStorePath(drvPath) });
|
||||||
|
@ -1165,13 +1165,13 @@ void DerivationBuilderImpl::startBuilder()
|
||||||
|
|
||||||
/* Fire up a Nix daemon to process recursive Nix calls from the
|
/* Fire up a Nix daemon to process recursive Nix calls from the
|
||||||
builder. */
|
builder. */
|
||||||
if (drvOptions->getRequiredSystemFeatures(*drv).count("recursive-nix"))
|
if (drvOptions.getRequiredSystemFeatures(drv).count("recursive-nix"))
|
||||||
startDaemon();
|
startDaemon();
|
||||||
|
|
||||||
/* Run the builder. */
|
/* Run the builder. */
|
||||||
printMsg(lvlChatty, "executing builder '%1%'", drv->builder);
|
printMsg(lvlChatty, "executing builder '%1%'", drv.builder);
|
||||||
printMsg(lvlChatty, "using builder args '%1%'", concatStringsSep(" ", drv->args));
|
printMsg(lvlChatty, "using builder args '%1%'", concatStringsSep(" ", drv.args));
|
||||||
for (auto & i : drv->env)
|
for (auto & i : drv.env)
|
||||||
printMsg(lvlVomit, "setting builder env variable '%1%'='%2%'", i.first, i.second);
|
printMsg(lvlVomit, "setting builder env variable '%1%'='%2%'", i.first, i.second);
|
||||||
|
|
||||||
/* Create the log file. */
|
/* Create the log file. */
|
||||||
|
@ -1434,8 +1434,8 @@ void DerivationBuilderImpl::initTmpDir()
|
||||||
environment or via a file, as specified by
|
environment or via a file, as specified by
|
||||||
`DerivationOptions::passAsFile`. */
|
`DerivationOptions::passAsFile`. */
|
||||||
if (!parsedDrv) {
|
if (!parsedDrv) {
|
||||||
for (auto & i : drv->env) {
|
for (auto & i : drv.env) {
|
||||||
if (drvOptions->passAsFile.find(i.first) == drvOptions->passAsFile.end()) {
|
if (drvOptions.passAsFile.find(i.first) == drvOptions.passAsFile.end()) {
|
||||||
env[i.first] = i.second;
|
env[i.first] = i.second;
|
||||||
} else {
|
} else {
|
||||||
auto hash = hashString(HashAlgorithm::SHA256, i.first);
|
auto hash = hashString(HashAlgorithm::SHA256, i.first);
|
||||||
|
@ -1512,7 +1512,7 @@ void DerivationBuilderImpl::initEnv()
|
||||||
if (!impureEnv.empty())
|
if (!impureEnv.empty())
|
||||||
experimentalFeatureSettings.require(Xp::ConfigurableImpureEnv);
|
experimentalFeatureSettings.require(Xp::ConfigurableImpureEnv);
|
||||||
|
|
||||||
for (auto & i : drvOptions->impureEnvVars){
|
for (auto & i : drvOptions.impureEnvVars){
|
||||||
auto envVar = impureEnv.find(i);
|
auto envVar = impureEnv.find(i);
|
||||||
if (envVar != impureEnv.end()) {
|
if (envVar != impureEnv.end()) {
|
||||||
env[i] = envVar->second;
|
env[i] = envVar->second;
|
||||||
|
@ -1537,9 +1537,9 @@ void DerivationBuilderImpl::writeStructuredAttrs()
|
||||||
if (parsedDrv) {
|
if (parsedDrv) {
|
||||||
auto json = parsedDrv->prepareStructuredAttrs(
|
auto json = parsedDrv->prepareStructuredAttrs(
|
||||||
store,
|
store,
|
||||||
*drvOptions,
|
drvOptions,
|
||||||
inputPaths,
|
inputPaths,
|
||||||
drv->outputs);
|
drv.outputs);
|
||||||
nlohmann::json rewritten;
|
nlohmann::json rewritten;
|
||||||
for (auto & [i, v] : json["outputs"].get<nlohmann::json::object_t>()) {
|
for (auto & [i, v] : json["outputs"].get<nlohmann::json::object_t>()) {
|
||||||
/* The placeholder must have a rewrite, so we use it to cover both the
|
/* The placeholder must have a rewrite, so we use it to cover both the
|
||||||
|
@ -1834,7 +1834,7 @@ void DerivationBuilderImpl::runChild()
|
||||||
different uid and/or in a sandbox). */
|
different uid and/or in a sandbox). */
|
||||||
std::string netrcData;
|
std::string netrcData;
|
||||||
std::string caFileData;
|
std::string caFileData;
|
||||||
if (drv->isBuiltin() && drv->builder == "builtin:fetchurl") {
|
if (drv.isBuiltin() && drv.builder == "builtin:fetchurl") {
|
||||||
try {
|
try {
|
||||||
netrcData = readFile(settings.netrcFile);
|
netrcData = readFile(settings.netrcFile);
|
||||||
} catch (SystemError &) { }
|
} catch (SystemError &) { }
|
||||||
|
@ -2019,7 +2019,7 @@ void DerivationBuilderImpl::runChild()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make /etc unwritable */
|
/* Make /etc unwritable */
|
||||||
if (!drvOptions->useUidRange(*drv))
|
if (!drvOptions.useUidRange(drv))
|
||||||
chmod_(chrootRootDir + "/etc", 0555);
|
chmod_(chrootRootDir + "/etc", 0555);
|
||||||
|
|
||||||
/* Unshare this mount namespace. This is necessary because
|
/* Unshare this mount namespace. This is necessary because
|
||||||
|
@ -2079,7 +2079,7 @@ void DerivationBuilderImpl::runChild()
|
||||||
unix::closeExtraFDs();
|
unix::closeExtraFDs();
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
linux::setPersonality(drv->platform);
|
linux::setPersonality(drv.platform);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Disable core dumps by default. */
|
/* Disable core dumps by default. */
|
||||||
|
@ -2217,7 +2217,7 @@ void DerivationBuilderImpl::runChild()
|
||||||
}
|
}
|
||||||
sandboxProfile += ")\n";
|
sandboxProfile += ")\n";
|
||||||
|
|
||||||
sandboxProfile += drvOptions->additionalSandboxProfile;
|
sandboxProfile += drvOptions.additionalSandboxProfile;
|
||||||
} else
|
} else
|
||||||
sandboxProfile +=
|
sandboxProfile +=
|
||||||
#include "sandbox-minimal.sb"
|
#include "sandbox-minimal.sb"
|
||||||
|
@ -2238,7 +2238,7 @@ void DerivationBuilderImpl::runChild()
|
||||||
Strings sandboxArgs;
|
Strings sandboxArgs;
|
||||||
sandboxArgs.push_back("_GLOBAL_TMP_DIR");
|
sandboxArgs.push_back("_GLOBAL_TMP_DIR");
|
||||||
sandboxArgs.push_back(globalTmpDir);
|
sandboxArgs.push_back(globalTmpDir);
|
||||||
if (drvOptions->allowLocalNetworking) {
|
if (drvOptions.allowLocalNetworking) {
|
||||||
sandboxArgs.push_back("_ALLOW_LOCAL_NETWORKING");
|
sandboxArgs.push_back("_ALLOW_LOCAL_NETWORKING");
|
||||||
sandboxArgs.push_back("1");
|
sandboxArgs.push_back("1");
|
||||||
}
|
}
|
||||||
|
@ -2256,23 +2256,23 @@ void DerivationBuilderImpl::runChild()
|
||||||
sendException = false;
|
sendException = false;
|
||||||
|
|
||||||
/* Execute the program. This should not return. */
|
/* Execute the program. This should not return. */
|
||||||
if (drv->isBuiltin()) {
|
if (drv.isBuiltin()) {
|
||||||
try {
|
try {
|
||||||
logger = makeJSONLogger(getStandardError());
|
logger = makeJSONLogger(getStandardError());
|
||||||
|
|
||||||
std::map<std::string, Path> outputs;
|
std::map<std::string, Path> outputs;
|
||||||
for (auto & e : drv->outputs)
|
for (auto & e : drv.outputs)
|
||||||
outputs.insert_or_assign(e.first,
|
outputs.insert_or_assign(e.first,
|
||||||
store.printStorePath(scratchOutputs.at(e.first)));
|
store.printStorePath(scratchOutputs.at(e.first)));
|
||||||
|
|
||||||
if (drv->builder == "builtin:fetchurl")
|
if (drv.builder == "builtin:fetchurl")
|
||||||
builtinFetchurl(*drv, outputs, netrcData, caFileData);
|
builtinFetchurl(drv, outputs, netrcData, caFileData);
|
||||||
else if (drv->builder == "builtin:buildenv")
|
else if (drv.builder == "builtin:buildenv")
|
||||||
builtinBuildenv(*drv, outputs);
|
builtinBuildenv(drv, outputs);
|
||||||
else if (drv->builder == "builtin:unpack-channel")
|
else if (drv.builder == "builtin:unpack-channel")
|
||||||
builtinUnpackChannel(*drv, outputs);
|
builtinUnpackChannel(drv, outputs);
|
||||||
else
|
else
|
||||||
throw Error("unsupported builtin builder '%1%'", drv->builder.substr(8));
|
throw Error("unsupported builtin builder '%1%'", drv.builder.substr(8));
|
||||||
_exit(0);
|
_exit(0);
|
||||||
} catch (std::exception & e) {
|
} catch (std::exception & e) {
|
||||||
writeFull(STDERR_FILENO, e.what() + std::string("\n"));
|
writeFull(STDERR_FILENO, e.what() + std::string("\n"));
|
||||||
|
@ -2283,9 +2283,9 @@ void DerivationBuilderImpl::runChild()
|
||||||
// Now builder is not builtin
|
// Now builder is not builtin
|
||||||
|
|
||||||
Strings args;
|
Strings args;
|
||||||
args.push_back(std::string(baseNameOf(drv->builder)));
|
args.push_back(std::string(baseNameOf(drv.builder)));
|
||||||
|
|
||||||
for (auto & i : drv->args)
|
for (auto & i : drv.args)
|
||||||
args.push_back(rewriteStrings(i, inputRewrites));
|
args.push_back(rewriteStrings(i, inputRewrites));
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
@ -2297,24 +2297,24 @@ void DerivationBuilderImpl::runChild()
|
||||||
if (posix_spawnattr_setflags(&attrp, POSIX_SPAWN_SETEXEC))
|
if (posix_spawnattr_setflags(&attrp, POSIX_SPAWN_SETEXEC))
|
||||||
throw SysError("failed to initialize builder");
|
throw SysError("failed to initialize builder");
|
||||||
|
|
||||||
if (drv->platform == "aarch64-darwin") {
|
if (drv.platform == "aarch64-darwin") {
|
||||||
// Unset kern.curproc_arch_affinity so we can escape Rosetta
|
// Unset kern.curproc_arch_affinity so we can escape Rosetta
|
||||||
int affinity = 0;
|
int affinity = 0;
|
||||||
sysctlbyname("kern.curproc_arch_affinity", NULL, NULL, &affinity, sizeof(affinity));
|
sysctlbyname("kern.curproc_arch_affinity", NULL, NULL, &affinity, sizeof(affinity));
|
||||||
|
|
||||||
cpu_type_t cpu = CPU_TYPE_ARM64;
|
cpu_type_t cpu = CPU_TYPE_ARM64;
|
||||||
posix_spawnattr_setbinpref_np(&attrp, 1, &cpu, NULL);
|
posix_spawnattr_setbinpref_np(&attrp, 1, &cpu, NULL);
|
||||||
} else if (drv->platform == "x86_64-darwin") {
|
} else if (drv.platform == "x86_64-darwin") {
|
||||||
cpu_type_t cpu = CPU_TYPE_X86_64;
|
cpu_type_t cpu = CPU_TYPE_X86_64;
|
||||||
posix_spawnattr_setbinpref_np(&attrp, 1, &cpu, NULL);
|
posix_spawnattr_setbinpref_np(&attrp, 1, &cpu, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
posix_spawn(NULL, drv->builder.c_str(), NULL, &attrp, stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data());
|
posix_spawn(NULL, drv.builder.c_str(), NULL, &attrp, stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data());
|
||||||
#else
|
#else
|
||||||
execve(drv->builder.c_str(), stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data());
|
execve(drv.builder.c_str(), stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
throw SysError("executing '%1%'", drv->builder);
|
throw SysError("executing '%1%'", drv.builder);
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
handleChildException(sendException);
|
handleChildException(sendException);
|
||||||
|
@ -2362,7 +2362,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
|
||||||
struct PerhapsNeedToRegister { StorePathSet refs; };
|
struct PerhapsNeedToRegister { StorePathSet refs; };
|
||||||
std::map<std::string, std::variant<AlreadyRegistered, PerhapsNeedToRegister>> outputReferencesIfUnregistered;
|
std::map<std::string, std::variant<AlreadyRegistered, PerhapsNeedToRegister>> outputReferencesIfUnregistered;
|
||||||
std::map<std::string, struct stat> outputStats;
|
std::map<std::string, struct stat> outputStats;
|
||||||
for (auto & [outputName, _] : drv->outputs) {
|
for (auto & [outputName, _] : drv.outputs) {
|
||||||
auto scratchOutput = get(scratchOutputs, outputName);
|
auto scratchOutput = get(scratchOutputs, outputName);
|
||||||
if (!scratchOutput)
|
if (!scratchOutput)
|
||||||
throw BuildError(
|
throw BuildError(
|
||||||
|
@ -2418,7 +2418,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
|
||||||
inodesSeen);
|
inodesSeen);
|
||||||
|
|
||||||
bool discardReferences = false;
|
bool discardReferences = false;
|
||||||
if (auto udr = get(drvOptions->unsafeDiscardReferences, outputName)) {
|
if (auto udr = get(drvOptions.unsafeDiscardReferences, outputName)) {
|
||||||
discardReferences = *udr;
|
discardReferences = *udr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2474,7 +2474,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
|
||||||
OutputPathMap finalOutputs;
|
OutputPathMap finalOutputs;
|
||||||
|
|
||||||
for (auto & outputName : sortedOutputNames) {
|
for (auto & outputName : sortedOutputNames) {
|
||||||
auto output = get(drv->outputs, outputName);
|
auto output = get(drv.outputs, outputName);
|
||||||
auto scratchPath = get(scratchOutputs, outputName);
|
auto scratchPath = get(scratchOutputs, outputName);
|
||||||
assert(output && scratchPath);
|
assert(output && scratchPath);
|
||||||
auto actualPath = toRealPathChroot(store.printStorePath(*scratchPath));
|
auto actualPath = toRealPathChroot(store.printStorePath(*scratchPath));
|
||||||
|
@ -2596,7 +2596,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
|
||||||
|
|
||||||
ValidPathInfo newInfo0 {
|
ValidPathInfo newInfo0 {
|
||||||
store,
|
store,
|
||||||
outputPathName(drv->name, outputName),
|
outputPathName(drv.name, outputName),
|
||||||
ContentAddressWithReferences::fromParts(
|
ContentAddressWithReferences::fromParts(
|
||||||
outputHash.method,
|
outputHash.method,
|
||||||
std::move(got),
|
std::move(got),
|
||||||
|
@ -2725,7 +2725,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
|
||||||
derivations. */
|
derivations. */
|
||||||
PathLocks dynamicOutputLock;
|
PathLocks dynamicOutputLock;
|
||||||
dynamicOutputLock.setDeletion(true);
|
dynamicOutputLock.setDeletion(true);
|
||||||
auto optFixedPath = output->path(store, drv->name, outputName);
|
auto optFixedPath = output->path(store, drv.name, outputName);
|
||||||
if (!optFixedPath ||
|
if (!optFixedPath ||
|
||||||
store.printStorePath(*optFixedPath) != finalDestPath)
|
store.printStorePath(*optFixedPath) != finalDestPath)
|
||||||
{
|
{
|
||||||
|
@ -2863,7 +2863,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
|
||||||
.outPath = newInfo.path
|
.outPath = newInfo.path
|
||||||
};
|
};
|
||||||
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)
|
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)
|
||||||
&& !drv->type().isImpure())
|
&& !drv.type().isImpure())
|
||||||
{
|
{
|
||||||
store.signRealisation(thisRealisation);
|
store.signRealisation(thisRealisation);
|
||||||
store.registerDrvOutput(thisRealisation);
|
store.registerDrvOutput(thisRealisation);
|
||||||
|
@ -3005,7 +3005,7 @@ void DerivationBuilderImpl::checkOutputs(const std::map<std::string, ValidPathIn
|
||||||
|
|
||||||
applyChecks(*outputChecks);
|
applyChecks(*outputChecks);
|
||||||
},
|
},
|
||||||
}, drvOptions->outputChecks);
|
}, drvOptions.outputChecks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3015,7 +3015,7 @@ void DerivationBuilderImpl::deleteTmpDir(bool force)
|
||||||
if (topTmpDir != "") {
|
if (topTmpDir != "") {
|
||||||
/* Don't keep temporary directories for builtins because they
|
/* Don't keep temporary directories for builtins because they
|
||||||
might have privileged stuff (like a copy of netrc). */
|
might have privileged stuff (like a copy of netrc). */
|
||||||
if (settings.keepFailed && !force && !drv->isBuiltin()) {
|
if (settings.keepFailed && !force && !drv.isBuiltin()) {
|
||||||
printError("note: keeping build directory '%s'", tmpDir);
|
printError("note: keeping build directory '%s'", tmpDir);
|
||||||
chmod(topTmpDir.c_str(), 0755);
|
chmod(topTmpDir.c_str(), 0755);
|
||||||
chmod(tmpDir.c_str(), 0755);
|
chmod(tmpDir.c_str(), 0755);
|
||||||
|
@ -3037,7 +3037,7 @@ StorePath DerivationBuilderImpl::makeFallbackPath(OutputNameView outputName)
|
||||||
return store.makeStorePath(
|
return store.makeStorePath(
|
||||||
pathType,
|
pathType,
|
||||||
// pass an all-zeroes hash
|
// pass an all-zeroes hash
|
||||||
Hash(HashAlgorithm::SHA256), outputPathName(drv->name, outputName));
|
Hash(HashAlgorithm::SHA256), outputPathName(drv.name, outputName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,38 +41,12 @@ struct LocalDerivationGoal : DerivationGoal, DerivationBuilderCallbacks
|
||||||
const OutputsSpec & wantedOutputs, Worker & worker,
|
const OutputsSpec & wantedOutputs, Worker & worker,
|
||||||
BuildMode buildMode)
|
BuildMode buildMode)
|
||||||
: DerivationGoal{drvPath, wantedOutputs, worker, buildMode}
|
: DerivationGoal{drvPath, wantedOutputs, worker, buildMode}
|
||||||
, builder{makeDerivationBuilder(
|
|
||||||
worker.store,
|
|
||||||
static_cast<DerivationBuilderCallbacks &>(*this),
|
|
||||||
DerivationBuilderParams {
|
|
||||||
DerivationGoal::drvPath,
|
|
||||||
DerivationGoal::buildMode,
|
|
||||||
DerivationGoal::buildResult,
|
|
||||||
DerivationGoal::drv,
|
|
||||||
DerivationGoal::parsedDrv,
|
|
||||||
DerivationGoal::drvOptions,
|
|
||||||
DerivationGoal::inputPaths,
|
|
||||||
DerivationGoal::initialOutputs,
|
|
||||||
})}
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
LocalDerivationGoal(const StorePath & drvPath, const BasicDerivation & drv,
|
LocalDerivationGoal(const StorePath & drvPath, const BasicDerivation & drv,
|
||||||
const OutputsSpec & wantedOutputs, Worker & worker,
|
const OutputsSpec & wantedOutputs, Worker & worker,
|
||||||
BuildMode buildMode = bmNormal)
|
BuildMode buildMode = bmNormal)
|
||||||
: DerivationGoal{drvPath, drv, wantedOutputs, worker, buildMode}
|
: DerivationGoal{drvPath, drv, wantedOutputs, worker, buildMode}
|
||||||
, builder{makeDerivationBuilder(
|
|
||||||
worker.store,
|
|
||||||
static_cast<DerivationBuilderCallbacks &>(*this),
|
|
||||||
DerivationBuilderParams {
|
|
||||||
DerivationGoal::drvPath,
|
|
||||||
DerivationGoal::buildMode,
|
|
||||||
DerivationGoal::buildResult,
|
|
||||||
DerivationGoal::drv,
|
|
||||||
DerivationGoal::parsedDrv,
|
|
||||||
DerivationGoal::drvOptions,
|
|
||||||
DerivationGoal::inputPaths,
|
|
||||||
DerivationGoal::initialOutputs,
|
|
||||||
})}
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~LocalDerivationGoal() override;
|
virtual ~LocalDerivationGoal() override;
|
||||||
|
@ -136,15 +110,19 @@ LocalDerivationGoal::~LocalDerivationGoal()
|
||||||
{
|
{
|
||||||
/* Careful: we should never ever throw an exception from a
|
/* Careful: we should never ever throw an exception from a
|
||||||
destructor. */
|
destructor. */
|
||||||
|
if (builder) {
|
||||||
try { builder->deleteTmpDir(false); } catch (...) { ignoreExceptionInDestructor(); }
|
try { builder->deleteTmpDir(false); } catch (...) { ignoreExceptionInDestructor(); }
|
||||||
|
}
|
||||||
try { killChild(); } catch (...) { ignoreExceptionInDestructor(); }
|
try { killChild(); } catch (...) { ignoreExceptionInDestructor(); }
|
||||||
|
if (builder) {
|
||||||
try { builder->stopDaemon(); } catch (...) { ignoreExceptionInDestructor(); }
|
try { builder->stopDaemon(); } catch (...) { ignoreExceptionInDestructor(); }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void LocalDerivationGoal::killChild()
|
void LocalDerivationGoal::killChild()
|
||||||
{
|
{
|
||||||
if (builder->pid != -1) {
|
if (builder && builder->pid != -1) {
|
||||||
worker.childTerminated(this);
|
worker.childTerminated(this);
|
||||||
|
|
||||||
/* If we're using a build user, then there is a tricky race
|
/* If we're using a build user, then there is a tricky race
|
||||||
|
@ -165,6 +143,7 @@ void LocalDerivationGoal::killChild()
|
||||||
|
|
||||||
void LocalDerivationGoal::childStarted()
|
void LocalDerivationGoal::childStarted()
|
||||||
{
|
{
|
||||||
|
assert(builder);
|
||||||
worker.childStarted(shared_from_this(), {builder->builderOut.get()}, true, true);
|
worker.childStarted(shared_from_this(), {builder->builderOut.get()}, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +181,24 @@ Goal::Co LocalDerivationGoal::tryLocalBuild()
|
||||||
co_return tryToBuild();
|
co_return tryToBuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!builder) {
|
||||||
|
/* If we have to wait and retry (see below), then `builder` will
|
||||||
|
already be created, so we don't need to create it again. */
|
||||||
|
builder = makeDerivationBuilder(
|
||||||
|
worker.store,
|
||||||
|
static_cast<DerivationBuilderCallbacks &>(*this),
|
||||||
|
DerivationBuilderParams {
|
||||||
|
DerivationGoal::drvPath,
|
||||||
|
DerivationGoal::buildMode,
|
||||||
|
DerivationGoal::buildResult,
|
||||||
|
*DerivationGoal::drv,
|
||||||
|
DerivationGoal::parsedDrv.get(),
|
||||||
|
*DerivationGoal::drvOptions,
|
||||||
|
DerivationGoal::inputPaths,
|
||||||
|
DerivationGoal::initialOutputs,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (!builder->prepareBuild()) {
|
if (!builder->prepareBuild()) {
|
||||||
if (!actLock)
|
if (!actLock)
|
||||||
actLock = std::make_unique<Activity>(*logger, lvlWarn, actBuildWaiting,
|
actLock = std::make_unique<Activity>(*logger, lvlWarn, actBuildWaiting,
|
||||||
|
@ -251,7 +248,7 @@ Goal::Co LocalDerivationGoal::tryLocalBuild()
|
||||||
bool LocalDerivationGoal::isReadDesc(int fd)
|
bool LocalDerivationGoal::isReadDesc(int fd)
|
||||||
{
|
{
|
||||||
return (hook && DerivationGoal::isReadDesc(fd)) ||
|
return (hook && DerivationGoal::isReadDesc(fd)) ||
|
||||||
(!hook && fd == builder->builderOut.get());
|
(!hook && builder && fd == builder->builderOut.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,24 @@ struct DerivationBuilderParams
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The derivation stored at drvPath.
|
* The derivation stored at drvPath.
|
||||||
*
|
|
||||||
* @todo Remove double indirection by delaying when this is
|
|
||||||
* initialized.
|
|
||||||
*/
|
*/
|
||||||
const std::unique_ptr<Derivation> & drv;
|
const Derivation & drv;
|
||||||
|
|
||||||
const std::unique_ptr<StructuredAttrs> & parsedDrv;
|
/**
|
||||||
const std::unique_ptr<DerivationOptions> & drvOptions;
|
* The "structured attrs" of `drv`, if it has them.
|
||||||
|
*
|
||||||
|
* @todo this should be part of `Derivation`.
|
||||||
|
*
|
||||||
|
* @todo this should be renamed from `parsedDrv`.
|
||||||
|
*/
|
||||||
|
const StructuredAttrs * parsedDrv;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The derivation options of `drv`.
|
||||||
|
*
|
||||||
|
* @todo this should be part of `Derivation`.
|
||||||
|
*/
|
||||||
|
const DerivationOptions & drvOptions;
|
||||||
|
|
||||||
// The remainder is state held during the build.
|
// The remainder is state held during the build.
|
||||||
|
|
||||||
|
@ -52,9 +62,9 @@ struct DerivationBuilderParams
|
||||||
const StorePath & drvPath,
|
const StorePath & drvPath,
|
||||||
const BuildMode & buildMode,
|
const BuildMode & buildMode,
|
||||||
BuildResult & buildResult,
|
BuildResult & buildResult,
|
||||||
const std::unique_ptr<Derivation> & drv,
|
const Derivation & drv,
|
||||||
const std::unique_ptr<StructuredAttrs> & parsedDrv,
|
const StructuredAttrs * parsedDrv,
|
||||||
const std::unique_ptr<DerivationOptions> & drvOptions,
|
const DerivationOptions & drvOptions,
|
||||||
const StorePathSet & inputPaths,
|
const StorePathSet & inputPaths,
|
||||||
std::map<std::string, InitialOutput> & initialOutputs)
|
std::map<std::string, InitialOutput> & initialOutputs)
|
||||||
: drvPath{drvPath}
|
: drvPath{drvPath}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue