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.ymlsudo工作完美,但是,如果不需要,我不想與 ansible 命令一起使用,並且 ansible 有一個技巧。

  • command: cp -r /d/ /dest/d/無需附加sudo到 ansible 命令 ( ansible-playbook p.yml) 即可運作。但是,如果我可以幫助它,我不想使用command它,因為冪等性和copy模組具有mode任務所需的選項。

答案1

更新:如果您可以將權限升級為本機上的root,解決方案是設定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

首先,它嘗試讀取文件但失敗

致命:[localhost]:失敗! => msg: '嘗試讀取檔案 ''/tmp/test/d/f1'' 時發生錯誤: [Errno 13] 權限被拒絕: b''/tmp/test/d/f1''。 [Errno 13] 權限被拒絕:b''/tmp/test/d/f1'''

預設情況下,模組複製複製文件來自原始碼(要複製到遠端伺服器的檔案的本機路徑)到目的地(檔案應複製到的遠端絕對路徑)。在這種情況下,become: true表示 Ansible 會提升遠端主機上的權限,但不會提升本機上的權限。儘管該任務在本機上運行,即主主機和遠端主機都是本機主機,但remote_src: true該設定become: true僅適用於寫入檔案而不適用於讀取檔案。如果您無法在 localhost 設定上升級到 rootremote_src: true

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

將失敗

致命:[localhost]:失敗! => 更改 = false ansible_facts: Discover_interpreter_python: /usr/bin/python3 module_stderr: |- sudo: 需要密碼 module_stdout: '' msg: |- MODULE FAILURE 請參閱 stdout/stderr: 了解確切的錯誤 rcrced: 1 請參閱 stdout/stderr: 1


問:“有什麼解決辦法嗎?”

答:如果不升級到根目錄,就沒有解決方法。這會侵犯文件的所有權和權限。例如,給定控制器上的文件

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'''

如果您無法升級到 localhost master 上的 root,解決方案是讓執行 playbook 的使用者可以讀取該檔案。

答案2

根據弗拉基米爾的回答,實際上有一個簡單的解決方法!

以下的評論(以及我用粗體添加的重點)是關鍵。

在模組copy中,變成:yes僅適用於寫入文件不去讀它

remote_src: true即使您在本地複製文件,也只需使用。這會導致從本機電腦become讀取檔案/目錄時正確升級權限,因為它將 視為遠端電腦並正確應用權限升級。srcsrc

- 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 - Ansiblebecome: root適用於目標機器,而不適用於執行 playbook 的 Ansible 主機。解決方法是可能的。

我寫了一個答案這裡若要解決單一檔案的此問題:執行 playbook 的 Ansible 主機不會將自己的權限提升為rootwith become: root;這僅適用於目標機器。在最初的問題中,兩者都是,localhost但我認為這種行為仍然適用,將其視為非特權root「來源」和root特權目標。

此解決方案將delegate_to: localhost所需slurp的檔案寫入記憶體 -delegate_to:能夠become: root在本地發揮其魔力,然後將已儲存的檔案寫入目標電腦。

最初的問題詢問如何對目錄執行此操作:slurping 目錄也已討論過這裡當與每個文件解決方案結合使用時,它應該提供一個合適的起點slurp,特別是。請注意@guzmonne對該答案的評論。slurp在使用每個文件的解決方法之前建立文件列表(這不是很好,但可能比更改文件/目錄權限更可取)。

相關內容