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

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

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 интересные вещи

  • определение ID пользователя

    • os.setegid - Set the current process’s effective group id.

    • getpass.getuser()- Return the “login name” of the user.

  • pwent.pw_dir - User home directory

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

Есть же ~

Зачем так сложно? можно же просто взять ~. Можно, но не всегда, Т.к. ~ это сущность 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/post/575880/


Интересные статьи

Интересные статьи

В русском языке порядок слов в предложении практически не важен. «Я тебя люблю», «Я люблю тебя», «Тебя я люблю», «Люблю я тебя». Нюансы есть, но при этом каждый из э...
Знаете, что общего между ситуацией с уничтожением антенн сотовой связи и последней лентой Тарантино «Однажды в Голливуде»? Они оба делят людей на два противоположных лагеря. Читать ...
Сравнивать CRM системы – дело неблагодарное. Очень уж сильно они отличаются в целях создания, реализации, в деталях.
На Хабре есть дайджесты анонсов для Москвы и Санкт-Петербурга, а для Нижнего Новгорода пока почему-то нет, хотя здесь и IT-компаний много (очень много!), и событий хватает всех форматов и для люб...
Прим. перев.: Ведущий инженер из компании Zalando — Henning Jacobs — не раз замечал у пользователей Kubernetes проблемы в понимании предназначения liveness (и readiness) probes и их корректного п...