Домашняя директория пользователя в ansible или что может быть проще? Как же вычисляется

от автора

ansible_user_dir как он получается?

Начнем с чтения сорцов и разберемся что такое ansible_user_dir

ansible использует https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/setup.py для сбора фактов, это и так все знают. Внутри модуля импортятся коллекторы https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/setup.py#L195

fact_collector = ansible_collector.get_ansible_collector(all_collector_classes=all_collector_classes,                                                          namespace=namespace,                                                          filter_spec=filter_spec,                                                          gather_subset=gather_subset,                                                          gather_timeout=gather_timeout,                                                          minimal_gather_subset=minimal_gather_subset) 

Нас интересует UserFactCollector https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/facts/default_collectors.py#L117

_general = [     PythonFactCollector,     SystemCapabilitiesFactCollector,     PkgMgrFactCollector,     OpenBSDPkgMgrFactCollector,     ServiceMgrFactCollector,     CmdLineFactCollector,     DateTimeFactCollector,     EnvFactCollector,     SshPubKeyFactCollector,     UserFactCollector ]  ...  collectors = _base + _restrictive + _general + _virtual + _hardware + _network + _extra_facts 

Теперь смотрим код коллектора https://github.com/ansible/ansible/blob/9c2f44b8848a317a2304254eba0b9b348d5034ad/lib/ansible/module_utils/facts/system/user.py#L46

class UserFactCollector(BaseFactCollector):     name = 'user'     _fact_ids = set(['user_id', 'user_uid', 'user_gid',                      'user_gecos', 'user_dir', 'user_shell',                      'real_user_id', 'effective_user_id',                      'effective_group_ids'])      def collect(self, module=None, collected_facts=None):         user_facts = {}          user_facts['user_id'] = getpass.getuser()          try:             pwent = pwd.getpwnam(getpass.getuser())         except KeyError:             pwent = pwd.getpwuid(os.getuid())          user_facts['user_uid'] = pwent.pw_uid         user_facts['user_gid'] = pwent.pw_gid         user_facts['user_gecos'] = pwent.pw_gecos         user_facts['user_dir'] = pwent.pw_dir         user_facts['user_shell'] = pwent.pw_shell         user_facts['real_user_id'] = os.getuid()         user_facts['effective_user_id'] = os.geteuid()         user_facts['real_group_id'] = os.getgid()         user_facts['effective_group_id'] = os.getgid()          return user_facts 

видим 2 интересные вещи

Вроде понятно. получили пользователя и вернули его домашнюю директорию

Есть же ~

Зачем так сложно? можно же просто взять ~. Можно, но не всегда, Т.к. ~ это сущность shell и разворачивается им. Может выстрелить когда shell явно не используется и/или требуется абсолютный путь.

Но, давайте глянем пример, что ~ и ansible_user_dir иногда могут выдать разный результат.

- tasks:     - shell: eval echo "~"       register: stdout     - name: ansible_user_dir - ~ without become in play       debug:         msg: "{{ ansible_user_dir }} - {{ stdout.stdout_lines | join(' ') }}"      - shell: eval echo "~"       become: true       become_user: lgonchar       register: stdout     - name: ~ without become in play with become in task       debug:         msg: "{{ ansible_user_dir }} - {{ stdout.stdout_lines | join(' ') }}"       become: true       become_user: lgonchar  - become: true   become_user: lgonchar   tasks:     - shell: eval echo "~"       register: stdout     - name: ansible_ansible_user_dir - ~ user_dir with become in task       debug:         msg: "{{ ansible_user_dir }} - {{ stdout.stdout_lines | join(' ') }}" 

А вот и результат работы:

TASK [ansible_user_dir - ~ without become in play]  ok: [lindev-lgonchar2.imagemaster.local] => {     "msg": "/home/deploy - /home/deploy" }  TASK [~ without become in play with become in task] changed: [lindev-lgonchar2.imagemaster.local]  TASK [ansible_ansible_user_dir - ~ user_dir with become in task] ok: [lindev-lgonchar2.imagemaster.local] => {     "msg": "/home/deploy - /home/ms/lgonchar" } 

поведение логичное. на момент сбора фактов у нас пользователь deploy поэтому он и сохраняется в ansible_user_dir

Вместо выводов

Выводов не будет. Это просто рассказ, что даже простая задача может скрывать подводные камни.


ссылка на оригинал статьи https://habr.com/ru/articles/575880/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *