Skip to content

Commit 0f985fe

Browse files
authored
Merge pull request #13138 from NixOS/register-builtin-builders
Register builtin builders
2 parents 6fdb170 + 1479305 commit 0f985fe

File tree

6 files changed

+64
-54
lines changed

6 files changed

+64
-54
lines changed

src/libstore/builtins/buildenv.cc

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "nix/store/builtins/buildenv.hh"
2+
#include "nix/store/builtins.hh"
23
#include "nix/store/derivations.hh"
34
#include "nix/util/signals.hh"
45

@@ -166,17 +167,15 @@ void buildProfile(const Path & out, Packages && pkgs)
166167
debug("created %d symlinks in user environment", state.symlinks);
167168
}
168169

169-
void builtinBuildenv(
170-
const BasicDerivation & drv,
171-
const std::map<std::string, Path> & outputs)
170+
static void builtinBuildenv(const BuiltinBuilderContext & ctx)
172171
{
173172
auto getAttr = [&](const std::string & name) {
174-
auto i = drv.env.find(name);
175-
if (i == drv.env.end()) throw Error("attribute '%s' missing", name);
173+
auto i = ctx.drv.env.find(name);
174+
if (i == ctx.drv.env.end()) throw Error("attribute '%s' missing", name);
176175
return i->second;
177176
};
178177

179-
auto out = outputs.at("out");
178+
auto out = ctx.outputs.at("out");
180179
createDirs(out);
181180

182181
/* Convert the stuff we get from the environment back into a
@@ -203,4 +202,6 @@ void builtinBuildenv(
203202
createSymlink(getAttr("manifest"), out + "/manifest.nix");
204203
}
205204

205+
static RegisterBuiltinBuilder registerBuildenv("buildenv", builtinBuildenv);
206+
206207
}

src/libstore/builtins/fetchurl.cc

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,29 @@
66

77
namespace nix {
88

9-
void builtinFetchurl(
10-
const BasicDerivation & drv,
11-
const std::map<std::string, Path> & outputs,
12-
const std::string & netrcData,
13-
const std::string & caFileData)
9+
static void builtinFetchurl(const BuiltinBuilderContext & ctx)
1410
{
1511
/* Make the host's netrc data available. Too bad curl requires
1612
this to be stored in a file. It would be nice if we could just
1713
pass a pointer to the data. */
18-
if (netrcData != "") {
14+
if (ctx.netrcData != "") {
1915
settings.netrcFile = "netrc";
20-
writeFile(settings.netrcFile, netrcData, 0600);
16+
writeFile(settings.netrcFile, ctx.netrcData, 0600);
2117
}
2218

2319
settings.caFile = "ca-certificates.crt";
24-
writeFile(settings.caFile, caFileData, 0600);
20+
writeFile(settings.caFile, ctx.caFileData, 0600);
2521

26-
auto out = get(drv.outputs, "out");
22+
auto out = get(ctx.drv.outputs, "out");
2723
if (!out)
2824
throw Error("'builtin:fetchurl' requires an 'out' output");
2925

30-
if (!(drv.type().isFixed() || drv.type().isImpure()))
26+
if (!(ctx.drv.type().isFixed() || ctx.drv.type().isImpure()))
3127
throw Error("'builtin:fetchurl' must be a fixed-output or impure derivation");
3228

33-
auto storePath = outputs.at("out");
34-
auto mainUrl = drv.env.at("url");
35-
bool unpack = getOr(drv.env, "unpack", "") == "1";
29+
auto storePath = ctx.outputs.at("out");
30+
auto mainUrl = ctx.drv.env.at("url");
31+
bool unpack = getOr(ctx.drv.env, "unpack", "") == "1";
3632

3733
/* Note: have to use a fresh fileTransfer here because we're in
3834
a forked process. */
@@ -56,8 +52,8 @@ void builtinFetchurl(
5652
else
5753
writeFile(storePath, *source);
5854

59-
auto executable = drv.env.find("executable");
60-
if (executable != drv.env.end() && executable->second == "1") {
55+
auto executable = ctx.drv.env.find("executable");
56+
if (executable != ctx.drv.env.end() && executable->second == "1") {
6157
if (chmod(storePath.c_str(), 0755) == -1)
6258
throw SysError("making '%1%' executable", storePath);
6359
}
@@ -79,4 +75,6 @@ void builtinFetchurl(
7975
fetch(mainUrl);
8076
}
8177

78+
static RegisterBuiltinBuilder registerFetchurl("fetchurl", builtinFetchurl);
79+
8280
}

src/libstore/builtins/unpack-channel.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,15 @@
33

44
namespace nix {
55

6-
void builtinUnpackChannel(
7-
const BasicDerivation & drv,
8-
const std::map<std::string, Path> & outputs)
6+
static void builtinUnpackChannel(const BuiltinBuilderContext & ctx)
97
{
108
auto getAttr = [&](const std::string & name) -> const std::string & {
11-
auto i = drv.env.find(name);
12-
if (i == drv.env.end()) throw Error("attribute '%s' missing", name);
9+
auto i = ctx.drv.env.find(name);
10+
if (i == ctx.drv.env.end()) throw Error("attribute '%s' missing", name);
1311
return i->second;
1412
};
1513

16-
std::filesystem::path out{outputs.at("out")};
14+
std::filesystem::path out{ctx.outputs.at("out")};
1715
auto & channelName = getAttr("channelName");
1816
auto & src = getAttr("src");
1917

@@ -42,4 +40,6 @@ void builtinUnpackChannel(
4240
}
4341
}
4442

43+
static RegisterBuiltinBuilder registerUnpackChannel("unpack-channel", builtinUnpackChannel);
44+
4545
}

src/libstore/include/nix/store/builtins.hh

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,30 @@
55

66
namespace nix {
77

8-
// TODO: make pluggable.
9-
void builtinFetchurl(
10-
const BasicDerivation & drv,
11-
const std::map<std::string, Path> & outputs,
12-
const std::string & netrcData,
13-
const std::string & caFileData);
14-
15-
void builtinUnpackChannel(
16-
const BasicDerivation & drv,
17-
const std::map<std::string, Path> & outputs);
8+
struct BuiltinBuilderContext
9+
{
10+
const BasicDerivation & drv;
11+
std::map<std::string, Path> outputs;
12+
std::string netrcData;
13+
std::string caFileData;
14+
Path tmpDirInSandbox;
15+
};
16+
17+
using BuiltinBuilder = std::function<void(const BuiltinBuilderContext &)>;
18+
19+
struct RegisterBuiltinBuilder
20+
{
21+
typedef std::map<std::string, BuiltinBuilder> BuiltinBuilders;
22+
23+
static BuiltinBuilders & builtinBuilders() {
24+
static BuiltinBuilders builders;
25+
return builders;
26+
}
27+
28+
RegisterBuiltinBuilder(const std::string & name, BuiltinBuilder && fun)
29+
{
30+
builtinBuilders().insert_or_assign(name, std::move(fun));
31+
}
32+
};
1833

1934
}

src/libstore/include/nix/store/builtins/buildenv.hh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,4 @@ typedef std::vector<Package> Packages;
4545

4646
void buildProfile(const Path & out, Packages && pkgs);
4747

48-
void builtinBuildenv(
49-
const BasicDerivation & drv,
50-
const std::map<std::string, Path> & outputs);
51-
5248
}

src/libstore/unix/build/derivation-builder.cc

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,15 +1861,18 @@ void DerivationBuilderImpl::runChild()
18611861
/* Make the contents of netrc and the CA certificate bundle
18621862
available to builtin:fetchurl (which may run under a
18631863
different uid and/or in a sandbox). */
1864-
std::string netrcData;
1865-
std::string caFileData;
1864+
BuiltinBuilderContext ctx{
1865+
.drv = drv,
1866+
.tmpDirInSandbox = tmpDirInSandbox,
1867+
};
1868+
18661869
if (drv.isBuiltin() && drv.builder == "builtin:fetchurl") {
18671870
try {
1868-
netrcData = readFile(settings.netrcFile);
1871+
ctx.netrcData = readFile(settings.netrcFile);
18691872
} catch (SystemError &) { }
18701873

18711874
try {
1872-
caFileData = readFile(settings.caFile);
1875+
ctx.caFileData = readFile(settings.caFile);
18731876
} catch (SystemError &) { }
18741877
}
18751878

@@ -2290,19 +2293,16 @@ void DerivationBuilderImpl::runChild()
22902293
try {
22912294
logger = makeJSONLogger(getStandardError());
22922295

2293-
std::map<std::string, Path> outputs;
22942296
for (auto & e : drv.outputs)
2295-
outputs.insert_or_assign(e.first,
2297+
ctx.outputs.insert_or_assign(e.first,
22962298
store.printStorePath(scratchOutputs.at(e.first)));
22972299

2298-
if (drv.builder == "builtin:fetchurl")
2299-
builtinFetchurl(drv, outputs, netrcData, caFileData);
2300-
else if (drv.builder == "builtin:buildenv")
2301-
builtinBuildenv(drv, outputs);
2302-
else if (drv.builder == "builtin:unpack-channel")
2303-
builtinUnpackChannel(drv, outputs);
2300+
std::string builtinName = drv.builder.substr(8);
2301+
assert(RegisterBuiltinBuilder::builtinBuilders);
2302+
if (auto builtin = get(RegisterBuiltinBuilder::builtinBuilders(), builtinName))
2303+
(*builtin)(ctx);
23042304
else
2305-
throw Error("unsupported builtin builder '%1%'", drv.builder.substr(8));
2305+
throw Error("unsupported builtin builder '%1%'", builtinName);
23062306
_exit(0);
23072307
} catch (std::exception & e) {
23082308
writeFull(STDERR_FILENO, e.what() + std::string("\n"));

0 commit comments

Comments
 (0)