nvm icon indicating copy to clipboard operation
nvm copied to clipboard

Add support for NixOS

Open jim3692 opened this issue 2 years ago • 10 comments

Solves #2065

jim3692 avatar Jan 30 '23 18:01 jim3692

I will have to do some research on how to automate the NixOS compatibility testing. The problem is that it's difficult to properly run Nix in a container. The official Nix Docker image is just Alpine with the Nix package manager.

jim3692 avatar Jan 30 '23 21:01 jim3692

It'd be great to add nixOS to the tests (on github actions please, not travis). Running a docker container would be fine if that can work.

ljharb avatar Jan 30 '23 22:01 ljharb

Trying to match Linux nixos in the output of uname -a turns out to be incorrect. That's the computer's hostname. My laptop just happened to have nixos as its hostname, which is the default.

Based on this thread: https://discourse.nixos.org/t/detect-that-bash-script-is-running-under-nixos/11402 The correct way to detect NixOS is to either check the NAME (or ID) value in /etc/os-release or check whether the directory /etc/NIXOS exists.

However, neither of those exists on the nixos/nix Docker image, making the tests a bit more complicated. After some digging I found that the $BASH variable could provide some info.

  • On NixOS, its default value is /run/current-system/sw/bin/bash
  • On nixos/nix image, its default value is /root/.nix-profile/bin/bash
  • On Arch, its default values is /usr/bin/bash
  • On any Linux system running nix-shell, its value becomes /nix/store/[some hash]-bash-interactive-[version]/bin/bash

I am not sure whether we can rely on that value. It seems too hacky.

Another problem with the nixos/nix image is that it needs to run inside a privileged container, due to nix's sandboxing. The support for privileged containers in Github Actions is also discussed here: https://github.com/actions/container-action/issues/2

jim3692 avatar Jan 31 '23 23:01 jim3692

Solves #2065

freddyg11 avatar Feb 06 '23 06:02 freddyg11

@jim3692 any interest in completing this PR?

ljharb avatar Jun 02 '23 17:06 ljharb

I haven't figured out a way for testing this with Github Actions. One approach, that I had came up, was running NixOS inside a UML container (example of using UML inside Docker is weber-software/diuid), but I wasn't able to make NixOS drop to a TTY, after loading systemd. Dropping to a TTY is an essential step to pass additional commands to the container to run the test.

I could probably add a way to force it to switch to "NixOS mode". This way we could use another distro (ex Ubuntu) to test it and just check whether its files are created, without actually testing if it works in a NixOS environment. However, I don't believe that this a reliable way of testing.

All in all, the lack of ways to properly test this feature is the reason there is no progress.

jim3692 avatar Jun 06 '23 12:06 jim3692

@jim3692 thanks for the thorough explanation; "no progress" is perfectly fine, just wanted to make sure you were still thinking about it :-)

I agree that it would be much better to test in actual NixOS than to fake it.

ljharb avatar Jun 06 '23 16:06 ljharb

@jim3692 would a custom Docker Container solve the issues? Like using debian:latest and add nixPackage Manager? Just saw this on twitter and happy to support from the Docker side of things :)

tippexs avatar Jun 06 '23 18:06 tippexs

I was recently experimenting with running Linux applications on Android and I did some research on PRoot. And I came up with a PRoot approach for NVM on NixOS.

The idea is to run NVM inside a minimal rootfs (like Alpine Linux) inside PRoot.

Such an approach could have a performance impact, due to the way PRoot works, but it could probably eliminate the need for privileged containers for automated testing.

Running NVM inside a bwrap environment (Steam works this way) would be another solution, to allow NVM to be distro-agnostic, but this also requires privileged containers to create the namespace.

Do you believe any of those ideas are worth further investigation?

jim3692 avatar Aug 23 '23 21:08 jim3692

@jim3692 tbh i don't have any idea what that would entail, but i'm comfortable with something for tests that you're willing to maintain :-D

ljharb avatar Aug 23 '23 22:08 ljharb

Closing this as I have run out of ideas on how to make it work reliably and be testable.

I had some ideas that would need to be implemented on Nix, and not modify nvm, but they would cause issues with native modules.

jim3692 avatar Dec 28 '23 09:12 jim3692

Fair enough. Can you document some of those ideas here for future readers?

ljharb avatar Dec 28 '23 16:12 ljharb

The idea was to emulate/wrap the nvm install and nvm use commands and probably hide the rest or work on them later.

It would run nvm in a new bash process just to download the needed Node version.

Then that version would be stored as a Nix FHS package, probably using a Flake.

On nvm use, it would just open a nix-shell with that version of Node, instead of running the normal nvm use code.

This approach is probably the most "NixOS" way to solve the problem, but it may have some issues, due to FHS.

Some of the topics that need some more thinking/research are:

  • Will this work for native modules?
  • How to hook the shell to read the .nvmrc file?
  • How to keep track of installed versions, as they will be stored in /nix/store, and not in home?
    • Maybe each user could keep a separate database of their installed versions and the corresponding Nix paths, as having shared versions is too dangerous. A user could easily install a malicious version of Node, which could be run by other users on that device.

jim3692 avatar Dec 28 '23 18:12 jim3692