我正在運行一個 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,解決方案是設定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
讀取檔案/目錄時正確升級權限,因為它將 視為遠端電腦並正確應用權限升級。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 - Ansiblebecome: root
適用於目標機器,而不適用於執行 playbook 的 Ansible 主機。解決方法是可能的。
我寫了一個答案這裡若要解決單一檔案的此問題:執行 playbook 的 Ansible 主機不會將自己的權限提升為root
with become: root
;這僅適用於目標機器。在最初的問題中,兩者都是,localhost
但我認為這種行為仍然適用,將其視為非特權root
「來源」和root
特權目標。
此解決方案將delegate_to: localhost
所需slurp
的檔案寫入記憶體 -delegate_to:
能夠become: root
在本地發揮其魔力,然後將已儲存的檔案寫入目標電腦。
最初的問題詢問如何對目錄執行此操作:slurp
ing 目錄也已討論過這裡當與每個文件解決方案結合使用時,它應該提供一個合適的起點slurp
,特別是。請注意@guzmonne對該答案的評論。slurp
在使用每個文件的解決方法之前建立文件列表(這不是很好,但可能比更改文件/目錄權限更可取)。