Назад | Перейти на главную страницу

Почему 'ansible -a «env»' возвращает PATH среды, отличной от моего пользователя?

Когда я подключаюсь по ssh к удаленному серверу и запускаю env Я возвращаю следующий ПУТЬ:

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

Напротив, когда я выполняю команду ansible ansible -a "env", Я получаю следующий ПУТЬ:

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

Как можно догадаться, это вызывает проблемы при попытке запустить sbin такие команды, как service, ntpdateи т. д., поскольку для этого нужно ввести полный путь к команде sbin. (Да, я знаю, что есть доступные модули, которые могут это делать, но я пытаюсь решить, почему PATH укорачивается / усекается.)

Кто-нибудь знает, почему это происходит?

РЕДАКТИРОВАТЬ: Причина, по которой я спрашиваю об этом, заключается в том, что я следую примерам из книги Ansible for DevOps и некоторые примеры не работают по этой причине.

Пример, который я пытаюсь заставить работать, взят со страницы 28 книги:

$ 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"

Эти команды всегда вызывают ошибку. Но если я изменю их, чтобы включить полный путь, они работают.

$ 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"

Естественно, я не хочу, чтобы мне приходилось вводить полный путь для каждой специальной команды, которую я выполняю. (Я не знаю пути каждой команды.)

Есть ли способ получить обычный путь, который в моей оболочке включен в ansible? Есть ли переменная пути, которую я могу добавить в файл инвентаризации или файл ansible.cfg, чтобы это произошло?

ansible -a использует командный модуль и это не использует оболочку для выполнения команды.

http://docs.ansible.com/ansible/intro_adhoc.html
Обычно команды также принимают -m в качестве имени модуля, но имя модуля по умолчанию - «команда».

Компоненты пути, такие как /usr/sbin добавляются к пути оболочкой, получающей /etc/profile файл, а командный модуль не создает авторизоваться shell, чтобы он не читал этот файл.

http://linux.die.net/man/1/bash
Когда bash вызывается как интерактивная оболочка входа или как неинтерактивная оболочка с параметром --login, она сначала считывает и выполняет команды из файла / etc / profile, если этот файл существует. После чтения этого файла он ищет ~ / .bash_profile, ~ / .bash_login и ~ / .profile в указанном порядке, а также читает и выполняет команды из первого существующего и доступного для чтения файла. Параметр --noprofile может использоваться при запуске оболочки, чтобы запретить такое поведение.

В доступных документах говорится, что если вам нужна оболочка, используйте оболочка модуль. Однако не похоже, что есть возможность запустить оболочку входа из модуля оболочки (путем передачи параметра --login) в любом случае.

Фактически, в разных местах упоминается, что доступная политика заключается в том, чтобы не доверять среде и явно устанавливать любые VARS при определении задачи.

Однако можно указать путь при использовании ansible в режиме ad-hoc. Это ближайшее, что я мог бы сделать, чтобы воспроизвести ПУТЬ, который вы видите в интерактивном /bin/bash оболочка;

$ 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

или, в качестве альтернативы, вы можете получить /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

похоже, это тоже работает;

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

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

Итак, учитывая, что ваш вопрос в конечном итоге касается запуска команд под sudo с помощью ansible, я еще раз посмотрел, как устанавливается PATH при использовании ansible -s -a env. Я думаю, важно отметить, что при использовании sudo -s недоступен, $ PATH устанавливается другим механизмом, чем при использовании только ansible -a env.

Когда используешь sudo command или ansible -s среда пользователя сбрасывается, а $ PATH управляется Default secure_path установка в /etc/sudoers и это объясняется в человек sudoers документация;

По умолчанию опция env_reset включена. Это вызывает выполнение команд в новой минимальной среде. Новая среда содержит переменные TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME и SUDO_ * в дополнение к переменным из вызывающего процесса, разрешенным параметрами env_check и env_keep.

Если вы не установите значение для Default secure_path, то эти значения жестко закодированы в двоичный файл sshd, см. этот ответ для подробностей.

Однако по умолчанию в Fedora / centros / ubuntu значение $ PATH берется из secure_path, установленного в /etc/sudoers;

secure_path - путь, используемый для каждой команды, запускаемой из sudo.

Например, на моем локальном хосте fedora он имеет следующую строку в /etc/sudoers

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

и если я запустил env удаленно с помощью ssh и sudo я получаю точный путь обратно;

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

и я получаю то же самое, используя ansible;

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

и я пробовал то же самое на экземпляре raspbian (debian), и у меня такое же поведение;

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

и это путь, который видит ansible с -s -a параметры;

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

Итак, что касается вашего первоначального вопроса, я бы взглянул на /etc/sudoers файл и проверьте значение Defaults secure_path="/some/path/here".

Если у вас нет значения, которое включает соответствующий sbin/ directory, то следующая команда в ansible не будет работать, если не указан полный путь;

ansible multi -s -a "service ntpd stop"

Каждый раз, когда я использовал ansible, он запускался от имени другого пользователя ... под другой оболочкой. должен иметь возможность видеть, что делает пользователь:

ansible -a "id"

затем вы можете увидеть оболочку пользователя, определенную в: cat /etc/passwd

Лучше всего добавить к пути, добавив строку: /home/<username>/.profile или ~/.bash_profile