aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2015-07-20 04:30:16 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2015-07-20 04:38:46 +0200
commit0a2bee307b20411f5b0dda0c662b1f9bb9e0e131 (patch)
treee0449738da384147f851a2343f8d21ae7591a3e0
parenteda2f36c2ac847e02e871c327e7633693d92cd8d (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.
-rw-r--r--corepkgs/config.nix.in1
-rw-r--r--corepkgs/fetchurl.nix15
-rw-r--r--src/libexpr/local.mk2
-rw-r--r--src/libstore/build.cc28
-rw-r--r--src/libstore/builtins.cc24
-rw-r--r--src/libstore/builtins.hh9
-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.mk2
9 files changed, 61 insertions, 20 deletions
diff --git a/corepkgs/config.nix.in b/corepkgs/config.nix.in
index 8918f4ddd..90e8edbea 100644
--- a/corepkgs/config.nix.in
+++ b/corepkgs/config.nix.in
@@ -12,7 +12,6 @@ in rec {
tar = "@tar@";
tarFlags = "@tarFlags@";
tr = "@tr@";
- curl = "@curl@";
nixBinDir = fromEnv "NIX_BIN_DIR" "@bindir@";
nixPrefix = "@prefix@";
diff --git a/corepkgs/fetchurl.nix b/corepkgs/fetchurl.nix
index 1ce88593c..64d1f121f 100644
--- a/corepkgs/fetchurl.nix
+++ b/corepkgs/fetchurl.nix
@@ -5,20 +5,9 @@ with import <nix/config.nix>;
assert (outputHash != "" && outputHashAlgo != "")
|| md5 != "" || sha1 != "" || sha256 != "";
-let
-
- builder = builtins.toFile "fetchurl.sh"
- (''
- echo "downloading $url into $out"
- ${curl} --fail --location --max-redirs 20 --insecure "$url" > "$out"
- '' + (if executable then "${coreutils}/chmod +x $out" else ""));
-
-in
-
derivation {
name = baseNameOf (toString url);
- builder = shell;
- args = [ "-e" builder ];
+ builder = "builtin:fetchurl";
# New-style output content requirements.
outputHashAlgo = if outputHashAlgo != "" then outputHashAlgo else
@@ -39,6 +28,4 @@ derivation {
# by definition pure.
"http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy"
];
-
- inherit chrootDeps;
}
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