リモートシステムでAnsibleタスクを使用してファイルを移動/名前変更する方法


202

リモートシステムのAnsibleモジュールを使用してファイル/ディレクトリを移動/名前変更するにはどうすればよいですか?コマンド/シェルタスクを使用したくないし、ローカルシステムからリモートシステムにファイルをコピーしたくありません。


コマンド/シェルを使用したくないのですか?
Nick Urban

4
上記のタスクを使用せずに方法があるかどうかを知りたかっただけです。現在、他に方法がないようです。
クリスチャンベレント2014年

1
コピーするのではなく、具体的に移動するのはなぜですか?それは、べき等のシステム状態を保証するタイプのステップというよりは、1回限りのアクションのようです。
Nick Urban

2
RPMパッケージにサンプル構成ファイルが含まれていますが、このサンプル構成ファイルを移動したいと思います。
クリスチャンベレント2014年

1
現時点では、ファイルを参照するためにシンボリックリンクを使用しています。システムがインターネットにアクセスできないため、get_urlを使用することは私にとってオプションではありません。
クリスチャンベレント2014年

回答:


201

ファイルモジュールは、リモートシステム上のファイルをコピーしません。srcパラメータは、ファイルへのシンボリックリンクを作成するときにファイルモジュールでのみ使用されます。

リモートシステム上のファイル全体を移動または名前を変更する場合は、コマンドモジュールを使用して適切なコマンドを呼び出すだけが最善です。

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

凝ったものにしたい場合は、最初にstatモジュールを使用して、fooが実際に存在することを確認します。

- 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

3
コマンドモジュールを使用しない場合、他の唯一の選択肢は、独自のカスタムモジュールを作成することです。
Bruce P

2
これはリモートファイルをコピーする現在の方法であるため、正解としてタグ付けされています。
クリスチャンベレント2014年

11
あなたが跳躍する前に見ることについて:モジュールのremovesオプションを使用しない理由はありますかcommandここに記載されています)?そのオプションは最初にAnsibleチェックを行うようです。
ジムウィッチェイ2015

2
Ansibleは変更を追跡してハンドラーに通知するため、このソリューションは最適ではありません。
2015年

3
removes: /path/to/fooおよびを使用する場合は、ファイルの存在を手動で確認する必要はありませんcreates: /path/to/bar。@Fonantはすでに別の回答に対するコメントとしてこれを述べましたが、これは受け入れられた回答なので、もう一度指摘したいと思います。
Michael Trojanek 2017

218

バージョン2.0以降、コピーモジュールでremote_srcパラメーターを使用できます。

Truesrcのリモート/ターゲットマシンに移動する場合。

- name: Copy files from foo to bar
  copy: remote_src=True src=/path/to/foo dest=/path/to/bar

ファイルを移動したい場合は、ファイルモジュールで古いファイルを削除する必要があります

- name: Remove old files foo
  file: path=/path/to/foo state=absent

バージョン2.8以降、 コピーモジュール remote_srcは再帰的なコピーをサポートしています。


29
小さな注意:「現在、remote_srcは再帰的なコピーをサポートしていません。」ansibleモジュールdocから取得。したがって、再帰的にコピーする場合は、シェル/コマンドモジュールが必要です。
klaas

23
わかりません。コピーしてから削除することは、移動することと同じではありません。まず、それはアトミックではありません。もう1つは、特に大きなファイルの場合、速度が遅くなります。私はAnsibleは初めてですが、これは本当に奇妙に思えます。
mlissner 2016

19
@alex私が言っていることは、これを行う正しい方法ではあり得ません。私は50の賛成投票に対して風上に行くつもりですが、これはクレイジーです。別の問題:権限とその他の属性が維持されない。別:コピー中にファイルが変更された場合はどうなりますか?
mlissner 2016

2
@ハミッシュダウナーとミリスナー。それがすべてのニーズに最適なソリューションであるとは言いませんでした。また、多くのファイルをコピーする場合は、コピーモジュールを使用しないでください。「コマンド/シェルタスクを使用したくない」という質問を読んでください。
Alex

7
@Alexこれは、べき等に移動するファイルに関する質問の投票で2番目に高い回答です。問題はコピーについてではありません。移動ではなくコピーには多くの問題があるため、この答えは正しくありません。だから、それは反対票を得ます。SOのエチケットは、反対票を説明することです。他の場所で述べたように、これまでのところの最良の選択肢はcommand: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Alec Wenzowski、2017年

106

コマンドモジュールの作成オプションが便利であることがわかりました。これはどう:

- name: Move foo to bar
  command: creates="path/to/bar" mv /path/to/foo /path/to/bar

