Closed neutralalice closed 1 year ago
i'll take a look.
The more I thought about it today I'm wondering if it actually has to do with it being run locally, and in the non-home directory; I wondered if my statement in the op "although this role generates it's own in the playbooks directory in this scenario as well" with respect to .bashrc is the real core of the problem. Since the generated .bashrc will be in a nonstandard directory(i.e. where the playbook lives /home/pickles/ubuntu2204-wsl
), and not be sourced by the shell when it sets up the local connection.
If I set nvm_profile "~/.bashrc"
instead of letting it default nvm_profile: ".bashrc"
as well as remove the becomes
from the nvm tasks(there's 3 of them) so it doesn't expand out to /root/.bashrc
then it runs fine locally.
I think the removing the become arguments may be reasonable for the same reasons as described in the readme. Unless I'm missing something, I don't think those specific tasks should actually need to be elevated? In the "best" example for the role import, it would context switch to the user anyway, and so I'm not sure what purpose those would be serving; The become for those tasks is either defaulting to root, or to the user which has already been context switched to in the play itself.
The ansible-role-nvm runs in the context of the user currently running the role.
So, if you are running the role and have become: true
or become: yes
or become: 1
at the top of your playbook (scoped globally) the ansible-role-nvm will run as root user
OR
have any of those declarations as part of the ansible-role-nvm role itself, the ansible-role-nvm will run as root user
OR
are running the role as the mustard
user, the ansible-role-nvm will run as mustard user and install in /home/mustard/
directory
:thumbsdown: This is likely NOT what you want
- hosts: all
become: true # THIS RUNS ALL TASKS, FOR ALL HOSTS, AS ROOT_USER
become_method: sudo # THIS RUNS ALL TASKS, FOR ALL HOSTS, AS ROOT_USER
roles:
- role: ansible-role-nvm # installs nvm in the root user directory /root/.bashrc
nodejs_version: "8.16.0"
nvm_commands:
- "nvm exec default npm install"
- role: some-other-role
...
Secondly, if the user pickles
is not a real user on the machine, the role will not work as expected. You will need to generate the user and home directory first, then install the role as that user.
- hosts: host1
pre_tasks:
- name: add new user
user:
name: "pickles"
become: true
roles:
- role: ansible-role-nvm
nodejs_version: "8.16.0"
nvm_profile: "/home/pickles/.bashrc"
nvm_commands:
- "whoami"
- "node --version"
- "nvm --version"
- "npm --version"
become_user: pickles
become: true
In the example above, the nvm_profile
key is optional, I use it for illustrative purposes in case people have renamed or have different .bashrc file.
It also scopes the install of NVM to the user it is destined for (in this case pickles). This is particularly useful when:
become: true
or become: yes
or become: 1
to work properlypickles is a real user (it was a test vm), and the playbook listed was the playbook utilized with zero changes; In other words, I did not set become
in the playbook. Because it's run locally without a "become_user: pickles" in the role include, when it gets to the become commands in the actual tasks, it becomes as root by default. The example playbooks listed in the readme (super simple, simple, more complex) will also exhibit this behavior.
If run locally as the user scoped in the playbook with become commands, there would be no problem. the tasks themselves don't need to attempt to become anything since "become: true" is set your examples in the above.
The problem is that the tasks which utilize the defaults variable generate relative ".bashrc". When you run a playbook locally it scopes to the directory that the playbook is run in, not the home directory of the user context. So in my case, with no changes to the role it will generate a .bashrc in the playbook directory (i.e. /home/pickles/ubuntu2204-wsl/.bashrc
with root:root owner/group) and not adjust the actual sourced .bashrc (i.e. /home/pickles/.bashrc
) for the user.
Ahh, ok
The problem is that the tasks which utilize the defaults variable generate relative ".bashrc". When you run a playbook locally it scopes to the directory that the playbook is run in, not the home directory of the user context.
That was helpful.
Putting this all together, I see a few fixes here:
~/.bashrc
instead of .bashrc
as you pointed outWould you mind testing this branch to see if this addresses your issue?
https://github.com/morgangraphics/ansible-role-nvm/tree/bugfix/41-connection-local
Or provide me with your playbook, so I can test
I will give it a go shortly.
I did find a different issue, but I'll open up a separate issue for the role if I can figure out exactly what's triggering it( I believe it's related to the interactive shell usage option).
The branch worked using the same playbook as listed in the OP (and also setting become as a local user, but not one running the playbook)
I believe the original issue has been addressed. If you are still having issues, please open another ticket. Thanks for participating in the process and helping with the project.
Describe the bug The role fails on the first nvm command it comes across if the role is run with a local connection rather than ssh. It doesn't have access to the nvm commands as they aren't being sourced.
Expected behavior nvm.sh needs to be sourced in the tasks that utilize nvm so that the shell module can be run locally successfully. Normally this would be fine when connection method is ssh because they get sourced via .bashrc (although this role generates it's own in the playbooks directory in this scenario as well), but running locally doesn't seem to exhibit this behavior
To Reproduce Ubuntu 22.04 host image In a directory with the playbook, and relevant cloned /roles/ansible-role-nvm folder (or .ansible/roles etc)
Shell [e.g. Bash, Dash, ksh, tcsh, zsh] bash
Desktop (please complete the following information):
Debugging output
Additional context I question if this is the same as #15 but since they didn't give enough information, it is hard to tell. You can test whether or not the local (sub)shell will have access to nvm by entering
bash
in a terminal and trying any nvm command.