From 09dc1d8ad625b9a1d5b89593b184d316837ba1cc Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Tue, 9 Apr 2019 18:19:04 +0200 Subject: build-support/build-sandbox: add support for mounting /nix Enables us to run nix *inside* of a sandbox. We have to mount the whole store, because otherwise realized store paths built inside of the sandbox are not accessible. --- pkgs/build-support/build-sandbox/default.nix | 42 ++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 12 deletions(-) (limited to 'pkgs/build-support/build-sandbox/default.nix') diff --git a/pkgs/build-support/build-sandbox/default.nix b/pkgs/build-support/build-sandbox/default.nix index 66797268..4e5cffe9 100644 --- a/pkgs/build-support/build-sandbox/default.nix +++ b/pkgs/build-support/build-sandbox/default.nix @@ -11,6 +11,10 @@ let pathsRuntimeVars = paths.runtimeVars or []; # Mount a dash shell in /bin/sh inside the chroot. allowBinSh = attrs.allowBinSh or false; + # Enable nix builds from within the sandbox. + # Has to write the full nix store to make the outputs accessible. + # TODO: get rid of nix & pkg-config if this is enabled (in the Makefile) + fullNixStore = attrs.fullNixStore or false; # Create code snippets for params.c to add extra_mount() calls. mkExtraMountParams = isRequired: lib.concatMapStringsSep "\n" (extra: let @@ -26,11 +30,13 @@ in stdenv.mkDerivation ({ inherit drv; + # writes files "sandbox-*" to the builder (see nix manual) exportReferencesGraph = [ "sandbox-closure" drv ] ++ lib.optionals allowBinSh [ "sandbox-binsh" dash ]; configurePhase = '' + # Reads the dependency closures and does … something? TODO: explain runtimeDeps="$(sed -ne ' p; n; n @@ -52,25 +58,36 @@ in stdenv.mkDerivation ({ echo '#include "setup.h"' > params.c echo 'bool setup_app_paths(void) {' >> params.c - for dep in $runtimeDeps; do - echo 'if (!bind_mount("'"$dep"'", true, true, true)) return false;' \ + ${if fullNixStore then '' + # /nix/var needs to be writable for nix to work inside the sandbox + echo 'if (!bind_mount("/nix/var", false, true, true)) return false;' \ + >> params.c + echo 'if (!bind_mount("/nix/store", true, true, true)) return false;' \ >> params.c - done + + '' else '' + for dep in $runtimeDeps; do + echo 'if (!bind_mount("'"$dep"'", true, true, true)) return false;' \ + >> params.c + done + ''} ${mkExtraMountParams true pathsRequired} ${mkExtraMountParams false pathsWanted} echo 'return true; }' >> params.c - echo 'bool mount_runtime_path_vars(struct query_state *qs) {' >> params.c + ${lib.optionalString (!fullNixStore) '' + echo 'bool mount_runtime_path_vars(struct query_state *qs) {' >> params.c - ${lib.concatMapStringsSep "\n" (pathvar: let - escaped = lib.escapeShellArg (lib.escape ["\\" "\""] pathvar); - fun = "mount_from_path_var"; - result = "echo 'if (!${fun}(qs, \"'${escaped}'\")) return false;'"; - in "${result} >> params.c") pathsRuntimeVars} + ${lib.concatMapStringsSep "\n" (pathvar: let + escaped = lib.escapeShellArg (lib.escape ["\\" "\""] pathvar); + fun = "mount_from_path_var"; + result = "echo 'if (!${fun}(qs, \"'${escaped}'\")) return false;'"; + in "${result} >> params.c") pathsRuntimeVars} - echo 'return true; }' >> params.c + echo 'return true; }' >> params.c + ''} ''; postInstall = '' @@ -82,8 +99,9 @@ in stdenv.mkDerivation ({ ''; nativeBuildInputs = [ pkgconfig ]; - buildInputs = [ nix boost ]; + buildInputs = [ boost nix ]; makeFlags = [ "BINDIR=${drv}/bin" ] - ++ lib.optional allowBinSh "BINSH_EXECUTABLE=${dash}/bin/dash"; + ++ lib.optional allowBinSh "BINSH_EXECUTABLE=${dash}/bin/dash" + ++ lib.optional fullNixStore "FULL_NIX_STORE=1"; } // removeAttrs attrs [ "paths" "allowBinSh" ]) -- cgit 1.4.1