web-dev-qa-db-fra.com

Comment déplacer / renommer un fichier en utilisant une tâche Ansible sur un système distant

Comment est-il possible de déplacer/renommer un fichier/répertoire en utilisant un module Ansible sur un système distant? Je ne souhaite pas utiliser les tâches de commande/Shell et je ne souhaite pas copier le fichier du système local vers le système distant.

175
Christian Berendt

Le module de fichiers ne copie pas les fichiers sur le système distant. Le paramètre src est uniquement utilisé par le module de fichier 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 simplement appeler la commande appropriée:

- name: Move foo to bar
  command: mv /path/to/foo /path/to/bar

Si vous voulez avoir du chic, 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
180
Bruce P

A partir de la version 2.0 , dans module de copie , vous pouvez utiliser le paramètre remote_src.

Si True, il ira à la machine distante/cible pour le code source.

- 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

A partir de la version 2.8 module de copieremote_src prend en charge la copie récursive.

195
Alex

J'ai trouvé l'option create utile dans le module de commande. 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 stat comme Bruce P le suggère. Maintenant, je fais cela comme une tâche avec crée. Je pense que c'est beaucoup plus clair.

98
Tom Ekberg

Une autre option qui a bien fonctionné pour moi utilise 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 }}"
7
Andrew Becker

Une autre méthode consiste à utiliser file avec state: hard.

Ceci est un exemple que je dois travailler:

- name: Link source file to another destination
  file:
    src: /path/to/source/file
    path: /target/path/of/file
    state: hard

Seulement testé sur localhost (OSX) cependant, mais devrait également fonctionner sur Linux. Je ne peux pas dire pour Windows.

Notez que les chemins absolus sont nécessaires. Sinon, cela ne me laisserait pas créer le lien. De plus, vous ne pouvez pas croiser les systèmes de fichiers, de sorte que tout travail sur un support monté peut échouer.

Le lien physique 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 persistés lorsque vous êtes au milieu d'une pièce. Ainsi, si quelqu'un modifie la source, toute modification est reflétée dans le fichier cible.

Vous pouvez vérifier le nombre de liens vers un fichier via ls -l. Le nombre de liens physiques est indiqué à côté du mode (par exemple, rwxr-xr-x 2, lorsqu'un fichier contient 2 liens).

5
martinczerwi

Bruce n'essayait pas d'indiquer 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 de tenter le mv.

Si votre intérêt, comme celui de Tom, est de ne déplacer que si le fichier n'existe pas déjà, je pense que nous devrions toujours intégrer le contrôle de Bruce dans le mélange:

- 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
4
gkedge

C'est comme ça que ça fonctionne 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 dans le dossier tmp.

2
eduprado

Vous pouvez le faire par -

tilisation 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
0
Dev pokhariya

Cela peut sembler excessif, mais si vous voulez éviter d'utiliser le module de commande (ce que je fais parce qu'il utilise command n'est pas idempotent), vous pouvez utiliser une combinaison de copie et de désarchive.

  1. Utilisez tar pour archiver le ou les fichiers dont vous aurez besoin. Si vous pensez à l'avenir, cela a du sens. Vous voudrez peut-être une série de fichiers dans un répertoire donné. Créez ce répertoire avec tous les fichiers et archivez-les dans un fichier .tar.
  2. Utilisez le module unarchive. Lorsque vous faites cela, avec le mot-clé destination: et remote_src:, vous pouvez copier tous vos fichiers dans un dossier temporaire pour commencer, puis les décompresser exactement à l'endroit souhaité.
0
Mark Chassy