Как получить домашний каталог произвольного удаленного пользователя в Ansible?
Я могу сделать это с консоли с помощью комбинации getent
и awk
такой:
getent passwd $user | awk -F: '{ print }'
для справки, в Puppet я могу использовать пользовательский факт, например:
require 'etc'
Etc.passwd { |user|
Facter.add("home_#{user.name}") do
setcode do
user.dir
end
end
}
что делает домашний каталог пользователя как home_<user name>
факт.
как мне получить домашний каталог произвольные удаленный пользователь?
8 ответов:
Ansible (начиная с 1.4 и далее) уже показывает переменные среды для пользователя под
ansible_env
переменной.- hosts: all tasks: - name: debug through ansible.env debug: var=ansible_env.HOME
кроме того, вы можете получить доступ к переменным среды с помощью поиск on
env
:- hosts: all tasks: - name: debug through lookup on env debug: var=lookup('env','HOME')
к сожалению, вы, по-видимому, можете использовать это только для получения переменных среды для подключенного пользователя в качестве этого playbook и вывода показывает:
- hosts: all tasks: - name: debug specified user's home dir through ansible.env debug: var=ansible_env.HOME become: true become_user: "{{ user }}" - name: debug specified user's home dir through lookup on env debug: var=lookup('env','HOME') become: true become_user: "{{ user }}"
выход:
vagrant@Test-01:~$ ansible-playbook -i "inventory/vagrant" env_vars.yml -e "user=testuser" PLAY [all] ******************************************************************** GATHERING FACTS *************************************************************** ok: [192.168.0.30] TASK: [debug specified user's home dir through ansible.env] ******************* ok: [192.168.0.30] => { "var": { "/home/vagrant": "/home/vagrant" } } TASK: [debug specified user's home dir through lookup on env] ***************** ok: [192.168.0.30] => { "var": { "/home/vagrant": "/home/vagrant" } } PLAY RECAP ******************************************************************** 192.168.0.30 : ok=3 changed=0 unreachable=0 failed=0
как и все в Ansible, если вы не можете получить модуль, чтобы дать вам то, что вы хотите, то вы всегда можете shell out (хотя это должно использоваться экономно, поскольку оно может быть хрупким и будет менее описательным), используя что-то вроде этого:
- hosts: all tasks: - name: grep and register shell: > egrep "^{{ user }}:" /etc/passwd | awk -F: '{ print }' changed_when: false register: user_home - name: debug output debug: var=user_home.stdout
там может быть чище способ сделать это, и я немного удивлен, что с помощью
become_user
чтобы переключиться в указанный пользователь, похоже, не влияет наenv
поиск, но это должно дать вам то, что вы хотите.
Проблема
The
lookup()
или методы ENV var для поиска дома произвольного пользователя, к сожалению, не будут надежно работать с Ansible, потому что он работает как пользователь, указанный с--user=REMOTE_USER
, а такжеsudo
(еслиsudo: yes
в playbook или--sudo
прошло). Эти два режима запуска (sudo или no sudo) изменят среду оболочки, в которой работает Ansible, и даже тогда вы будете ограничены пользователем, указанным как-u REMOTE_USER
илиroot
.вы могли бы попробовать использовать
sudo: yes
иsudo_user: myarbitraryuser
вместе... однако из-за ошибки в некоторые версии Ansible вы можете увидеть, что он ведет себя не так, как надо. Если вы находитесь на Ansible >=1.9
, вы можете использоватьbecome: true
иbecome_user: myarbitraryuser
вместо. Однако это означает, что книги воспроизведения и роли, которые вы пишете, не будут работать на предыдущих версиях Ansible.если вы ищете портативный способ получить домашний каталог пользователя, который также будет работать с LDAP или какой-либо другой службой каталогов, используйте
getent
.пример Ansible getent
создать простой playbook с именем:
playbooks/ad-hoc/get-user-homedir.yml
- hosts: all tasks: - name: shell: > getent passwd {{ user }} | cut -d: -f6 changed_when: false register: user_home - name: debug output debug: var=user_home.stdout
запустите его с помощью:
ansible-playbook -i inventory/racktables.py playbooks/ad-hoc/get-user-homedir.yml -e "user=someuser"
Ansible 1.8 ввел
getent
модуль. Он регистрирует результат getent как факт хоста-в этом случае этоgetent_passwd
.примеры:
печать домашней папки для данного
user
:--- - getent: database: passwd key: "{{ user }}" split: ":" - debug: msg: "{{ getent_passwd[user][4] }}"
накопить таблицу поиска (
user_homes
), используяset_fact
и Jinja2combine()
фильтр:--- - assert: that: - user_name is defined - when: user_homes is undefined or user_name not in user_homes block: - name: getent become: yes getent: database: passwd key: "{{ user_name }}" split: ":" - name: set fact set_fact: "user_homes": "{{ user_homes | d({}) | combine({user_name: getent_passwd[user_name][4]}) }}"
было бы лучше с пользовательским модулем фактов, хотя.
Я думаю, что здесь есть несколько ответов, которые будут работать, но я думал, что покажу, что вы можете получить это от ansible user модуль, зарегистрировав его в качестве переменной.
# The `webserver_user` value will usually be provided by a distro # specific vars file. But for the purposes of demonstration, let's # hard code it to something... - set_fact: webserver_user: www-data when: ansible_os_family is 'Debian'
затем используйте модуль ansible user, чтобы убедиться, что пользователь присутствует, и прочитайте атрибут в зарегистрированную переменную для последующего использования.
- user: name: "{{ webserver_user }}" state: present register: webserver_user_registered
Итак, мы можем использовать для отладки, чтобы показать значения, что методика расчета var, включая путь...
- debug: var: webserver_user_registered TASK [wordpress : debug] ****************** ok: [wordpresssite.org] => { "webserver_user_registered": { "append": false, "changed": false, "comment": "www-data", "failed": false, "group": 33, "home": "/var/www", <<------ this is the user home dir "move_home": false, "name": "www-data", "shell": "/usr/sbin/nologin", "state": "present", "uid": 33 } }
и вы можете использовать эти свойства в других модулях, как это:
- file: name: "{{ webserver_user_registered.home }}/.wp-cli" state: directory
Я знаю, что это довольно старый поток, но я думаю, что это немного более простой способ получить домашний каталог пользователей
- name: Get users homedir local_action: command echo ~ register: homedir
в системах Linux (или Unix) знак Тильды указывает на домашний каталог пользователей.
каждый ответ упоминает о том, как распечатать детали домашнего каталога во время запуска playbook и отображения его на экране с помощью debug и var.
адаптация к @TrinitronX ответ
дополнительные сведения об использовании этой информации для новой задачи.
у меня есть список пользователей, чей домашний каталог должен быть извлечен. Поэтому я добавил данные пользователя в список
- name: Get home directory shell: > getent passwd {{ item.user }} | cut -d: -f6 changed_when: false with_items: - "{{java}}" register: user_home
вот этот шаг будет петля через весь список пользователей и зарегистрирует эту информацию в user_home. И это будет в виде массива.
Затем следующий шаг-использовать эту информацию для новой задачи, которая, например, говорит о поиске файла в профиле bash. Это просто пример и может быть любой сценарий, но метод останется тот же.- name: Set Java home in .bash_profile lineinfile: path="{{ item.stdout }}/.bash_profile" regexp='^source "{{ java_dir }}/.bash_profile_java"' line='source "{{ java_dir }}/.bash_profile_java"' state=present with_items: - "{{ user_home.results }}" loop_control: label: "{{ item.stdout }}"
Я установил факт для java_dir в /usr/java / latest в том же playbook.
массив user_home.результаты будут содержать сведения о задаче получить домашний каталог. Теперь мы перебираем этот массив и вынимаем значение stdout, которое содержит путь к домашнему каталогу.
Я поставил loop_control для печати только домашний каталог, иначе он будет печатать весь массив.
С помощью этого процесса, мы можем гарантировать, что если n количество пользователей есть, мы можем следовать этому методу, и все будет позаботились.
Примечание: я начал изучать Ansible, в случае, если таковые имеются терминология, которую я использовал, неверна, пожалуйста, извините. Я провел некоторое время, выясняя, как это сделать и думал разделить.
в данный момент нет простого способа сделать это в Ansible, и именно поэтому вы следует добавить свои голоса в этот вопрос
https://github.com/ansible/ansible/issues/15901
в то время как вы можете использовать этот обходной путь:https://stackoverflow.com/a/33343455/99834 Вы не должны забывать, чтобы отправить обратную связь, что вы хотите, чтобы это было легко использовать.