diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2015-07-20T02·30+0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2015-07-20T02·38+0200 |
commit | 0a2bee307b20411f5b0dda0c662b1f9bb9e0e131 (patch) | |
tree | e0449738da384147f851a2343f8d21ae7591a3e0 | |
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.
-rw-r--r-- | corepkgs/config.nix.in | 1 | ||||
-rw-r--r-- | corepkgs/fetchurl.nix | 15 | ||||
-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 |
9 files changed, 61 insertions, 20 deletions
diff --git a/corepkgs/config.nix.in b/corepkgs/config.nix.in index 8918f4ddde8d..90e8edbea833 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 1ce88593cff2..64d1f121f81c 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 35e84980a6dd..4c1f4de19187 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 61677d1eb5a2..46d2841dc9e4 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 000000000000..97d6cb943402 --- /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 000000000000..4b2431aa08cf --- /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 9bf3e13aa9da..9bf3e13aa9da 100644 --- a/src/libexpr/download.cc +++ b/src/libstore/download.cc diff --git a/src/libexpr/download.hh b/src/libstore/download.hh index 28c9117e4227..28c9117e4227 100644 --- a/src/libexpr/download.hh +++ b/src/libstore/download.hh diff --git a/src/libstore/local.mk b/src/libstore/local.mk index 771c06753a65..bf5c256c949e 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 |