Bruce Pが示唆するように、私はstatを使用して2タスクアプローチを行っていました。これをcreateの1つのタスクとして実行します。これはもっとはっきりしていると思います。


60
または、さらに良い: command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Fonant 2015

8

私にとってうまくいったもう1つのオプションは、同期モジュールの使用です。次に、ファイルモジュールを使用して元のディレクトリを削除します。

これはドキュメントの例です:

- synchronize:
    src: /first/absolute/path
    dest: /second/absolute/path
    archive: yes
  delegate_to: "{{ inventory_hostname }}"

destディレクトリが同じマシン上にあってもSSH経由でアクセスされるため、これはすべてのケースでローカルでは機能しません。
Karl Richter、

5

これを達成するためのもう一つの方法は、使用しているfilestate: hard

これは私が働いた例です:

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

ただし、localhost(OSX)でのみテストされていますが、Linuxでも動作するはずです。Windowsではわかりません。

絶対パスが必要であることに注意してください。それ以外の場合は、リンクを作成できません。また、ファイルシステムをクロスすることはできないため、マウントされたメディアの操作は失敗する可能性があります。

後でソースファイルを削除する場合、ハードリンクは移動に非常に似ています。

- name: Remove old file
  file:
    path: /path/to/source/file
    state: absent

もう1つの利点は、プレイの最中に変更が永続化されることです。したがって、誰かがソースを変更した場合、変更はすべてターゲットファイルに反映されます。

を介して、ファイルへのリンクの数を確認できますls -l。モードの横にハードリンクの数が表示されます(たとえば、ファイルに2つのリンクがある場合、rwxr-xr-x 2)。


2
残念ながら、これはディレクトリでは機能しません。ハードリンクはディレクトリに許可されていないためです(((
Drew

1
この回答では、ターゲットシステムについて、特にsrcとdestの両方が同じパーティション上にあると想定しています。これは正しくない可能性があるため、この回答は使用しないでください。
ミッキー、

4

Bruceは、ファイルがすでにそこにある場合に、ファイルを移動するかどうかを確認するために宛先を統計することを試みていませんでした。彼は、mvを試す前に、移動するファイルが実際に存在することを確認していました。

Tomのように、ファイルがまだ存在しない場合にのみ移動することに関心がある場合は、Bruceのチェックをミックスに統合する必要があります。

- 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

3

これは私がそれを私のために機能させる方法です:

  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

上記のプレイブックでは、ファイルをtmpフォルダーに移動する前に、ファイルabc.xtsが存在するかどうかを確認します。


3
使用する必要はありませんwhen: stat_result.stat.exists == True。使うwhen: stat_result.stat.existsだけで十分です。
kuttumiah

私は通常== True、ファイルが見つからないときや何かが見つからないときに何かをしているので、それを使用します== False
エドゥプラド

モジュールプロパティの公式ドキュメントページにstat よるとexistsboolean値が返されます。つまり、when: stat_result.stat.existsファイルが存在する場合にのみ条件を満たしますが、これも同じですwhen: stat_result.stat.exists == Trueが、テキストが多く、不要な条件チェックが行われます。
kuttumiah

0

これはやり過ぎのように思えるかもしれませんが、コマンドモジュールの使用を避けたい場合は(コマンドの使用はべき等ではないため、これを行います)、コピーとアーカイブ解除の組み合わせを使用できます。

  1. tarを使用して、必要なファイルをアーカイブします。あなたが先を考えれば、これは実際に理にかなっています。特定のディレクトリに一連のファイルが必要な場合があります。すべてのファイルでそのディレクトリを作成し、それらをtarにアーカイブします。
  2. unarchiveモジュールを使用します。これを行う場合は、destination:およびremote_src:キーワードとともに、すべてのファイルを一時フォルダーにコピーして開始し、目的の場所に正確に解凍できます。

tarを使用したアーカイブにはべき等性はありません
1985年

0

あなたはそれを行うことができます-

アドホックコマンドの使用

ansible all -m command -a" mv /path/to/foo /path/to/bar"

または、プレイブックを使用して実行する場合

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

0

私はそれが知っている年間古いトピックが、私はイライラと私は、ファイルの任意のリストについては、まさにこれを実行するための役割を建てました。必要に応じて拡張します。

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

ハードリンクは本質的に所有権とアクセス許可を保持するため、ここでコピーするよりもハードリンクの方が望ましいことに注意してください(ファイルの2番目のコピーにディスク領域を消費しないことに加えて)。


0

Windowsの場合: - name: Move old folder to backup win_command: "cmd.exe /c move /Y {{ sourcePath }} {{ destinationFolderPath }}"

名前を変更するには、代わりにrenameまたはrenコマンドを使用します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.