Getting remote user environment with sudo

Hi all,

It seems I can not get the remote user's environment loaded when using
sudo in a playbook (or at the command line).

Here is an example : I need to retrieve the installed ruby version with
rbenv. Ruby is installed for user 'rbuser', and rbenv requires .bashrc
to be loaded so it can be found.

Trying at the command line (or in a playbook with "sudo: True" and
"sudo_user: rbuser") doesn't work :

ws$ ansible all -m shell -a 'rbenv version' -l goat -U rbuser
<goat> EXEC /bin/sh -c 'sudo -k && sudo -p "[sudo snip] password: " -u
rbuser /bin/sh -c '"'"'/usr/bin/python
/tmp/ansible-1358499444.98-121478482753266/command; rm -rf
/tmp/ansible-1358499444.98-121478482753266/ >/dev/null 2>&1'"'"''
goat | FAILED | rc=127 >>
/bin/sh: 1: rbenv: not found

Trying the geenrated python directly from the node unsurprisingly gives
the same result :

ws$ ssh root@goat
root@goat:~ sudo -u rbuser /bin/sh -c '/usr/bin/python
/tmp/ansible-1358499444.98-121478482753266/command'
{"changed": true, "end": "2013-01-18 09:57:54.312280", "stdout": "",
"cmd": "rbenv version ", "start": "2013-01-18 09:57:54.302952", "delta":
"0:00:00.009328", "stderr": "/bin/sh: 1: rbenv: not found", "rc": 127}

However, when trying with an additional (-i) flag (asking sudo to load
the user's environment), it works fine :

root@goat:~ sudo -iu rbuser /bin/sh -c '/usr/bin/python
/tmp/ansible-1358499444.98-121478482753266/command'
{"changed": true, "end": "2013-01-18 09:58:06.176637", "stdout": "system
(set by /home/rbuser/.rbenv/version)", "cmd": "rbenv version ", "start":
"2013-01-18 09:58:06.061737", "delta": "0:00:00.114900", "stderr": "",
"rc": 0}

Am I missing something here ? Should we invoke sudo with -i flag in
make_sudo_command ?

Thanks,

M

Sudo normally removes most env vars, you should be able to configure it to preserve those you need.

Brian Coca

Sudo has a -E flag that prevents env filtering, test with that.

Brian Coca

Hi Brian,

May be I misexplained my problem, but it is not about preserving
environment; it's about getting the environment of the target user.

For instance, when the playbook is ran with this :

  - hosts: ubuntu
    name: Install ruby for the configured ruby user
    sudo: True
    sudo_user: rubyuser
    # should be ${ruby_user}, but can't for now because of #1665
    tasks:
    - name: Gets current ruby version
      action: shell rbenv version
      register: ruby_current_version

The 'rubyuser' environment on the remote node is not loaded when the
tasks are run. This prevents tools like rvm or rbenv from working,
because they both need to be initialized and have their path added to
$PATH, and this setup phase typically takes place in .bash_profile.

Just to check :

$ ansible all -m shell -a 'echo $HOME' -l somehost -U someuser
somehost | success | rc=0 >>
/root

What I'd rather get : /home/someuser

So the need here is to be sure that when root SUDOs as someuser, the
latter gets it's environment properly (AFAIK, -E does the exact oppostite).

And the problem is not doing it by hand, but being able to get the
user-we-sudo-as environment loaded.

May be I'm missing the point, and loading the target user is a problem,
but I don't really see why. As a side effect, it would have solved #1864.

M

Sorry, I had misunderstood.

One thing to note is that ansible uses /bin/sh by default, which does
not source .bash_profile, even if you switch to bash it would have to
do so as a login shell (--login IIRC).

Sorry, I had misunderstood.

No problem. It was probably unclear in the first place !

One thing to note is that ansible uses /bin/sh by default, which does
not source .bash_profile, even if you switch to bash it would have to
do so as a login shell (--login IIRC).

Yes, I tried all sort of combinations, e.g.

action: shell bash -lc 'rbenv version'

and none worked. Seems that using '-i' in make_sudo_cmd is the best option.

I'll just send a PR and see how it goes.

Thanks,

M

I think I'm fine with adding -i to sudo (so that the environment gets
loaded) unless anyone is running a sudo that doesn't have it.

BSD/Solaris folks, please check?

--Michael

confirmed -i on freebsd 8.0 and above

Has this made it to a released Ansible version yet?

//Marcus

It is in the current development branch, and will be in 1.4.

Hi,

I’m running into the same issue the original poster was running into. Based on my cursory search it appears that this change has never made it into a release. Does anyone know why?

Thanks,

Sergei.

I don’t see this change in any current release. Did it get reverted for some reason?

Hi Sergei,

The patch was accepted but it turned out it had unwanted side effects,
with somme connections lingering under some circumptances, so in the
end, it was removed from the code.

So I now I rap all my shell calls in 'bash -lc' to get the remote user's
environment set-uip properly. For instance :

- shell: cd; bash -lc "rbenv install {{ ruby_version }}"

Cheers,

M