¿Cómo es posible mover / cambiar el nombre de un archivo / directorio utilizando un módulo Ansible en un sistema remoto? No quiero usar el comando / tareas de shell y no quiero copiar el archivo del sistema local al sistema remoto.
¿Cómo es posible mover / cambiar el nombre de un archivo / directorio utilizando un módulo Ansible en un sistema remoto? No quiero usar el comando / tareas de shell y no quiero copiar el archivo del sistema local al sistema remoto.
Respuestas:
El módulo de archivo no copia archivos en el sistema remoto. El módulo src solo usa el parámetro src al crear un enlace simbólico a un archivo.
Si desea mover / cambiar el nombre de un archivo por completo en un sistema remoto, lo mejor es usar el módulo de comando para invocar el comando apropiado:
- name: Move foo to bar
command: mv /path/to/foo /path/to/bar
Si quieres ponerte elegante, primero puedes usar el módulo de estadísticas para verificar que 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
opción para el command
módulo (documentado aquí )? Parece que esa opción haría que Ansible verifique primero.
removes: /path/to/foo
y creates: /path/to/bar
. @Fonant ya mencionó esto como comentario en otra respuesta, pero como esta es la aceptada, quiero señalarlo nuevamente.
Desde la versión 2.0 , en el módulo de copia puede usarremote_src
parámetro.
Si True
irá a la máquina remota / objetivo para el src.
- name: Copy files from foo to bar
copy: remote_src=True src=/path/to/foo dest=/path/to/bar
Si desea mover el archivo, debe eliminar el archivo antiguo con el módulo de archivo
- name: Remove old files foo
file: path=/path/to/foo state=absent
Desde la versión 2.8, el módulo de copia remote_src
admite la copia recursiva.
command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
He encontrado útil la opción de creación en el módulo de comando. Qué tal esto:
- name: Move foo to bar
command: creates="path/to/bar" mv /path/to/foo /path/to/bar
Solía hacer un enfoque de 2 tareas usando estadísticas como sugiere Bruce P. Ahora hago esto como una tarea con crea. Creo que esto es mucho más claro.
command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Otra opción que me ha funcionado bien es usar el módulo de sincronización . Luego, elimine el directorio original utilizando el módulo de archivo.
Aquí hay un ejemplo de los documentos:
- synchronize:
src: /first/absolute/path
dest: /second/absolute/path
archive: yes
delegate_to: "{{ inventory_hostname }}"
dest
se accede a través de SSH incluso si el directorio está en la misma máquina.
Otra forma de lograr esto es usar file
con state: hard
.
Este es un ejemplo que puse a trabajar:
- name: Link source file to another destination
file:
src: /path/to/source/file
path: /target/path/of/file
state: hard
Sin embargo, solo se probó en localhost (OSX), pero también debería funcionar en Linux. No puedo decir para Windows.
Tenga en cuenta que se necesitan rutas absolutas. De lo contrario, no me dejaría crear el enlace. Además, no puede cruzar los sistemas de archivos, por lo que puede fallar el trabajo con cualquier medio montado.
El enlace duro es muy similar al movimiento, si luego elimina el archivo fuente:
- name: Remove old file
file:
path: /path/to/source/file
state: absent
Otro beneficio es que los cambios persisten cuando estás en medio de una jugada. Entonces, si alguien cambia la fuente, cualquier cambio se refleja en el archivo de destino.
Puede verificar el número de enlaces a un archivo a través de ls -l
. El número de enlaces duros se muestra junto al modo (por ejemplo, rwxr-xr-x 2, cuando un archivo tiene 2 enlaces).
Bruce no estaba intentando establecer el destino para verificar si se movía o no el archivo si ya estaba allí; se estaba asegurando de que el archivo a mover realmente existiera antes de intentar el mv.
Si su interés, como el de Tom, es moverse solo si el archivo aún no existe, creo que aún deberíamos integrar el cheque de Bruce en la mezcla:
- 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
Así es como lo hice funcionar para mí:
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
el libro de jugadas anterior verificará si existe el archivo abc.xts antes de mover el archivo a la carpeta tmp.
when: stat_result.stat.exists == True
. Solo usar when: stat_result.stat.exists
es lo suficientemente bueno.
== True
porque siempre estoy haciendo algo cuando no se encuentra el archivo o == False
.
stat
exists
propiedad del módulo , se devuelve un boolean
valor. Entonces, si solo coloca when: stat_result.stat.exists
eso, satisfará la condición si el archivo está presente, que también es idéntico when: stat_result.stat.exists == True
pero con más textos y verificación condicional innecesaria.
Esto puede parecer excesivo, pero si desea evitar usar el módulo de comando (lo cual hago, porque usar el comando no es idempotente) puede usar una combinación de copiar y desarchivar.
Puedes hacerlo por -
Uso del comando ad hoc
ansible all -m command -a" mv /path/to/foo /path/to/bar"
O usted si quiere hacerlo usando el libro de jugadas
- name: Move File foo to destination bar
command: mv /path/to/foo /path/to/bar
Sé que es un tema de AÑOS , pero me sentí frustrado y creé un papel para que yo hiciera exactamente esto para una lista arbitraria de archivos. Extienda como mejor le parezca:
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
Tenga en cuenta que la vinculación física es preferible a copiar aquí, ya que inherentemente conserva la propiedad y los permisos (además de no consumir más espacio en disco para una segunda copia del archivo).