Ansible Копировать модуль и стать - Отказано в доступе

Ansible Копировать модуль и стать - Отказано в доступе

Я запускаю скрипт ansible localhostдля копирования папки в другое место. Однако,

- name: Copy Network
  become: yes
  become_user: root
  copy:
    src: /d/
    dest: "/dest/d/"
    mode: 0644
  tags: [network]

дает мне [Errno 13] Permission denied: b'd/f1'. Я ожидал, become_userчто команда будет выполнена как root, не сработало. Разрешение этого файла 0600(root:root).

Можете ли вы дать мне указания, как получить доступ к этому файлу, чтобы скопировать его с помощью ansible?

Примечание:

  • sudo ansible-playbook p.ymlОднако работает отлично, я не хочу использовать sudoкоманду ansible, если она не требуется, а в ansible для этого есть свой трюк.

  • command: cp -r /d/ /dest/d/работает без добавления sudoк команде ansible ( ansible-playbook p.yml). Однако я не хочу использовать commandее, если могу помочь, из-за идемпотентности и copyу модуля есть modeопция, необходимая для задачи.

решение1

Обновление: если вы можете повысить привилегии до root на локальном хосте master, то решение заключается в установке remote_src: true(кредит @ivandov)

- copy:
    src: /d/
    dest: /dest/d/
    mode: '0644'
    remote_src: true
  become: true
  become_user: root

Ниже приведены подробности о том, как обстоит дело, когда вы не можете перейти на уровень root на локальном хосте. Учитывая файл на локальном хосте

shell> ll /tmp/test/d/f1
-rw-r----- 1 root root 0 Aug 25 23:23 /tmp/test/d/f1

модулькопияработает как и ожидалось

- copy:
    src: /tmp/test/d/
    dest: /tmp/test/dest/
  become: true
  become_user: root

Сначала он пытается прочитать файл и терпит неудачу.

fatal: [localhost]: FAILED! => msg: 'произошла ошибка при попытке чтения файла ''/tmp/test/d/f1'': [Errno 13] Отказано в доступе: b''/tmp/test/d/f1'''. [Errno 13] Отказано в доступе: b''/tmp/test/d/f1'''

По умолчанию модулькопиякопирует файлы изисточник(локальный путь к файлу для копирования на удаленный сервер)место назначения(удаленный абсолютный путь, куда следует скопировать файл). В этом случае become: trueозначает, что Ansible повышает привилегии на удаленном хосте, но не на локальном хосте master. Несмотря на то, что задача выполняется на localhost, т. е. и master, и удаленный хост являются localhost, без remote_src: trueнастройки become: trueприменяется только к записи файла, а не к его чтению. Если вы не можете повысить привилегии до root на локальном хосте, настройкаremote_src: true

- copy:
    src: /tmp/test/d/
    dest: /tmp/test/dest/
    remote_src: true
  become: true
  become_user: root

не удастся

fatal: [localhost]: СБОЙ! => changed=false ansible_facts: discover_interpreter_python: /usr/bin/python3 module_stderr: |- sudo: требуется пароль module_stdout: '' msg: |- СБОЙ МОДУЛЯ Смотрите stdout/stderr для точного кода ошибки: 1


В:«Есть ли какое-то решение?»

A: Без эскалации до корня нет обходного пути. Это нарушит права собственности и разрешения файлов. Например, учитывая файл на контроллере

shell> ll f1
-rw-rw---- 1 root root 0 Sep 13 18:17 f1

Представленная ниже инструкция была запущена непривилегированным пользователем.

shell> cat playbook.yml
- hosts: test_01
  become: true
  tasks:
    - copy:
        src: f1
        dest: /tmp

рухнет

TASK [copy] ****
fatal: [test_01]: FAILED! => 
  msg: 'an error occurred while trying to read the file ''/scratch/f1'':
       [Errno 13] Permission denied: b''/scratch/f1'''

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

решение2

Основываясь на ответе Владимира, можно сказать, что на самом деле ЕСТЬ простое решение!

Комментарий ниже (и выделенный мной жирным шрифтом текст) был ключевым.

В модуле copy, become: yes применяется только к записи файлане читать это.

Просто используйте remote_src: true, даже если вы копируете файл локально. Это заставляет becomeправильно повышать привилегии при чтении srcфайла/каталога с локальной машины, поскольку он рассматривает srcкак удаленную машину и правильно применяет повышение привилегий.

- name: Copy Network
  become: yes
  become_user: root
  copy:
    src: /d/
    dest: "/dest/d/"
    remote_src: true  # this allows become to work as expected
    mode: 0644
  tags: [network]

решение3

tl;dr - Ansible's become: rootприменяется к целевой машине, а не к хосту Ansible, на котором запущен плейбук. Возможны обходные пути.

Я написал ответздесьчтобы решить эту проблему для одного файла: Хост Ansible, на котором запущена книга сценариев, не повышает свои собственные разрешения для rootwith become: root; это относится только к целевой машине. В исходном вопросе оба варианта, localhostно я думаю, что это поведение все еще применимо, думайте о нем как о непривилегированном root«источнике» и rootпривилегированной цели.

Решение использует delegate_to: localhostдля сохранения slurpнеобходимого файла в памяти, что delegate_to:позволяет become: rootработать локально, а затем записывать сохраненный файл на целевую машину.

Однако в исходном вопросе спрашивается о том, как это сделать для каталогов: slurping directorys также обсуждалосьздесьчто должно обеспечить подходящую отправную точку в сочетании с решением для каждого файла slurp, особенно обратите внимание на комментарий @guzmonne к этому ответу относительно создания списка файлов перед slurpиспользованием обходного пути для каждого файла (что не очень хорошо, но может быть предпочтительнее изменения прав доступа к файлам/каталогам).

Связанный контент