【Ansible】指定のディレクトリ配下にあるファイルをすべてコピーする
はじめに
指定のディレクトリ配下にあるすべてのファイルを、
指定のディレクトリにコピーするPlaybook書きました。
registerを駆使したパワープレイbookです。
動作確認環境
- Ansible:2.8.5
要件
/tmp/hoge/target_dir/
配下のすべてのファイルを、/root/fishing/dest/
にコピーしたい/tmp/hoge/target_dir/
直下にファイルがあったり、サブディレクトリがあったりする想定
状況
コピー先のファイルパスが定義できない想定です。
とにかく、target_dir
より下の階層に存在するファイルはすべて取ってくる!という仕様です。
こんな感じで仕込みました。
/tmp/hoge/ └ target_dir ├ subdir │ └ test03.txt ├ test01.txt └ test02.txt
Playbook
流れとしては、以下の通りです。
1. 対象のディレクトリがあるか確認する
2. 対象のディレクトリ内のファイルを再帰的に検索
3. 2.の検索の返り値(ファイルパス)をコピー元として、/root/fishing/dest/
にコピー
- hosts: all tasks: - name: find directory find: paths: /tmp/hoge/ file_type: directory patterns: "target_dir" register: find_dir_result - name: find file in target directory find: paths: /tmp/hoge/target_dir/ recurse: yes when: find_dir_result.matched != 0 register: find_file_result - name: copy the file to another directory copy: src: "{{ item.path }}" dest: /root/fishing/dest with_items: "{{ find_file_result.files }}" when: find_dir_result.matched != 0
実行ログ
# ansible-playbook -i "localhost," -c local site.yml PLAY [all] ********************************************************************* TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [find directory] ********************************************************** ok: [localhost] TASK [find file in target directory] ******************************************* ok: [localhost] TASK [copy the file to another directory] ************************************** changed: [localhost] => (item={'path': '/tmp/hoge/target_dir/test02.txt', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 0, 'gid': 0, 'size': 7, 'inode': 271483, 'dev': 64770, 'nlink': 1, 'atime': 1574214578.7024505, 'mtime': 1574214578.7024505, 'ctime': 1574214578.7024505, 'gr_name': 'root', 'pw_name': 'root', 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False}) changed: [localhost] => (item={'path': '/tmp/hoge/target_dir/test01.txt', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 0, 'gid': 0, 'size': 5, 'inode': 264556, 'dev': 64770, 'nlink': 1, 'atime': 1574214468.7718232, 'mtime': 1574214053.4072368, 'ctime': 1574214602.3138, 'gr_name': 'root', 'pw_name': 'root', 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False}) changed: [localhost] => (item={'path': '/tmp/hoge/target_dir/subdir/test03.txt', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 0, 'gid': 0, 'size': 0, 'inode': 271486, 'dev': 64770, 'nlink': 1, 'atime': 1574214635.5332918, 'mtime': 1574214635.5332918, 'ctime': 1574214635.5332918, 'gr_name': 'root', 'pw_name': 'root', 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False}) PLAY RECAP ********************************************************************* localhost : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
結果
ちゃんとコピーされてます。
# ls /root/fishing/dest/ test01.txt test02.txt test03.txt
まとめ
工夫した点、学んだ点は以下の通り。
(find結果のregister変数).matched
でfindのヒット数を処理に使える- findモジュールの
recurse: yes
で再帰的検索ができる with_items: (find結果のregister変数).files
で、findでヒットしたファイル分の処理をループできる
registerを駆使してごにょごにょするのが得意になってきた気がします。
もっとスマートな方法があるのかもしれないけども。。
補足(経緯など)
Windowsホストからfetchした痕跡で、
後々Git管理したいディレクトリに、C:
というディレクトリが含まれてました。
WindowsクライアントでPullするとエラーになるため、
C:
配下のファイルを上の階層に引き上げるために作ったPlaybookです。
fetchしているPlaybookはいじれない状況だったので、
別のPlaybookでごにょごにょした次第です。
実際はlocal_actionでやりました。
つまるところ、
Ansibleを取り巻くJenkinsやGitの動作を改善するために、
仕掛けた小細工なので、
果たして有用な情報なのかは置いておきます。