Ich führe ein Ansible-Skript aus, localhost
um einen Ordner an einen anderen Ort zu kopieren. Allerdings
- name: Copy Network
become: yes
become_user: root
copy:
src: /d/
dest: "/dest/d/"
mode: 0644
tags: [network]
gibt mir [Errno 13] Permission denied: b'd/f1'
. Ich hatte erwartet, become_user
dass der Befehl als Root ausgeführt wird, hat aber nicht funktioniert. Die Berechtigung dieser Datei ist 0600(root:root)
.
Können Sie mir bitte Hinweise geben, wie ich auf diese Datei zugreifen kann, um sie mit Ansible zu kopieren?
Notiz:
sudo ansible-playbook p.yml
funktioniert perfekt, ich möchte es jedoch nicht mit Ansible-Befehlen verwenden,sudo
wenn es nicht erforderlich ist und Ansible einen Trick dafür hat.command: cp -r /d/ /dest/d/
funktioniert ohne Anhängensudo
an den Ansible-Befehl (ansible-playbook p.yml
). Ich möchte es jedoch nicht verwenden,command
wenn ich es vermeiden kann, da Idempotenz vorliegt undcopy
das Modul übermode
die für die Aufgabe erforderliche Option verfügt.
Antwort1
Update: Wenn Sie die Berechtigung zum Rooten auf dem lokalen Host-Master erhöhen können, besteht die Lösung darin, Folgendes festzulegen remote_src: true
(Quelle: @ivandov)
- copy:
src: /d/
dest: /dest/d/
mode: '0644'
remote_src: true
become: true
become_user: root
Die folgenden Details beschreiben den Fall, wenn Sie nicht in der Lage sind, auf den lokalen Host zu gelangen. Angesichts der Datei auf dem lokalen Host
shell> ll /tmp/test/d/f1
-rw-r----- 1 root root 0 Aug 25 23:23 /tmp/test/d/f1
Das ModulKopierenfunktioniert wie erwartet
- copy:
src: /tmp/test/d/
dest: /tmp/test/dest/
become: true
become_user: root
Zuerst versucht es, die Datei zu lesen und schlägt fehl
fatal: [localhost]: FEHLGESCHLAGEN! => msg: 'beim Versuch, die Datei ''/tmp/test/d/f1'' zu lesen, ist ein Fehler aufgetreten: [Errno 13] Berechtigung verweigert: b''/tmp/test/d/f1'''. [Errno 13] Berechtigung verweigert: b''/tmp/test/d/f1'''
Standardmäßig ist das ModulKopierenkopiert Dateien vonQuelle(lokaler Pfad zu einer Datei, die auf den Remote-Server kopiert werden soll) zuZiel(absoluter Remote-Pfad, in den die Datei kopiert werden soll). In diesem Fall become: true
bedeutet dies, dass Ansible die Rechte auf dem Remote-Host erhöht, aber nicht auf dem lokalen Master-Host. Obwohl die Aufgabe auf dem lokalen Host ausgeführt wird, d. h. sowohl der Master als auch der Remote-Host lokale Hosts sind, gilt remote_src: true
die Einstellung ohne diese Einstellung become: true
nur für das Schreiben der Datei, nicht für das Lesen. Wenn Sie die Rechte auf dem lokalen Host nicht auf Root erhöhen können,remote_src: true
- copy:
src: /tmp/test/d/
dest: /tmp/test/dest/
remote_src: true
become: true
become_user: root
wird versagen
fatal: [localhost]: FEHLGESCHLAGEN! => geändert=false ansible_facts: discovered_interpreter_python: /usr/bin/python3 module_stderr: |- sudo: ein Passwort ist erforderlich module_stdout: '' msg: |- MODULFEHLER Den genauen Fehler finden Sie in stdout/stderr rc: 1
Q:„Gibt es dafür eine Problemumgehung?“
A: Ohne die Eskalation an die Root gibt es keinen Workaround. Es würde den Besitz und die Berechtigungen der Dateien verletzen. Wenn sich die Datei beispielsweise auf dem Controller befindet,
shell> ll f1
-rw-rw---- 1 root root 0 Sep 13 18:17 f1
Das folgende Playbook wurde von einem nicht privilegierten Benutzer gestartet
shell> cat playbook.yml
- hosts: test_01
become: true
tasks:
- copy:
src: f1
dest: /tmp
wird abstürzen
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'''
Wenn Sie nicht zum Root auf dem Localhost-Master eskalieren können, besteht die Lösung darin, die Datei für den Benutzer lesbar zu machen, der das Playbook ausführt.
Antwort2
Aufbauend auf Vladimirs Antwort gibt es tatsächlich eine einfache Problemumgehung!
Der folgende Kommentar (und die Hervorhebung, die ich in Fettschrift hinzugefügt habe) war der Schlüssel.
Im Modul Kopieren gilt become: yes nur für das Schreiben der Dateinicht, es zu lesen.
Verwenden Sie einfach remote_src: true
, auch wenn Sie die Datei lokal kopieren. Dadurch werden die Berechtigungen beim Lesen der Datei/des Verzeichnisses vom lokalen Computer become
korrekt erhöht, da der als Remotecomputer behandelt wird und die Berechtigungserhöhung ordnungsgemäß anwendet.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]
Antwort3
tl;dr – Ansible become: root
gilt für die Zielmaschine, nicht für den Ansible-Host, auf dem das Playbook läuft. Workarounds sind möglich.
Ich habe eine Antwort geschriebenHierum dieses Problem für eine einzelne Datei zu beheben: Der Ansible-Host, auf dem das Playbook ausgeführt wird, erhöht seine eigenen Berechtigungen nicht mit root
; become: root
dies gilt nur für die Zielmaschine. In der ursprünglichen Frage sind beide, localhost
aber ich denke, dieses Verhalten gilt immer noch. Betrachten Sie es als eine nicht- root
privilegierte „Quelle“ und ein root
-privilegiertes Ziel.
Die Lösung legt delegate_to: localhost
die slurp
erforderliche Datei im Speicher ab, sodass sie ihre Magie lokal entfalten und die gespeicherte Datei anschließend auf den Zielcomputer schreiben kann delegate_to:
.become: root
Die ursprüngliche Frage bezieht sich jedoch auf Verzeichnisse: slurp
ing-Verzeichnisse wurden ebenfalls besprochenHierDies sollte in Kombination mit der Datei-für-Datei-Lösung einen geeigneten Ausgangspunkt bieten. slurp
Beachten Sie insbesondere den Kommentar von @guzmonne zu dieser Antwort bezüglich des Erstellens einer Dateiliste slurp
vor der Verwendung der Datei-für-Datei-Lösung (die nicht so toll ist, aber einer Änderung der Datei-/Verzeichnisberechtigungen vorzuziehen sein kann).