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
					
				
					 9 changed files with 61 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -12,7 +12,6 @@ in rec {
 | 
			
		|||
  tar = "@tar@";
 | 
			
		||||
  tarFlags = "@tarFlags@";
 | 
			
		||||
  tr = "@tr@";
 | 
			
		||||
  curl = "@curl@";
 | 
			
		||||
  nixBinDir = fromEnv "NIX_BIN_DIR" "@bindir@";
 | 
			
		||||
  nixPrefix = "@prefix@";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										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_LDFLAGS = -lsqlite3 -lbz2
 | 
			
		||||
libstore_LDFLAGS = -lsqlite3 -lbz2 -lcurl
 | 
			
		||||
 | 
			
		||||
ifeq ($(OS), SunOS)
 | 
			
		||||
	libstore_LDFLAGS += -lsocket
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue