Estoy ejecutando un script ansible localhost
para copiar una carpeta a otra ubicación. Sin embargo,
- name: Copy Network
become: yes
become_user: root
copy:
src: /d/
dest: "/dest/d/"
mode: 0644
tags: [network]
me está dando [Errno 13] Permission denied: b'd/f1'
. Esperaba become_user
que el comando se ejecutara como root, pero no funcionó. El permiso de este archivo es 0600(root:root)
.
¿Puede darme sugerencias para acceder a este archivo y copiarlo usando ansible?
Nota:
sudo ansible-playbook p.yml
funciona perfectamente, sin embargo, no quiero usarlosudo
con el comando ansible si no es necesario y ansible tiene un truco para ello.command: cp -r /d/ /dest/d/
funciona sin agregarsudo
al comando ansible (ansible-playbook p.yml
). Sin embargo, no quiero usarlocommand
si puedo evitarlo debido a la idempotencia ycopy
el módulo tienemode
la opción requerida para la tarea.
Respuesta1
Actualización: si puede escalar el privilegio a root en localhost master, la solución es configurarlo remote_src: true
(crédito @ivandov)
- copy:
src: /d/
dest: /dest/d/
mode: '0644'
remote_src: true
become: true
become_user: root
Los detalles a continuación describen el caso en el que no puede escalar a root en localhost. Dado el archivo en localhost
shell> ll /tmp/test/d/f1
-rw-r----- 1 root root 0 Aug 25 23:23 /tmp/test/d/f1
el móduloCopiarfunciona como se esperaba
- copy:
src: /tmp/test/d/
dest: /tmp/test/dest/
become: true
become_user: root
Primero, intenta leer el archivo y falla.
fatal: [localhost]: ¡FALLÓ! => msg: 'se produjo un error al intentar leer el archivo ''/tmp/test/d/f1'': [Errno 13] Permiso denegado: b''/tmp/test/d/f1''. [Errno 13] Permiso denegado: b''/tmp/test/d/f1'''
Por defecto, móduloCopiarcopia archivos desrc(ruta local a un archivo para copiar al servidor remoto) adestino(ruta absoluta remota donde se debe copiar el archivo). En este caso, become: true
significa que Ansible aumenta los privilegios en el host remoto, pero no en el maestro del host local. A pesar de que la tarea se ejecuta en el host local, es decir, tanto el host maestro como el remoto son host local, sin remote_src: true
la configuración become: true
se aplica solo a escribir el archivo, no a leerlo. Si no puede escalar a root en la configuración de localhostremote_src: true
- copy:
src: /tmp/test/d/
dest: /tmp/test/dest/
remote_src: true
become: true
become_user: root
fallará
fatal: [localhost]: ¡FALLÓ! => cambiado=falso ansible_facts: discover_interpreter_python: /usr/bin/python3 module_stderr: |- sudo: se requiere una contraseña module_stdout: '' msg: |- FALLO DEL MÓDULO Consulte stdout/stderr para conocer el error exacto rc: 1
P:"¿Existe alguna solución para esto?"
R: Sin escalar a la raíz, no hay solución alternativa. Violaría la propiedad y los permisos de los archivos. Por ejemplo, dado el archivo en el controlador
shell> ll f1
-rw-rw---- 1 root root 0 Sep 13 18:17 f1
El siguiente manual fue iniciado por un usuario sin privilegios.
shell> cat playbook.yml
- hosts: test_01
become: true
tasks:
- copy:
src: f1
dest: /tmp
se estrellará
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'''
Si no puede escalar a root en el servidor maestro local, la solución es hacer que el archivo sea legible para el usuario que ejecuta el libro de estrategias.
Respuesta2
A partir de la respuesta de Vladimir, ¡en realidad HAY una solución alternativa simple!
El comentario a continuación (y el énfasis que agregué en negrita) fue la clave.
En la copia del módulo, conviértase en: sí se aplica solo para escribir el archivono leerlo.
Simplemente use remote_src: true
, aunque esté copiando el archivo localmente. Esto hace que become
aumente los privilegios correctamente al leer el src
archivo/directorio de la máquina local porque lo trata src
como una máquina remota y aplica correctamente la escalada de privilegios.
- 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]
Respuesta3
tl;dr: Ansible become: root
se aplica a la máquina de destino, no al host de Ansible que ejecuta el libro de jugadas. Son posibles soluciones alternativas.
escribí una respuestaaquípara solucionar este problema para un solo archivo: el host Ansible que ejecuta el libro de estrategias no genera sus propios permisos root
con become: root
; esto sólo se aplica a la máquina de destino. En la pregunta original, ambos lo son, localhost
pero creo que este comportamiento todavía se aplica; considérelo como una root
"fuente" no privilegiada y un root
destino privilegiado.
La solución utiliza delegate_to: localhost
el slurp
archivo requerido en la memoria: delegate_to:
permite become: root
hacer su magia localmente y luego escribir el archivo guardado en la máquina de destino.
Sin embargo, la pregunta original se refiere a cómo hacer esto para directorios: slurp
también se ha discutido la creación de directoriosaquílo que debería proporcionar un punto de partida adecuado cuando se combina con la solución por archivo slurp
, especialmente. tenga en cuenta el comentario de @guzmonne sobre esa respuesta con respecto a. construir una lista de archivos slurp
antes de usar la solución alternativa por archivo (que no es excelente, pero puede ser preferible a alterar los permisos de archivos/directorios).