Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow nvm-exec to be linked into individual .nvm directories for system-wide installs with a localized Nodes #1845

Open
wants to merge 3 commits into
base: master
from

Conversation

Projects
None yet
2 participants
@msaladna
Copy link

commented Jun 21, 2018

Let's say we have nvm installed in a separate mount, /.socket. NVM_DIR is $HOME/.nvm in /etc/profile.d/nvm.sh. With this setup, users can install Node versions to their home directories without each installing nvm.

nvm install --lts

This works fine as does nvm use --lts. When nvm exec is used though, it fails because it looks for nvm-exec in $NVM_DIR. First fix is to look for nvm-exec in $NVM_DIR. If NVM_DIR does not contain nvm-exec, check $BASH_SOURCE[0]. The second fix is to follow nvm-exec if a symbolic link to determine the proper location of nvm's home. Alternatively we could use a second environment variable, NVM_HOME in exec instead of relying on the directory name of nvm-exec.

msaladna added some commits Jun 21, 2018

Allow nvm-exec to be linked into individual .nvm directories for syst…
…em-wide installs with a localized Nodes.

Let's say we have nvm installed in a separate mount, /.socket. NVM_DIR is $HOME/.nvm in /etc/profile.d/nvm.sh. With this setup, users can install Node versions to their home directories without each installing nvm.

nvm install --lts

This works fine as does nvm use --lts. When nvm exec is used though, it fails because it looks for nvm-exec in $NVM_DIR. First fix is to look for nvm-exec in $NVM_DIR. If NVM_DIR does not contain nvm-exec, check $BASH_SOURCE[0]. The second fix is to follow nvm-exec if a symbolic link to determine the proper location of nvm's home. Alternatively we could use a second environment variable, NVM_HOME in exec instead of relying on the directory name of nvm-exec.

@msaladna msaladna force-pushed the apisnetworks:master branch from d8a87b4 to 7d8b67b Jun 21, 2018

@ljharb ljharb changed the title Allow nvm-exec to be linked into individual .nvm directories for syst… Allow nvm-exec to be linked into individual .nvm directories for system-wide installs with a localized Nodes Jun 21, 2018

@ljharb

This comment has been minimized.

Copy link
Collaborator

commented Jun 21, 2018

I'm confused; nvm is per-user, which means that each user must have their own $NVM_DIR - which includes having their own installation of nvm.

@ljharb

This comment has been minimized.

Copy link
Collaborator

commented Jun 21, 2018

This seems like something that would be better to have discussed in an issue first.

Now that you have a PR, can you provide some failing tests?

@msaladna

This comment has been minimized.

Copy link
Author

commented Jun 21, 2018

In the default situation each user is responsible for managing their copy of nvm. This allows for a system-wide approach that can be managed from a single point.

  • Install nvm in /opt/nvm
  • For /etc/profile.d/nvm.sh, add:
export NVM_DIR="$HOME/.nvm"
[ -s "/opt/nvm/nvm.sh" ] && \. "/opt/nvm/nvm.sh" # This loads nvm

nvm install works fine, installs in $HOME/.nvm
nvm use works fine too
nvm exec fails, because it looks for nvm-exec in $HOME/.nvm, which only contains the localized Node installs, not nvm.

@msaladna

This comment has been minimized.

Copy link
Author

commented Jun 21, 2018

Updated PR to include test that causes nvm exec to fail when NVM_DIR is different from where nvm.sh is located.

@msaladna msaladna force-pushed the apisnetworks:master branch from 2a354a8 to 626b960 Jun 21, 2018

@ljharb

This comment has been minimized.

Copy link
Collaborator

commented Jun 21, 2018

Right - but NVM_DIR is not "the directory holding node installs", it's "the directory holding nvm itself AND the node installs, including nvm-exec".

Add test for NVM_DIR outside nvm.sh
Fix symlink traversal

@msaladna msaladna force-pushed the apisnetworks:master branch from 626b960 to ca358b1 Jun 21, 2018

@msaladna

This comment has been minimized.

Copy link
Author

commented Jun 21, 2018

What then would be another approach for having a single nvm instance where each user can have their own Node installs without putting every user under the same group and giving the group rwx or having each user manage their own nvm git repository?

This is primarily for multi-tenant environments where 100+ users can manage their own Node interpreters + npm packages, their interactions can't necessarily be trusted, and you want to maintain a global nvm version such that if there are any issues you aren't entrusting 100 users to each update their nvm repo.

Setting NVM_DIR to wherever nvm is installed will allow whoever (root for example) to install system-wide Nodes, but delegate individual power for users to install their own Nodes/packages without cluttering up what's available system-wide.

Edit: nor giving them the power to muck around and drop rogue binaries under NVM_DIR...

@ljharb

This comment has been minimized.

Copy link
Collaborator

commented Jun 21, 2018

Each user could have their own git repo, but you could still chmod the .git dirs, and nvm.sh/nvm-exec etc, so they would be unable to write to them?

Re "nor giving them the power to muck around and drop rogue binaries under NVM_DIR.." that's fair, but I'm wondering what you're trying to defend against - if the user messes up their NVM_DIR, then you can reset it (since you can always reach in and manage the user's NVM_DIR yourself)

Just throwing out ideas here! I'm not sure what the best solution is, but it seems like there's a bunch of ways to have the control and the flexibility you need without needing to share an nvm.sh or nvm-exec or NVM_DIR.

@msaladna

This comment has been minimized.

Copy link
Author

commented Jun 21, 2018

Yes, that's a possibility and you can also use something like OverlayFS/aufs to create a layered filesystem where a copy-up would be written to their filesystem layer. I use a similar approach with pyenv/rbenv/goenv, but the limitation is that if you have say 1 user under wheel and 4 subordinate users under the same gid (but not wheel), those subordinates cannot install additional Ruby/Python/Go interpreters without wheel's consent, because wheel has rwx on the directory that's shared on the account.

nvm at least will install Node locally to $HOME/.nvm, which is a good thing for giving users the power to install Node on their account, but not share what's installed among other users on the account. Rolling out git individually across each account creates a lot of duplication; this is a technique to deduplicate nvm and keep 1 system version.

Having a single, system-wide nvm allows for greater customization if you wanted to alter nvm.sh for whatever reason. Simpler to propagate changes once rather than n-way.

And with this approach if they mess up their NVM_DIR, they're nuking just the Nodes/npm packages installed, not nvm and potentially any custom, system-wide additions that are made.

e.g...

[debug@testing ~]$ nvm install --lts
Installing latest LTS version.
Downloading and installing node v8.11.3...
Downloading https://nodejs.org/dist/v8.11.3/node-v8.11.3-linux-x64.tar.xz...
[debug@testing ~]$ nvm ls
->      v8.11.3
default -> lts/* (-> v8.11.3)
node -> stable (-> v8.11.3) (default)
stable -> 8.11 (-> v8.11.3) (default)
iojs -> N/A (default)
unstable -> N/A (default)
lts/* -> lts/carbon (-> v8.11.3)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.14.3 (-> N/A)
lts/carbon -> v8.11.3

Then under the same account as test123...

[debug@testing ~]$ su test123
[test123@testing ~]$ nvm ls
            N/A
iojs -> N/A (default)
node -> stable (-> N/A) (default)
unstable -> N/A (default)
[test123@testing ~]$ nvm install lts/argon
Downloading and installing node v4.9.1...
Downloading https://nodejs.org/dist/v4.9.1/node-v4.9.1-linux-x64.tar.xz...
Now using node v4.9.1 (npm v2.15.11)
Creating default alias: default -> lts/argon (-> v4.9.1)

So each user has control over their own Nodes. Each can delete ~/.nvm without affecting the other user or requiring superuser privilege. nvm has the ability to do this, and does it quite well. I've used this approach since 2016 for my clients, except never sat down to work out a process to allow nvm exec to work as it should in this setup; that's what this patch aims to solve.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.