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

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

msaladna
Copy link

@msaladna msaladna 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.

@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
Copy link
Member

ljharb 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 ljharb added the root / multiuser issues Anything related to using `sudo` or `su`, or using nvm across multiple user accounts. label Jun 21, 2018
@ljharb
Copy link
Member

ljharb 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
Copy link
Author

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
Copy link
Author

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

@ljharb
Copy link
Member

ljharb 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".

@msaladna
Copy link
Author

msaladna 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
Copy link
Member

ljharb 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
Copy link
Author

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.

@@ -3201,7 +3201,9 @@ nvm() {
nvm_echo "Running node $VERSION$(nvm use --silent "$VERSION" && nvm_print_npm_version)"
fi
fi
NODE_VERSION="$VERSION" "$NVM_DIR/nvm-exec" "$@"
NVM_EXEC="$NVM_DIR/nvm-exec"
test ! -f "$NVM_EXEC" && NVM_EXEC="$(dirname "${BASH_SOURCE[0]-}")/nvm-exec"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
test ! -f "$NVM_EXEC" && NVM_EXEC="$(dirname "${BASH_SOURCE[0]-}")/nvm-exec"
if [! -f "$NVM_EXEC"]; then
NVM_EXEC="$(dirname "${BASH_SOURCE[0]-}")/nvm-exec"
fi

DIR="$(command cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
SOURCE=${BASH_SOURCE[0]}
test -L "$SOURCE" && command cd "$( dirname "$SOURCE" )" && \
SOURCE=$(readlink "$SOURCE")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is readlink in POSIX?

@msaladna
Copy link
Author

I release any changes to you going forward 👍

@msaladna msaladna closed this Nov 23, 2021
@ljharb ljharb reopened this Nov 23, 2021
@ljharb
Copy link
Member

ljharb commented Nov 23, 2021

@msaladna that only works if the PR remains open for me to update :-) thanks, i'll try to finish it.

@ljharb
Copy link
Member

ljharb commented Dec 23, 2021

@msaladna actually, since this PR was made from a fork you don't own, i won't be able to force push to it unless you add me to the apisnetworks nvm fork. Can you do so?

@ljharb ljharb marked this pull request as draft December 23, 2021 18:33
@msaladna
Copy link
Author

I use that repo as a base for platform installs. Would forking it into msaladna and opening up a new PR be a suitable workaround? I don't believe you can change the source on a PR.

@ljharb
Copy link
Member

ljharb commented Dec 29, 2021

@msaladna no, unfortunately once the PR is opened it's unchangeable. If you'd temporarily add me to your fork, I can rebase this PR and land it, and then you can remove me once the PR has merged? I'd much prefer that over polluting the repo with a redundant PR ref forever :-)

@ljharb
Copy link
Member

ljharb commented Mar 11, 2022

@msaladna any chance for a temporary add to that fork?

@msaladna
Copy link
Author

I will not be able to do this. That repository is intertwined with our product.

@ljharb
Copy link
Member

ljharb commented Mar 11, 2022

That's very unfortunate :-/ please don't make PRs from it in the future; PRs should only ever be made from personal forks.

@msaladna For this one, can you rebase this on latest master, and then I'll provide you a commit hash to force push to it, so we can land this?

…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.
@ljharb
Copy link
Member

ljharb commented Dec 11, 2023

@msaladna thanks! could you fetch, check out the branch, git reset --hard ec9a755, and then force push it back?

@ljharb
Copy link
Member

ljharb commented Feb 2, 2024

@msaladna ping! the updated SHA is 44039c1, could you force push that to the master branch?

…s.current bean counter resulting in 64+ concurrent tids (tasks, w/ threads) thus making it susceptible to hit pids.max. Once reached, subshell behavior is unexpected yielding "retry: Resource temporarily unavailable" errors until cgroup capacity is restored.
@ljharb ljharb force-pushed the master branch 2 times, most recently from c6cfc3a to c20db2a Compare June 10, 2024 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
root / multiuser issues Anything related to using `sudo` or `su`, or using nvm across multiple user accounts.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants