forked from lix-project/lix
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.
This commit is contained in:
parent
eda2f36c2a
commit
0a2bee307b
|
@ -12,7 +12,6 @@ in rec {
|
||||||
tar = "@tar@";
|
tar = "@tar@";
|
||||||
tarFlags = "@tarFlags@";
|
tarFlags = "@tarFlags@";
|
||||||
tr = "@tr@";
|
tr = "@tr@";
|
||||||
curl = "@curl@";
|
|
||||||
nixBinDir = fromEnv "NIX_BIN_DIR" "@bindir@";
|
nixBinDir = fromEnv "NIX_BIN_DIR" "@bindir@";
|
||||||
nixPrefix = "@prefix@";
|
nixPrefix = "@prefix@";
|
||||||
|
|
||||||
|
|
|
@ -5,20 +5,9 @@ with import <nix/config.nix>;
|
||||||
assert (outputHash != "" && outputHashAlgo != "")
|
assert (outputHash != "" && outputHashAlgo != "")
|
||||||
|| md5 != "" || sha1 != "" || sha256 != "";
|
|| 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 {
|
derivation {
|
||||||
name = baseNameOf (toString url);
|
name = baseNameOf (toString url);
|
||||||
builder = shell;
|
builder = "builtin:fetchurl";
|
||||||
args = [ "-e" builder ];
|
|
||||||
|
|
||||||
# New-style output content requirements.
|
# New-style output content requirements.
|
||||||
outputHashAlgo = if outputHashAlgo != "" then outputHashAlgo else
|
outputHashAlgo = if outputHashAlgo != "" then outputHashAlgo else
|
||||||
|
@ -39,6 +28,4 @@ derivation {
|
||||||
# by definition pure.
|
# by definition pure.
|
||||||
"http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy"
|
"http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy"
|
||||||
];
|
];
|
||||||
|
|
||||||
inherit chrootDeps;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ libexpr_SOURCES := $(wildcard $(d)/*.cc) $(d)/lexer-tab.cc $(d)/parser-tab.cc
|
||||||
|
|
||||||
libexpr_LIBS = libutil libstore libformat
|
libexpr_LIBS = libutil libstore libformat
|
||||||
|
|
||||||
libexpr_LDFLAGS = -ldl -lcurl
|
libexpr_LDFLAGS = -ldl
|
||||||
|
|
||||||
# The dependency on libgc must be propagated (i.e. meaning that
|
# The dependency on libgc must be propagated (i.e. meaning that
|
||||||
# programs/libraries that use libexpr must explicitly pass -lgc),
|
# programs/libraries that use libexpr must explicitly pass -lgc),
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
#include "archive.hh"
|
#include "archive.hh"
|
||||||
#include "affinity.hh"
|
#include "affinity.hh"
|
||||||
|
#include "builtins.hh"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <sstream>
|
#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()
|
void DerivationGoal::tryToBuild()
|
||||||
{
|
{
|
||||||
trace("trying to build");
|
trace("trying to build");
|
||||||
|
@ -2139,7 +2146,7 @@ void DerivationGoal::startBuilder()
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ProcessOptions options;
|
ProcessOptions options;
|
||||||
options.allowVfork = !buildUser.enabled();
|
options.allowVfork = !buildUser.enabled() && !isBuiltin(*drv);
|
||||||
pid = startProcess([&]() {
|
pid = startProcess([&]() {
|
||||||
runChild();
|
runChild();
|
||||||
}, options);
|
}, options);
|
||||||
|
@ -2386,7 +2393,9 @@ void DerivationGoal::runChild()
|
||||||
const char *builder = "invalid";
|
const char *builder = "invalid";
|
||||||
|
|
||||||
string sandboxProfile;
|
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 */
|
/* Lots and lots and lots of file functions freak out if they can't stat their full ancestry */
|
||||||
PathSet ancestry;
|
PathSet ancestry;
|
||||||
|
|
||||||
|
@ -2413,7 +2422,6 @@ void DerivationGoal::runChild()
|
||||||
for (auto & i : inputPaths)
|
for (auto & i : inputPaths)
|
||||||
dirsInChroot[i] = i;
|
dirsInChroot[i] = i;
|
||||||
|
|
||||||
|
|
||||||
/* TODO: we should factor out the policy cleanly, so we don't have to repeat the constants every time... */
|
/* TODO: we should factor out the policy cleanly, so we don't have to repeat the constants every time... */
|
||||||
sandboxProfile += "(version 1)\n";
|
sandboxProfile += "(version 1)\n";
|
||||||
|
|
||||||
|
@ -2517,6 +2525,20 @@ void DerivationGoal::runChild()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute the program. This should not return. */
|
/* 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());
|
execve(builder, stringsToCharPtrs(args).data(), stringsToCharPtrs(envStrs).data());
|
||||||
|
|
||||||
throw SysError(format("executing ‘%1%’") % drv->builder);
|
throw SysError(format("executing ‘%1%’") % drv->builder);
|
||||||
|
|
24
src/libstore/builtins.cc
Normal file
24
src/libstore/builtins.cc
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
9
src/libstore/builtins.hh
Normal file
9
src/libstore/builtins.hh
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "derivations.hh"
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
void builtinFetchurl(const BasicDerivation & drv);
|
||||||
|
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ libstore_SOURCES := $(wildcard $(d)/*.cc)
|
||||||
|
|
||||||
libstore_LIBS = libutil libformat
|
libstore_LIBS = libutil libformat
|
||||||
|
|
||||||
libstore_LDFLAGS = -lsqlite3 -lbz2
|
libstore_LDFLAGS = -lsqlite3 -lbz2 -lcurl
|
||||||
|
|
||||||
ifeq ($(OS), SunOS)
|
ifeq ($(OS), SunOS)
|
||||||
libstore_LDFLAGS += -lsocket
|
libstore_LDFLAGS += -lsocket
|
||||||
|
|
Loading…
Reference in a new issue