Por que 'ansible -a' env '' retorna um PATH de ambiente diferente do meu usuário?

5

Quando eu ssh em um servidor remoto e executo env , recebo o seguinte PATH:

PATH=/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/myusername/bin

Por outro lado, quando executo o comando ansible ansible -a "env" , recebo o seguinte PATH:

PATH=/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin

Como pode ser imaginado, isso causa problemas ao tentar executar sbin comandos como service , ntpdate , etc. porque requer a digitação do caminho completo para o comando sbin. (Sim, eu sei que existem módulos ansible que podem fazer isso, mas estou tentando resolver porque o PATH está ficando reduzido / truncado.)

Alguém sabe por que isso está acontecendo?

EDIT: A razão pela qual estou perguntando sobre isso é que estou seguindo os exemplos no livro Ansible for DevOps e alguns dos exemplos não estão funcionando por esse motivo.

O exemplo que estou tentando fazer é da página 28 do livro:

$ ansible multi -s -a "service ntpd stop"
$ ansible multi -s -a "ntpdate -q 0.rhel.pool.ntp.org"
$ ansible multi -s -a "service ntpd start"

Esses comandos sempre geram um erro. Mas se eu alterá-los para incluir o caminho completo, eles funcionam.

$ ansible multi -s -a "/sbin/service ntpd stop"
$ ansible multi -s -a "/usr/sbin/ntpdate -q 0.rhel.pool.ntp.org"
$ ansible multi -s -a "/sbin/service ntpd start"

Naturalmente, não quero ter que digitar o caminho completo para cada comando ad-hoc que eu emitir. (Eu não sei os caminhos de cada comando).

Existe alguma maneira de obter o caminho normal que está no meu shell incluído com ansible? Existe uma variável de caminho que eu possa adicionar ao arquivo de inventário ou ao arquivo ansible.cfg que permitirá que isso aconteça?

    
por Pretzel 27.07.2016 / 18:59

3 respostas

2

Sempre que usava ansible, ele funcionava como um usuário diferente ... sob um shell diferente. deve ser capaz de ver o que o usuário está fazendo:

ansible -a "id"

você pode então ver o shell do usuário definido em:   cat /etc/passwd

A prática recomendada para adicionar ao caminho seria adicionar uma linha em: /home/<username>/.profile ou ~/.bash_profile

    
por 05.08.2016 / 16:50
10

ansible -a está usando o módulo de comando e isso não usa um shell para executar o comando.

http://docs.ansible.com/ansible/intro_adhoc.html
Normally commands also take a -m for module name, but the default module name is ‘command’.

Os componentes do caminho, como /usr/sbin , são adicionados ao caminho pelo shell que está obtendo o arquivo /etc/profile , e o módulo de comando não cria login shell para que ele não leia esse arquivo.

http://linux.die.net/man/1/bash
When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

Os documentos ansible dizem que se você quiser um shell, use o módulo shell . No entanto, não parece que haja uma opção para iniciar um shell de login a partir do módulo shell (passando a opção --login) de qualquer maneira.

De fato, é mencionado em vários lugares que a política ansiosa é não confiar no ambiente e definir qualquer VARS explicitamente quando a tarefa é definida.

No entanto, é possível definir o caminho ao usar ansible no modo ad-hoc. Estes são os mais próximos que eu poderia fazer para replicar o PATH que você vê em um /bin/bash shell interativo;

$ ansible raspberrypi -m shell \
-a 'PATH=$PATH:/usr/local/sbin:/usr/sbin:$HOME/bin  env' \
 | grep PATH

PATH=/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/local/sbin:
/usr/sbin:/home/pi/bin

ou, como alternativa, você pode criar o arquivo /etc/profile

 $ ansible raspberrypi -m shell \
 -a 'executable=/bin/bash source /etc/profile ; env | grep PATH'

 PATH=/opt/consul/bin:/usr/local/sbin:/usr/local/bin:
 /usr/sbin:/usr/bin:/sbin:/bin

isso parece funcionar também;

$ ansible raspberrypi -a '/bin/bash -l -c "env"'

 PATH=/opt/consul/bin:/usr/local/sbin:/usr/local/bin:
 /usr/sbin:/usr/bin:/sbin:/bin
    
por 27.07.2016 / 19:27
2

Então, dada a sua pergunta, em última análise, sobre a execução de comandos sob o sudo com ansible, eu dei uma outra olhada em como o PATH é definido ao usar ansible -s -a env . Eu acho que é importante notar que ao usar o sinalizador sudo -s em ansible, o $ PATH é definido por um mecanismo diferente ao usar apenas ansible -a env .

Ao usar sudo command ou ansible -s , o ambiente dos usuários é redefinido e $ PATH é controlado pela configuração Default secure_path em /etc/sudoers e isso é explicado no sudoers do homem documentação;

By default, the env_reset option is enabled. This causes commands to be executed with a new, minimal environment. The new environment contains the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables in addition to variables from the invoking process permitted by the env_check and env_keep options.

Se você não definir um valor para Default secure_path , esses valores serão codificados para o binário sshd, consulte esta resposta para detalhes.

No entanto, por padrão, no fedora / centros / ubuntu, o valor para $ PATH é obtido de secure_path definido em /etc/sudoers ;

secure_path - Path used for every command run from sudo.

Por exemplo, no meu host local fedora, ele tem a seguinte linha em /etc/sudoers

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin

e se eu executar o comando env remotamente por ssh e sudo, obtenho o caminho exato de volta;

$ ssh localhost "sudo env" | grep PATH
PATH=/sbin:/bin:/usr/sbin:/usr/bin

e eu recebo a mesma coisa usando ansible;

$ ansible localhost -s -a 'env' | grep PATH
PATH=/sbin:/bin:/usr/sbin:/usr/bin

e eu tentei a mesma coisa em uma instância raspbian (debian) e obtive um comportamento semelhante;

$ ansible raspberrypi -s -a 'cat /etc/sudoers' | grep secure
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

e esse é o caminho que ansible vê com as opções -s -a ;

$ ansible raspberrypi -s -a env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Portanto, em relação à sua pergunta original, eu verificaria o arquivo /etc/sudoers e verificaria o valor de Defaults secure_path="/some/path/here" .

Se você não tiver um valor lá que inclua o diretório sbin/ apropriado, o seguinte comando em ansible não funcionará sem um caminho completo fornecido;

ansible multi -s -a "service ntpd stop"
    
por 04.08.2016 / 22:16