Comment déplacer / renommer un fichier / répertoire à l'aide d'un module Ansible sur un système distant? Je ne veux pas utiliser les tâches de commande / shell et je ne veux pas copier le fichier du système local vers le système distant.
Comment déplacer / renommer un fichier / répertoire à l'aide d'un module Ansible sur un système distant? Je ne veux pas utiliser les tâches de commande / shell et je ne veux pas copier le fichier du système local vers le système distant.
Réponses:
Le module de fichiers ne copie pas les fichiers sur le système distant. Le paramètre src n'est utilisé que par le module de fichiers lors de la création d'un lien symbolique vers un fichier.
Si vous souhaitez déplacer / renommer un fichier entièrement sur un système distant, le mieux est d'utiliser le module de commande pour appeler simplement la commande appropriée:
- name: Move foo to bar
command: mv /path/to/foo /path/to/bar
Si vous voulez devenir sophistiqué, vous pouvez d'abord utiliser le module stat pour vérifier que foo existe réellement:
- 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
option du command
module (documentée ici )? Il semble que cette option ferait d'abord vérifier Ansible.
removes: /path/to/foo
et creates: /path/to/bar
. @Fonant a déjà mentionné cela comme un commentaire sur une autre réponse, mais comme c'est la réponse acceptée, je tiens à le souligner à nouveau.
À partir de la version 2.0 , dans le module de copie, vous pouvez utiliser le remote_src
paramètre.
S'il True
ira à la machine distante / cible pour le src.
- name: Copy files from foo to bar
copy: remote_src=True src=/path/to/foo dest=/path/to/bar
Si vous souhaitez déplacer un fichier, vous devez supprimer l'ancien fichier avec le module de fichiers
- name: Remove old files foo
file: path=/path/to/foo state=absent
À partir de la version 2.8, le module de copie remote_src
prend en charge la copie récursive.
command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
J'ai trouvé l'option create dans le module de commande utile. Que dis-tu de ça:
- name: Move foo to bar
command: creates="path/to/bar" mv /path/to/foo /path/to/bar
J'avais l'habitude de faire une approche en 2 tâches en utilisant des statistiques comme le suggère Bruce P. Maintenant, je fais cela comme une tâche avec create. Je pense que c'est beaucoup plus clair.
command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Une autre option qui a bien fonctionné pour moi est d'utiliser le module de synchronisation . Supprimez ensuite le répertoire d'origine à l'aide du module de fichiers.
Voici un exemple tiré de la documentation:
- synchronize:
src: /first/absolute/path
dest: /second/absolute/path
archive: yes
delegate_to: "{{ inventory_hostname }}"
dest
est accessible via SSH même si le répertoire est sur la même machine.
Une autre façon d'y parvenir est d'utiliser file
avec state: hard
.
Voici un exemple que j'ai eu à travailler:
- name: Link source file to another destination
file:
src: /path/to/source/file
path: /target/path/of/file
state: hard
Testé uniquement sur localhost (OSX), mais devrait également fonctionner sur Linux. Je ne peux pas dire pour Windows.
Notez que des chemins absolus sont nécessaires. Sinon, cela ne me laisserait pas créer le lien. De plus, vous ne pouvez pas traverser les systèmes de fichiers, donc travailler avec n'importe quel support monté peut échouer.
Le lien dur est très similaire au déplacement, si vous supprimez le fichier source par la suite:
- name: Remove old file
file:
path: /path/to/source/file
state: absent
Un autre avantage est que les changements sont conservés lorsque vous êtes au milieu d'une pièce. Donc, si quelqu'un change la source, tout changement est reflété dans le fichier cible.
Vous pouvez vérifier le nombre de liens vers un fichier via ls -l
. Le nombre de liens physiques est affiché à côté du mode (par exemple rwxr-xr-x 2, lorsqu'un fichier a 2 liens).
Bruce n'essayait pas de déclarer la destination pour vérifier s'il fallait déplacer le fichier s'il était déjà là; il s'assurait que le fichier à déplacer existait réellement avant d'essayer le mv.
Si votre intérêt, comme celui de Tom, est de ne bouger que si le fichier n'existe pas déjà, je pense que nous devrions quand même intégrer le chèque de Bruce dans le mix:
- 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
Voici comment je l'ai fait fonctionner pour moi:
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
le playbook ci-dessus, vérifiera si le fichier abc.xts existe avant de déplacer le fichier vers le dossier tmp.
when: stat_result.stat.exists == True
. Il suffit d’utiliser when: stat_result.stat.exists
.
== True
car je fais toujours quelque chose lorsque le fichier n'est pas trouvé ou == False
.
stat
exists
propriété du module renvoie une boolean
valeur. Donc, si vous ne mettez when: stat_result.stat.exists
que cela remplira la condition si le fichier est présent, qui est également identique pour when: stat_result.stat.exists == True
mais avec plus de textes et une vérification conditionnelle inutile.
Cela peut sembler exagéré, mais si vous voulez éviter d'utiliser le module de commande (ce que je fais, parce que l'utilisation de la commande n'est pas idempotente), vous pouvez utiliser une combinaison de copie et de désarchivage.
Vous pouvez le faire en -
Utilisation de la commande ad hoc
ansible all -m command -a" mv /path/to/foo /path/to/bar"
Ou vous si vous voulez le faire en utilisant playbook
- name: Move File foo to destination bar
command: mv /path/to/foo /path/to/bar
Je sais que c'est un AN vieux sujet, mais je suis frustré et construit un rôle pour moi - même de faire exactement cela pour une liste arbitraire de fichiers. Prolongez comme bon vous semble:
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
Notez que la liaison matérielle est préférable à la copie ici, car elle préserve intrinsèquement la propriété et les autorisations (en plus de ne pas consommer plus d'espace disque pour une deuxième copie du fichier).