Como é possível mover / renomear um arquivo / diretório usando um módulo Ansible em um sistema remoto? Não quero usar as tarefas de comando / shell e não quero copiar o arquivo do sistema local para o sistema remoto.
Como é possível mover / renomear um arquivo / diretório usando um módulo Ansible em um sistema remoto? Não quero usar as tarefas de comando / shell e não quero copiar o arquivo do sistema local para o sistema remoto.
Respostas:
O módulo de arquivo não copia arquivos no sistema remoto. O parâmetro src é usado apenas pelo módulo de arquivo ao criar um link simbólico para um arquivo.
Se você deseja mover / renomear um arquivo inteiramente em um sistema remoto, sua melhor aposta é usar o módulo de comando para chamar o comando apropriado:
- name: Move foo to bar
command: mv /path/to/foo /path/to/bar
Se você quiser ser extravagante, poderá primeiro usar o módulo stat para verificar se o foo realmente existe:
- name: stat foo
stat: path=/path/to/foo
register: foo_stat
- name: Move foo to bar
command: mv /path/to/foo /path/to/bar
when: foo_stat.stat.exists
removes
opção do command
módulo (documentada aqui )? Parece que essa opção faria o Ansible checar primeiro.
removes: /path/to/foo
e creates: /path/to/bar
. A @Fonant já mencionou isso como comentário em outra resposta, mas como essa é a aceita, quero apontar novamente.
A partir da versão 2.0 , no módulo de cópia, você pode usar o remote_src
parâmetro
Se True
for para a máquina remota / de destino do src.
- name: Copy files from foo to bar
copy: remote_src=True src=/path/to/foo dest=/path/to/bar
Se você deseja mover o arquivo, é necessário excluir o arquivo antigo com o módulo de arquivo
- name: Remove old files foo
file: path=/path/to/foo state=absent
A partir da versão 2.8, o módulo de cópia remote_src
suporta cópia recursiva.
command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Eu encontrei a opção de criação no módulo de comando útil. Que tal agora:
- name: Move foo to bar
command: creates="path/to/bar" mv /path/to/foo /path/to/bar
Eu costumava fazer uma abordagem de duas tarefas usando estatísticas, como sugere Bruce P. Agora eu faço isso como uma tarefa com cria. Eu acho que isso é muito mais claro.
command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Outra opção que funcionou bem para mim é usar o módulo de sincronização . Em seguida, remova o diretório original usando o módulo de arquivo.
Aqui está um exemplo dos documentos:
- synchronize:
src: /first/absolute/path
dest: /second/absolute/path
archive: yes
delegate_to: "{{ inventory_hostname }}"
dest
é acessado através do SSH, mesmo que o diretório esteja na mesma máquina.
Outra maneira de conseguir isso é usando file
com state: hard
.
Este é um exemplo que eu tenho que trabalhar:
- name: Link source file to another destination
file:
src: /path/to/source/file
path: /target/path/of/file
state: hard
Apenas testado no localhost (OSX), mas deve funcionar também no Linux. Eu não posso dizer para o Windows.
Observe que caminhos absolutos são necessários. Senão, não me deixaria criar o link. Além disso, você não pode atravessar sistemas de arquivos; portanto, o trabalho com qualquer mídia montada pode falhar.
O hardlink é muito semelhante ao movimento, se você remover o arquivo de origem depois:
- name: Remove old file
file:
path: /path/to/source/file
state: absent
Outro benefício é que as mudanças persistem quando você está no meio de uma peça. Portanto, se alguém alterar a fonte, qualquer alteração será refletida no arquivo de destino.
Você pode verificar o número de links para um arquivo via ls -l
. O número de links físicos é mostrado próximo ao modo (por exemplo, rwxr-xr-x 2, quando um arquivo possui 2 links).
Bruce não estava tentando determinar o destino para verificar se movia ou não o arquivo, se ele já estava lá; ele estava se certificando de que o arquivo a ser movido realmente existia antes de tentar o mv.
Se o seu interesse, como o de Tom, é apenas mudar se o arquivo ainda não existir, acho que ainda devemos integrar o cheque de Bruce na mistura:
- name: stat foo
stat: path=/path/to/foo
register: foo_stat
- name: Move foo to bar
command: creates="path/to/bar" mv /path/to/foo /path/to/bar
when: foo_stat.stat.exists
Foi assim que consegui trabalhar para mim:
Tasks:
- name: checking if the file 1 exists
stat:
path: /path/to/foo abc.xts
register: stat_result
- name: moving file 1
command: mv /path/to/foo abc.xts /tmp
when: stat_result.stat.exists == True
o manual acima, verificará se o arquivo abc.xts existe antes de mover o arquivo para a pasta tmp.
when: stat_result.stat.exists == True
. Apenas usar when: stat_result.stat.exists
é bom o suficiente.
== True
porque estou sempre fazendo algo quando o arquivo não é encontrado ou == False
.
stat
exists
propriedade do módulo , retorna um boolean
valor. Portanto, se você colocar apenas when: stat_result.stat.exists
isso, satisfará a condição se o arquivo estiver presente, o que também é idêntico, when: stat_result.stat.exists == True
mas com mais textos e verificação condicional desnecessária.
Isso pode parecer um exagero, mas se você quiser evitar o uso do módulo de comando (o que eu faço, porque ele não é idempotente), você pode usar uma combinação de copiar e desarquivar.
Você pode fazer isso por -
Usando o comando ad hoc
ansible all -m command -a" mv /path/to/foo /path/to/bar"
Ou você, se você quiser fazê-lo usando o playbook
- name: Move File foo to destination bar
command: mv /path/to/foo /path/to/bar
Sei que é um tópico antigo de ANOS , mas fiquei frustrado e criei uma função para fazer exatamente isso em uma lista arbitrária de arquivos. Estenda como achar melhor:
main.yml
- name: created destination directory
file:
path: /path/to/directory
state: directory
mode: '0750'
- include_tasks: move.yml
loop:
- file1
- file2
- file3
move.yml
- name: stat the file
stat:
path: {{ item }}
register: my_file
- name: hard link the file into directory
file:
src: /original/path/to/{{ item }}
dest: /path/to/directory/{{ item }}
state: hard
when: my_file.stat.exists
- name: Delete the original file
file:
path: /original/path/to/{{ item }}
state: absent
when: my_file.stat.exists
Observe que a vinculação física é preferível à cópia aqui, pois preserva inerentemente a propriedade e as permissões (além de não consumir mais espaço em disco para uma segunda cópia do arquivo).