Hey
I am trying to write a derivation for a proprietary image processing program called PixInsight. It has a complex runtime (many X11 libraries, libGL, a lot of network, audio, video libs). Next to huge amounts of binaries, there are also many Javascript and bash files and I basically gave up on patching all binaries and scripts and I am OK with using buildFHSUserEnv. However, there is an installer (another C++ binary), which does a lot of magic. I wasn’t successfull in reverse engineering everything it does and can therefore not replicate its behaviour. Not running the installer properly, leads to no usable installation/directory structure. Unfortunately the installer strictly checks for being executed by root, as it installs into /opt, /bin, /usr/share/ by default. All these paths can be changed (and I want to put them into $out) by command line options, but the requirement for root cannot be circumvented. I’ve tried to fake root by calling unshare in the installPhase, but this does not seem to be possible. I’ve also tried proot with no success. It is of course possible that I am doing something wrong, though.
Does anyone have an idea how to execute a binary installer, which cecks for being called by root, in the build sandbox?
You could try to figure out what the installer is checking by using ltrace.
If it is using a library call (i.e. getuid()) to check for root, then you could write a shared library, which you LD_PRELOAD, to change the return value of the library call. Example: https://www.sweharris.org/post/2017-03-05-ld-preload/
To my surprise this fails with no error message in the installPhase:
building '/nix/store/hir661djlvcd9x3zm4cw7psfj3znny9i-pixinsight-1.8.8-12.drv'...
qtPreHook
unpacking sources
unpacking source archive /nix/store/p5n8ziabj88p9dxwnwml7yn778w77rqh-PI-linux-x64-1.8.8-12-20211229-c.tar.xz
source root is .
setting SOURCE_DATE_EPOCH to timestamp 1640818872 of file ./installer
patching sources
glibPreInstallPhase
installing
build failed in installPhase with exit code 1
I am then attaching with cntr:
> cntr attach -t command cntr-/nix/store/i93i6mz9k60iscii9r4vkmmxcrq83fy0-pixinsight-1.8.8-12
> cd build
> unshare -r ./installer --help
unshare: unshare failed: Operation not permitted
Alternatively with proot -0 ./installer --help nix-build fails the same way. However, the proot command is not available when attaching with cntr.
The idea with LD_PRELOAD is very interesting. I am not very experienced with C/C++ and ltrace, but ltrace ./installer |& grep uid actually gives a getuid() = 9038, so this might actually be an alternative option.
strace said, that the installer is trying to get tty setting (ioctl with TCGETS), which fails as there’s no tty. script from util-linux can solve the problem:
You could also have just used runInLinuxVM. It’s very slightly slower since it has to boot up nixos, and it requires you to have linux Nix build machines that support KVM. But it would work quite well if these aren’t issues for you.
Basically it starts a VM, and replaces init with a script that calls does a bit of setup and calls your builder. All using a virtfs file system, so it doesn’t require huge disk image.
Because the root fs in the VM is writable IIRC, and your builder gets run as root. So you do your root stuff and move it to $out, which corresponds to the actual out on the host.
Sure, can do. I am not so sure how helpful this is to others, as this is proprietary software and quite specific to astrophotography, but if you think it is useful, I will open a PR and ping you for the review.
Namespaces actually work fine. I can execute unshare properly in a normal shell. Meanwhile I figured out that it actually also works in the build sandbox. The second problem that @bartsch pointed out (the ioctl call) actually prevented it from working. Interestingly unshare only fails when attaching with cntr to the breakpointHook. I have no idea why, though.
Oh very nice. I am surprised to find such overlaps in the NixOS community. With @markuskowa I was already very lucky to find someone else doing quantum chemistry
Does PixInsight work nicely for you so far in Nix? I will try to migrate my equipment control PC from Debian to NixOS in July probably and see if INDI in NixOS works nicely. Feel free to shoot me a PM if you like.