Estou executando um script ansible localhost
para copiar uma pasta para outro local. No entanto,
- name: Copy Network
become: yes
become_user: root
copy:
src: /d/
dest: "/dest/d/"
mode: 0644
tags: [network]
está me dando [Errno 13] Permission denied: b'd/f1'
. Eu esperava become_user
que o comando fosse executado como root, não funcionou. A permissão deste arquivo é 0600(root:root)
.
Você pode me dar dicas para obter acesso a este arquivo e copiá-lo usando ansible?
Observação:
sudo ansible-playbook p.yml
funciona perfeitamente, no entanto, não quero usarsudo
o comando ansible se não for necessário e o ansible tiver um truque para isso.command: cp -r /d/ /dest/d/
funciona sem anexarsudo
ao comando ansible (ansible-playbook p.yml
). No entanto, não quero usarcommand
se puder ajudar por causa da idempotência ecopy
o módulo temmode
a opção necessária para a tarefa.
Responder1
Atualização: Se você puder escalar o privilégio para root no localhost master, a solução é definir remote_src: true
(crédito @ivandov)
- copy:
src: /d/
dest: /dest/d/
mode: '0644'
remote_src: true
become: true
become_user: root
Os detalhes abaixo descrevem o caso em que você não consegue escalar para root no host local. Dado o arquivo em localhost
shell> ll /tmp/test/d/f1
-rw-r----- 1 root root 0 Aug 25 23:23 /tmp/test/d/f1
o módulocópia defunciona como esperado
- copy:
src: /tmp/test/d/
dest: /tmp/test/dest/
become: true
become_user: root
Primeiro, ele tenta ler o arquivo e falha
fatal: [localhost]: FALHA! => msg: 'ocorreu um erro ao tentar ler o arquivo ''/tmp/test/d/f1'': [Erro 13] Permissão negada: b''/tmp/test/d/f1''. [Errno 13] Permissão negada: b''/tmp/test/d/f1'''
Por padrão, módulocópia decopia arquivos defonte(caminho local para um arquivo a ser copiado para o servidor remoto) paradestino(caminho absoluto remoto para onde o arquivo deve ser copiado). Nesse caso, become: true
significa que o Ansible escala privilégios no host remoto, mas não no host local mestre. Apesar de a tarefa estar sendo executada em localhost, ou seja, tanto o host mestre quanto o host remoto são localhost, sem remote_src: true
a configuração become: true
se aplica apenas à gravação do arquivo e não à sua leitura. Se você não conseguir escalar para root na configuração localhostremote_src: true
- copy:
src: /tmp/test/d/
dest: /tmp/test/dest/
remote_src: true
become: true
become_user: root
vai falhar
fatal: [localhost]: FALHA! => alterado = falso ansible_facts:discovered_interpreter_python: /usr/bin/python3 module_stderr: |- sudo: uma senha é necessária module_stdout: '' msg: |- MODULE FAILURE Consulte stdout/stderr para obter o erro exato rc: 1
P:"Existe alguma solução alternativa para isso?"
R: Sem o escalonamento para a raiz, não há solução alternativa. Isso violaria a propriedade e as permissões dos arquivos. Por exemplo, dado o arquivo no controlador
shell> ll f1
-rw-rw---- 1 root root 0 Sep 13 18:17 f1
O manual abaixo foi iniciado por um usuário sem privilégios
shell> cat playbook.yml
- hosts: test_01
become: true
tasks:
- copy:
src: f1
dest: /tmp
vai falhar
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'''
Se você não conseguir escalar para root no mestre localhost, a solução é tornar o arquivo legível para o usuário que executa o manual.
Responder2
Com base na resposta de Vladimir, EXISTE uma solução alternativa simples!
O comentário abaixo (e a ênfase que adicionei em negrito) foi a chave.
Na cópia do módulo, torne-se: sim aplica-se apenas à gravação do arquivonão para ler.
Basta usar remote_src: true
, mesmo que você esteja copiando o arquivo localmente. Isso faz com que o become
privilégio seja escalonado corretamente ao ler o src
arquivo/diretório da máquina local porque ele o trata src
como uma máquina remota e aplica corretamente o escalonamento de privilégios.
- 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]
Responder3
dr - O Ansible become: root
se aplica à máquina de destino, não ao host Ansible que executa o playbook. Soluções alternativas são possíveis.
Eu escrevi uma respostaaquipara resolver esse problema para um único arquivo: O host Ansible que executa o playbook não aumenta suas próprias permissões para root
with become: root
; isso se aplica apenas à máquina de destino. Na pergunta original, ambos são, localhost
mas acho que esse comportamento ainda se aplica, pense nele como uma root
'fonte' não privilegiada e um root
alvo privilegiado.
A solução usa delegate_to: localhost
o slurp
arquivo necessário na memória - delegate_to:
permite become: root
fazer sua mágica localmente e, em seguida, gravar o arquivo salvo na máquina de destino.
A pergunta original pergunta sobre como fazer isso para diretórios: slurp
ing diretórios também foi discutidoaquique deve fornecer um ponto de partida adequado quando combinado com a solução por arquivo slurp
, esp. observe o comentário de @guzmonne sobre essa resposta. construir uma lista de arquivos slurp
antes de usar a solução alternativa por arquivo (o que não é ótimo, mas pode ser preferível a alterar as permissões de arquivo/diretório).