Using FUSE inside Nix derivation?

Is it possible to use FUSE inside a Nix derivation (it seems not)? If not, is there a workaround?

I’m creating a derivation to build an Redox OS ISO. I’ve gotten pretty far, but Nix fails once it reaches the step to mount the Redox filesystem to fill it files:

redoxfs: opening build/filesystem.bin.partial
redoxfs: opened filesystem on build/filesystem.bin.partial with uuid 07470a8b-2d09-4f05-8a13-ab535028b73c
fuse: device not found, try 'modprobe fuse' first
redoxfs: failed to mount build/filesystem.bin.partial to build/filesystem/: No such file or directory (os error 2)
redoxfs: not able to mount path build/filesystem.bin.partial

It should be possible with namespaces. I believe you just need a Linux kernel >= 4.18 to support mounting FUSE filesystems by unprivileged users inside a user/mount namespace. Try: unshare -m -r

For a while my robotnix project would mount the android source code inside a fuse filesystem, which let me easily fix user/group permissions without requiring me to copy multiple gigabytes of AOSP source every time I wanted to build android. (See: source: Use bind-mounts in user namespace instead of copying · danielfullmer/robotnix@fd892e2 · GitHub )

1 Like

Anyway, it is possible to run qemu VM with a code which would require root.
It is a usual way to create images and there are some helper functions (runInLinuxVM, etc)

AFAIK this isn’t possible by default.

The (only?) problem is that /dev/fuse isn’t available inside of the build sandbox, so I see the following theoretical solution:

  1. Patch Nix: Add /dev/fuse to the list here (maybe that patch could be upstreamed?).
  2. Use the sandbox/sandbox-paths/extra-sandbox-paths Nix option (documentation).

Using extra-sandbox-paths for /dev seems like the easiest solution, but unfortunately any of my ideas will apply to all builds and be required for anyone trying to build your Nix derivation so I’m not sure if it fits your use-case. Something like runInLinuxVM might be more useful (but I haven’t looked into it).

4 Likes

So, I’ve tried building it with /dev/fuse in extra-sandbox-paths — that didn’t work.

nix build .\#default.x86_64-linux.testList --option extra-sandbox-paths '/dev/fuse /etc/mtab'
warning: Git tree '/home/cab/data/forks/logseq-up/other-logseq/nix' is dirty
error: builder for '/nix/store/rinr14m17k0c6d4d77wj062nx1dvvzfl-command-list.drv' failed with exit code 1;
       last 3 log lines:
       > /nix/store/vjs0lps193gd8ih9c0xf8m6hvbvx4qpn-fuse-overlayfs-1.8.2/bin/fuse-overlayfs -o auto_unmount,lowerdir=/nix/store/0lr2x0syf7ywcdbp8ff8czmsx801481v-command-list/layer,workdir=/build/.workdir,upperdir=/build/.layer /nix/store/xqwg3i6pvgxi4bwrzcfnpxm6c7dpqgkv-command-list
       > fusermount3: mount failed: Operation not permitted
       > fuse-overlayfs: cannot mount: Operation not permitted
       For full logs, run 'nix log /nix/store/rinr14m17k0c6d4d77wj062nx1dvvzfl-command-list.drv'.
error: error: 1 dependencies of derivation '/nix/store/c29dd7liaxxa7b06flk3w3rcsbgap9bi-command-list.drv' failed to build

Also I’ve added /etc/mtab.

However, that does seem to remove “try modprobing fuse” error

Here’s the repo I am experimenting on: GitHub - cab404/layernix