libstore: add capnp build request parameter struct to builders
there's nothing in here yet, we'll add that piece by piece. Change-Id: Ib276d9e8281bb08013197db0f2bbfd8eec76b5ce
This commit is contained in:
@@ -33,7 +33,9 @@
|
||||
#include "lix/libutil/thread-name.hh"
|
||||
#include "lix/libstore/platform/linux.hh"
|
||||
#include "lix/libstore/path-tree.hh"
|
||||
#include "request.capnp.h"
|
||||
|
||||
#include <capnp/message.h>
|
||||
#include <cstddef>
|
||||
#include <dirent.h>
|
||||
#include <exception>
|
||||
@@ -921,8 +923,14 @@ try {
|
||||
builder = drv->builder;
|
||||
}
|
||||
|
||||
capnp::MallocMessageBuilder requestBuilder;
|
||||
|
||||
auto request = requestBuilder.initRoot<build::Request>();
|
||||
|
||||
fillBuilderConfig(request);
|
||||
|
||||
/* Fork a child to build the package. */
|
||||
pg = ProcessGroup{startChild(builder, envStrs, args, std::move(builderOut))};
|
||||
pg = ProcessGroup{startChild(request.asReader(), builder, envStrs, args, std::move(builderOut))};
|
||||
|
||||
/* Check if setting up the build environment failed. */
|
||||
std::vector<std::string> msgs;
|
||||
@@ -956,7 +964,11 @@ try {
|
||||
}
|
||||
|
||||
Pid LocalDerivationGoal::startChild(
|
||||
const Path & builder, const Strings & envStrs, const Strings & args, AutoCloseFD logPTY
|
||||
build::Request::Reader request,
|
||||
const Path & builder,
|
||||
const Strings & envStrs,
|
||||
const Strings & args,
|
||||
AutoCloseFD logPTY
|
||||
)
|
||||
{
|
||||
return startProcess([&]() {
|
||||
@@ -964,7 +976,7 @@ Pid LocalDerivationGoal::startChild(
|
||||
throw SysError("failed to redirect build output to log file");
|
||||
}
|
||||
closeOnExec(STDERR_FILENO, false);
|
||||
runChild(builder, envStrs, args);
|
||||
runChild(request, builder, envStrs, args);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1245,7 +1257,9 @@ static void closeExtraFDs()
|
||||
}
|
||||
}
|
||||
|
||||
void LocalDerivationGoal::runChild(const Path & builder, const Strings & envStrs, const Strings & args)
|
||||
void LocalDerivationGoal::runChild(
|
||||
build::Request::Reader request, const Path & builder, const Strings & envStrs, const Strings & args
|
||||
)
|
||||
{
|
||||
/* Warning: in the child we should absolutely not make any SQLite
|
||||
calls! */
|
||||
@@ -1286,7 +1300,7 @@ void LocalDerivationGoal::runChild(const Path & builder, const Strings & envStrs
|
||||
throw SysError("cannot dup null device into stdin");
|
||||
}
|
||||
|
||||
const bool setUser = prepareChildSetup();
|
||||
const bool setUser = prepareChildSetup(request);
|
||||
|
||||
if (sys::chdir(tmpDirInSandbox) == -1) {
|
||||
throw SysError("changing into '%1%'", tmpDir);
|
||||
@@ -1328,7 +1342,7 @@ void LocalDerivationGoal::runChild(const Path & builder, const Strings & envStrs
|
||||
throw SysError("setuid failed");
|
||||
}
|
||||
|
||||
finishChildSetup();
|
||||
finishChildSetup(request);
|
||||
|
||||
/* Indicate that we managed to set up the build environment. */
|
||||
writeFull(STDERR_FILENO, std::string("\2\n"));
|
||||
@@ -1336,7 +1350,7 @@ void LocalDerivationGoal::runChild(const Path & builder, const Strings & envStrs
|
||||
sendException = false;
|
||||
|
||||
/* Execute the program. This should not return. */
|
||||
execBuilder(builder, args, envStrs);
|
||||
execBuilder(request, builder, args, envStrs);
|
||||
|
||||
throw SysError("executing '%1%'", drv->builder);
|
||||
|
||||
@@ -1352,7 +1366,9 @@ void LocalDerivationGoal::runChild(const Path & builder, const Strings & envStrs
|
||||
}
|
||||
}
|
||||
|
||||
void LocalDerivationGoal::execBuilder(std::string builder, Strings args, Strings envStrs)
|
||||
void LocalDerivationGoal::execBuilder(
|
||||
build::Request::Reader request, std::string builder, Strings args, Strings envStrs
|
||||
)
|
||||
{
|
||||
sys::execve(builder, args, envStrs);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
///@file
|
||||
|
||||
#include "lix/libstore/build/derivation-goal.hh"
|
||||
#include "lix/libstore/build/request.capnp.h"
|
||||
#include "lix/libstore/local-store.hh"
|
||||
#include "lix/libutil/error.hh"
|
||||
#include "lix/libutil/processes.hh"
|
||||
@@ -209,7 +210,9 @@ struct LocalDerivationGoal : public DerivationGoal
|
||||
/**
|
||||
* Run the builder's process.
|
||||
*/
|
||||
void runChild(const Path & builder, const Strings & envStrs, const Strings & args);
|
||||
void runChild(
|
||||
build::Request::Reader request, const Path & builder, const Strings & envStrs, const Strings & args
|
||||
);
|
||||
|
||||
/**
|
||||
* Check that the derivation outputs all exist and register them
|
||||
@@ -291,12 +294,19 @@ protected:
|
||||
* Create a new process that runs `openSlave` and `runChild`
|
||||
* On some platforms this process is created with sandboxing flags.
|
||||
*/
|
||||
virtual Pid
|
||||
startChild(const Path & builder, const Strings & envStrs, const Strings & args, AutoCloseFD logPTY);
|
||||
virtual Pid startChild(
|
||||
build::Request::Reader request,
|
||||
const Path & builder,
|
||||
const Strings & envStrs,
|
||||
const Strings & args,
|
||||
AutoCloseFD logPTY
|
||||
);
|
||||
|
||||
kj::Promise<Result<WorkResult>> handleRawChild() noexcept;
|
||||
kj::Promise<Result<std::optional<WorkResult>>> handleRawChildStream() noexcept;
|
||||
|
||||
virtual void fillBuilderConfig(build::Request::Builder request) {}
|
||||
|
||||
/**
|
||||
* Prepare the sandbox. Currently only used on linux to build the sandbox namespace,
|
||||
* write configuration files inside it, and to set up networking with pasta enabled.
|
||||
@@ -304,7 +314,7 @@ protected:
|
||||
* `false` if this step has changed our credentials to the build user/group already.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
virtual bool prepareChildSetup()
|
||||
virtual bool prepareChildSetup(build::Request::Reader request)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -312,7 +322,7 @@ protected:
|
||||
/**
|
||||
* Finish sandbox setup and prepare for actually executing the builder processes.
|
||||
*/
|
||||
virtual void finishChildSetup() {}
|
||||
virtual void finishChildSetup(build::Request::Reader request) {}
|
||||
|
||||
/**
|
||||
* Create a special accessor that can access paths that were built within the sandbox's
|
||||
@@ -327,7 +337,8 @@ protected:
|
||||
* Execute the builder, replacing the current process.
|
||||
* Generally this means an `execve` call.
|
||||
*/
|
||||
virtual void execBuilder(std::string builder, Strings args, Strings envStrs);
|
||||
virtual void
|
||||
execBuilder(build::Request::Reader request, std::string builder, Strings args, Strings envStrs);
|
||||
|
||||
/**
|
||||
* Whether derivation can be built on current platform with `uid-range` feature
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
libstore_rpc += custom_target(
|
||||
command : [
|
||||
capnpc_wrapper,
|
||||
'--language=c++',
|
||||
'--src-prefix=@CURRENT_SOURCE_DIR@',
|
||||
'--outdir=@OUTDIR@',
|
||||
'--depfile=@DEPFILE@',
|
||||
'-I@SOURCE_ROOT@',
|
||||
'@INPUT@',
|
||||
],
|
||||
input : files(
|
||||
# keep-sorted start
|
||||
'hook-instance.capnp',
|
||||
# keep-sorted end
|
||||
),
|
||||
output : [
|
||||
'@PLAINNAME@.h',
|
||||
'@PLAINNAME@.c++',
|
||||
],
|
||||
depfile : '@PLAINNAME@.d',
|
||||
build_capnp_files = files(
|
||||
# keep-sorted start
|
||||
'hook-instance.capnp',
|
||||
'request.capnp',
|
||||
# keep-sorted end
|
||||
)
|
||||
|
||||
foreach infile : build_capnp_files
|
||||
libstore_rpc += custom_target(
|
||||
command : [
|
||||
capnpc_wrapper,
|
||||
'--language=c++',
|
||||
'--src-prefix=@CURRENT_SOURCE_DIR@',
|
||||
'--outdir=@OUTDIR@',
|
||||
'--depfile=@DEPFILE@',
|
||||
'-I@SOURCE_ROOT@',
|
||||
'@INPUT@',
|
||||
],
|
||||
input : infile,
|
||||
output : [
|
||||
'@PLAINNAME@.h',
|
||||
'@PLAINNAME@.c++',
|
||||
],
|
||||
depfile : '@PLAINNAME@.d',
|
||||
)
|
||||
endforeach
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
@0xa7f090bdc7816f8f;
|
||||
|
||||
using Cxx = import "/capnp/c++.capnp";
|
||||
$Cxx.namespace("nix::build");
|
||||
|
||||
struct Request {
|
||||
}
|
||||
@@ -371,7 +371,7 @@ void DarwinLocalDerivationGoal::prepareSandbox()
|
||||
debug("Generated sandbox profile: %1%", sandboxProfile);
|
||||
}
|
||||
|
||||
void DarwinLocalDerivationGoal::finishChildSetup()
|
||||
void DarwinLocalDerivationGoal::finishChildSetup(build::Request::Reader request)
|
||||
{
|
||||
bool allowLocalNetworking = parsedDrv->getBoolAttr("__darwinAllowLocalNetworking");
|
||||
|
||||
@@ -405,7 +405,9 @@ void DarwinLocalDerivationGoal::finishChildSetup()
|
||||
}
|
||||
}
|
||||
|
||||
void DarwinLocalDerivationGoal::execBuilder(std::string builder, Strings args, Strings envStrs)
|
||||
void DarwinLocalDerivationGoal::execBuilder(
|
||||
build::Request::Reader request, std::string builder, Strings args, Strings envStrs
|
||||
)
|
||||
{
|
||||
posix_spawnattr_t attrp;
|
||||
|
||||
|
||||
@@ -44,12 +44,13 @@ private:
|
||||
*/
|
||||
void prepareSandbox() override;
|
||||
|
||||
void finishChildSetup() override;
|
||||
void finishChildSetup(build::Request::Reader request) override;
|
||||
|
||||
/**
|
||||
* Set process flags to enter or leave rosetta, then execute the builder
|
||||
*/
|
||||
void execBuilder(std::string builder, Strings args, Strings envStrs) override;
|
||||
void
|
||||
execBuilder(build::Request::Reader request, std::string builder, Strings args, Strings envStrs) override;
|
||||
|
||||
/**
|
||||
* Whether we need to rewrite output hashes.
|
||||
|
||||
@@ -1267,7 +1267,7 @@ static void bindPath(const Path & source, const Path & target, bool optional = f
|
||||
}
|
||||
}
|
||||
|
||||
bool LinuxLocalDerivationGoal::prepareChildSetup()
|
||||
bool LinuxLocalDerivationGoal::prepareChildSetup(build::Request::Reader request)
|
||||
{
|
||||
// Set the NO_NEW_PRIVS prctl flag.
|
||||
// This both makes loading seccomp filters work for unprivileged users,
|
||||
@@ -1551,7 +1551,7 @@ bool LinuxLocalDerivationGoal::prepareChildSetup()
|
||||
return false;
|
||||
}
|
||||
|
||||
void LinuxLocalDerivationGoal::finishChildSetup()
|
||||
void LinuxLocalDerivationGoal::finishChildSetup(build::Request::Reader request)
|
||||
{
|
||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL) == -1) {
|
||||
throw SysError("setting death signal");
|
||||
@@ -1562,12 +1562,16 @@ void LinuxLocalDerivationGoal::finishChildSetup()
|
||||
}
|
||||
|
||||
Pid LinuxLocalDerivationGoal::startChild(
|
||||
const Path & builder, const Strings & envStrs, const Strings & args, AutoCloseFD logPTY
|
||||
build::Request::Reader request,
|
||||
const Path & builder,
|
||||
const Strings & envStrs,
|
||||
const Strings & args,
|
||||
AutoCloseFD logPTY
|
||||
)
|
||||
{
|
||||
// If we're not sandboxing no need to faff about, use the fallback
|
||||
if (!useChroot) {
|
||||
return LocalDerivationGoal::startChild(builder, envStrs, args, std::move(logPTY));
|
||||
return LocalDerivationGoal::startChild(request, builder, envStrs, args, std::move(logPTY));
|
||||
}
|
||||
/* Set up private namespaces for the build:
|
||||
|
||||
@@ -1737,7 +1741,7 @@ Pid LinuxLocalDerivationGoal::startChild(
|
||||
options.cloneFlags =
|
||||
CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWUTS | CLONE_PARENT | SIGCHLD;
|
||||
|
||||
return startProcess([&]() { runChild(builder, envStrs, args); }, options);
|
||||
return startProcess([&]() { runChild(request, builder, envStrs, args); }, options);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,11 @@ private:
|
||||
* create /etc/passwd and /etc/group based on discovered uid/gid
|
||||
*/
|
||||
Pid startChild(
|
||||
const Path & builder, const Strings & envStrs, const Strings & args, AutoCloseFD logPTY
|
||||
build::Request::Reader request,
|
||||
const Path & builder,
|
||||
const Strings & envStrs,
|
||||
const Strings & args,
|
||||
AutoCloseFD logPTY
|
||||
) override;
|
||||
|
||||
/**
|
||||
@@ -94,9 +98,9 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool prepareChildSetup() override;
|
||||
bool prepareChildSetup(build::Request::Reader request) override;
|
||||
|
||||
void finishChildSetup() override;
|
||||
void finishChildSetup(build::Request::Reader request) override;
|
||||
|
||||
std::string rewriteResolvConf(std::string fromHost);
|
||||
|
||||
|
||||
@@ -293,6 +293,7 @@ configdata.set('HAVE_BOEHMGC', boehm.found().to_int())
|
||||
|
||||
boost = dependency('boost', required : true, include_type : 'system')
|
||||
kj = dependency('kj-async', required : true, include_type : 'system')
|
||||
capnp = dependency('capnp', required : true, include_type : 'system')
|
||||
capnp_rpc = dependency('capnp-rpc', required : true, include_type : 'system')
|
||||
|
||||
# cpuid only makes sense on x86_64
|
||||
|
||||
Reference in New Issue
Block a user