diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2015-07-20 04:30:16 +0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2015-07-20 04:38:46 +0200 |
commit | 0a2bee307b20411f5b0dda0c662b1f9bb9e0e131 (patch) | |
tree | e0449738da384147f851a2343f8d21ae7591a3e0 /src | |
parent | eda2f36c2ac847e02e871c327e7633693d92cd8d (diff) |
Make <nix/fetchurl.nix> a builtin builder
This ensures that 1) the derivation doesn't change when Nix changes;
2) the derivation closure doesn't contain Nix and its dependencies; 3)
we don't have to rely on ugly chroot hacks.
Diffstat (limited to 'src')
-rw-r--r-- | src/libexpr/local.mk | 2 | ||||
-rw-r--r-- | src/libstore/build.cc | 28 | ||||
-rw-r--r-- | src/libstore/builtins.cc | 24 | ||||
-rw-r--r-- | src/libstore/builtins.hh | 9 | ||||
-rw-r--r-- | src/libstore/download.cc (renamed from src/libexpr/download.cc) | 0 | ||||
-rw-r--r-- | src/libstore/download.hh (renamed from src/libexpr/download.hh) | 0 | ||||
-rw-r--r-- | src/libstore/local.mk | 2 |
7 files changed, 60 insertions, 5 deletions
diff --git a/src/libexpr/local.mk b/src/libexpr/local.mk index 35e84980a..4c1f4de19 100644 --- a/src/libexpr/local.mk +++ b/src/libexpr/local.mk @@ -8,7 +8,7 @@ libexpr_SOURCES := $(wildcard $(d)/*.cc) $(d)/lexer-tab.cc $(d)/parser-tab.cc libexpr_LIBS = libutil libstore libformat -libexpr_LDFLAGS = -ldl -lcurl +libexpr_LDFLAGS = -ldl # The dependency on libgc must be propagated (i.e. meaning that # programs/libraries that use libexpr must explicitly pass -lgc), diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 61677d1eb..46d2841dc 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -8,6 +8,7 @@ #include "util.hh" #include "archive.hh" #include "affinity.hh" +#include "builtins.hh" #include <map> #include <sstream> @@ -1269,6 +1270,12 @@ bool substitutesAllowed(const BasicDerivation & drv) } +static bool isBuiltin(const BasicDerivation & drv) +{ + return string(drv.builder, 0, 8) == "builtin:"; +} + + void DerivationGoal::tryToBuild() { trace("trying to build"); @@ -2139,7 +2146,7 @@ void DerivationGoal::startBuilder() #endif { ProcessOptions options; - options.allowVfork = !buildUser.enabled(); + options.allowVfork = !buildUser.enabled() && !isBuiltin(*drv); pid = startProcess([&]() { runChild(); }, options); @@ -2386,7 +2393,9 @@ void DerivationGoal::runChild() const char *builder = "invalid"; string sandboxProfile; - if (useChroot && SANDBOX_ENABLED) { + if (isBuiltin(*drv)) + ; + else if (useChroot && SANDBOX_ENABLED) { /* Lots and lots and lots of file functions freak out if they can't stat their full ancestry */ PathSet ancestry; @@ -2413,7 +2422,6 @@ void DerivationGoal::runChild() for (auto & i : inputPaths) dirsInChroot[i] = i; - /* TODO: we should factor out the policy cleanly, so we don't have to repeat the constants every time... */ sandboxProfile += "(version 1)\n"; @@ -2517,6 +2525,20 @@ void DerivationGoal::runChild() } /* Execute the program. This should not return. */ + if (isBuiltin(*drv)) { + try { + logType = ltFlat; + if (drv->builder == "builtin:fetchurl") + builtinFetchurl(*drv); + else + throw Error(format("unsupported builtin function ‘%1%’") % string(drv->builder, 8)); + _exit(0); + } catch (std::exception & e) { + writeFull(STDERR_FILENO, "error: " + string(e.what()) + "\n"); + _exit(1); + } + } + execve(builder, stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data()); throw SysError(format("executing ‘%1%’") % drv->builder); diff --git a/src/libstore/builtins.cc b/src/libstore/builtins.cc new file mode 100644 index 000000000..97d6cb943 --- /dev/null +++ b/src/libstore/builtins.cc @@ -0,0 +1,24 @@ +#include "builtins.hh" +#include "download.hh" + +namespace nix { + +void builtinFetchurl(const BasicDerivation & drv) +{ + auto url = drv.env.find("url"); + if (url == drv.env.end()) throw Error("attribute ‘url’ missing"); + printMsg(lvlInfo, format("downloading ‘%1%’...") % url->second); + auto data = downloadFile(url->second); // FIXME: show progress + + auto out = drv.env.find("out"); + if (out == drv.env.end()) throw Error("attribute ‘url’ missing"); + writeFile(out->second, data.data); + + auto executable = drv.env.find("out"); + if (executable != drv.env.end() && executable->second == "1") { + if (chmod(out->second.c_str(), 0755) == -1) + throw SysError(format("making ‘%1%’ executable") % out->second); + } +} + +} diff --git a/src/libstore/builtins.hh b/src/libstore/builtins.hh new file mode 100644 index 000000000..4b2431aa0 --- /dev/null +++ b/src/libstore/builtins.hh @@ -0,0 +1,9 @@ +#pragma once + +#include "derivations.hh" + +namespace nix { + +void builtinFetchurl(const BasicDerivation & drv); + +} diff --git a/src/libexpr/download.cc b/src/libstore/download.cc index 9bf3e13aa..9bf3e13aa 100644 --- a/src/libexpr/download.cc +++ b/src/libstore/download.cc diff --git a/src/libexpr/download.hh b/src/libstore/download.hh index 28c9117e4..28c9117e4 100644 --- a/src/libexpr/download.hh +++ b/src/libstore/download.hh diff --git a/src/libstore/local.mk b/src/libstore/local.mk index 771c06753..bf5c256c9 100644 --- a/src/libstore/local.mk +++ b/src/libstore/local.mk @@ -8,7 +8,7 @@ libstore_SOURCES := $(wildcard $(d)/*.cc) libstore_LIBS = libutil libformat -libstore_LDFLAGS = -lsqlite3 -lbz2 +libstore_LDFLAGS = -lsqlite3 -lbz2 -lcurl ifeq ($(OS), SunOS) libstore_LDFLAGS += -lsocket |