buildFHSUserEnv doesn't work inside sandbox. It can sometimes be useful to build, or unpack something in an environment that has a lot of assumptions (say, self-extracting checksummed executable, or build system that expects FHS-compliant paths).
Given /etc/nixos/configuration.nix containing:
nix.useSandbox = true;
Given example.nix:
{ stdenv, buildFHSUserEnv }:
let
buildEnv = buildFHSUserEnv {
name = "example-build-env";
runScript = "echo hello";
targetPkgs = pkgs: [];
};
in
stdenv.mkDerivation {
name = "example";
unpackPhase = ":";
buildPhase = "${buildEnv}/bin/${buildEnv.name}";
installPhase = "ln -s ${buildEnv} $out";
}
$ nix-build -E "with import <nixpkgs> {}; callPackage ./example.nix {}"
these derivations will be built:
/nix/store/dm11jjsk39lh8lhi8l88pzvvw85d5c3h-example.drv
building path(s) ‘/nix/store/mq3nlfsalghxj87v41yc4wvkm8196mzs-example’
unpacking sources
patching sources
configuring
no configure script, doing nothing
building
/nix/store/iwxs4nwk80arwkvqdjqcy74r34wcg3wl-chroot-user:45:in `block in make_fcall': No such file or directory (Errno::ENOENT)
from /nix/store/iwxs4nwk80arwkvqdjqcy74r34wcg3wl-chroot-user:131:in `block in <main>'
from /nix/store/iwxs4nwk80arwkvqdjqcy74r34wcg3wl-chroot-user:128:in `each'
from /nix/store/iwxs4nwk80arwkvqdjqcy74r34wcg3wl-chroot-user:128:in `<main>'
builder for ‘/nix/store/dm11jjsk39lh8lhi8l88pzvvw85d5c3h-example.drv’ failed with exit code 1
/cc @abbradar
I think at this point you would need to use the vmtools to do this. See e.g. buildRPM.
I have noticed the same. I came up with this simpler FHS environment to run Altera Quartus installer on NixOS with sandbox build:
setup-chroot-and-exec = writeScript "setup-chroot-and-exec"
(''
#!${bash}/bin/sh
chrootdir=chroot # relative to the current directory
mkdir -p "$chrootdir"/host
mkdir -p "$chrootdir"/proc
mkdir -p "$chrootdir"/nix
mkdir -p "$chrootdir"/tmp
mkdir -p "$chrootdir"/dev
mkdir -p "$chrootdir"/lib
mkdir -p "$chrootdir"/lib64
mkdir -p "$chrootdir"/bin
${utillinux}/bin/mount --rbind / "$chrootdir"/host
${utillinux}/bin/mount --rbind /proc "$chrootdir"/proc
${utillinux}/bin/mount --rbind /nix "$chrootdir"/nix
${utillinux}/bin/mount --rbind /tmp "$chrootdir"/tmp
${utillinux}/bin/mount --rbind /dev "$chrootdir"/dev
'' + (if is32bitPackage then ''
${utillinux}/bin/mount --rbind "${glibc_lib32_for_installer}"/lib "$chrootdir"/lib
'' else ''
${utillinux}/bin/mount --rbind "${glibc_lib_for_installer}"/lib64 "$chrootdir"/lib64
'') + ''
${utillinux}/bin/mount --rbind "${bash}"/bin "$chrootdir"/bin
chroot "$chrootdir" "$@"
'');
# buildFHSUserEnv from nixpkgs tries to mount a few directories that are not
# available in sandboxed Nix builds (/sys, /run), hence we have our own
# slimmed down variant.
run-in-fhs-env = writeScript "run-in-fhs-env"
''
#!${bash}/bin/sh
if [ "$*" = "" ]; then
echo "Usage: run-in-fhs-env <COMMAND> [ARGS...]"
exit 1
fi
"${utillinux}/bin/unshare" -r -U -m "${setup-chroot-and-exec}" "$@"
'';
@bjornfor Thanks! This looks nice, and no Ruby dependency.
BTW, just commenting out line 45 in chroot-user script (one that raises the exception) solves the issue. Probably makes sense to mount /run and /sys only if available.
Probably makes sense to mount /run and /sys only if available.
Yes, +1 for working buildFHSUserEnv in sandboxed build.
Most helpful comment
I have noticed the same. I came up with this simpler FHS environment to run Altera Quartus installer on NixOS with sandbox build: