Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.Sign up
Allow nvm-exec to be linked into individual .nvm directories for system-wide installs with a localized Nodes #1845
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. 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.
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.
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
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...
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.
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.
[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.