博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Ansible基础 - 03文件模块

Posted on 2022-01-07 14:14  Kingdomer  阅读(111)  评论(0编辑  收藏  举报

Ansible基础 - 03文件模块

一、概述

file、 copy、 fetch、 get_url、 git、 lineinfile、 synchronize

 

SEE ALSO:
      * Module assemble
           The official documentation on the assemble module.
           https://docs.ansible.com/ansible/2.9/modules/assemble_module.html
      * Module fetch
           The official documentation on the fetch module.
           https://docs.ansible.com/ansible/2.9/modules/fetch_module.html
      * Module file
           The official documentation on the file module.
           https://docs.ansible.com/ansible/2.9/modules/file_module.html
      * Module synchronize
           The official documentation on the synchronize module.
           https://docs.ansible.com/ansible/2.9/modules/synchronize_module.html
      * Module template
           The official documentation on the template module.
           https://docs.ansible.com/ansible/2.9/modules/template_module.html
      * Module win_copy
           The official documentation on the win_copy module.
           https://docs.ansible.com/ansible/2.9/modules/win_copy_module.html

 

  

 

二、file 模块

  • 创建目录:           ansible cl -m file -a 'path=/tmp/app          state=directory'
  • 创建文件:           ansible cl -m file -a 'path=/tmp/app/abc.txt  state=touch'
  • 创建软连接:         ansible cl -m file -a 'path=/tmp/tt-txt.link  src=tt.txt  state=link'
  • 删除文件,链接文件未删除:  ansible cl -m file -a 'path=/tmp/tt.txt       state=absent'
[root@cl-server playbooks]# ansible cl-node03 -m file -a "path=/tmp/new/aa.txt state=touch"
cl-node03 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "msg": "Error, could not touch target: [Errno 2] 没有那个文件或目录: '/tmp/new/aa.txt'", 
    "path": "/tmp/new/aa.txt"
}
[root@cl-server playbooks]# ansible cl-node03 -m file -a "path=/tmp/new/ state=touch"
cl-node03 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "msg": "Error, could not touch target: [Errno 21] 是一个目录: '/tmp/new/'", 
    "path": "/tmp/new/"
}
[root@cl-server ~]# ansible cl-node03 -m file -a 'path=/tmp/v1/v11 state=directory'
cl-node03 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0755", 
    "owner": "root", 
    "path": "/tmp/v1/v11", 
    "size": 6, 
    "state": "directory", 
    "uid": 0
}
[root@cl-server playbooks]# ansible cl-node03 -m file -a "path=/tmp/new.link src=/tmp/new state=hard"
cl-node03 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "dest": "/tmp/new.link", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "owner": "root", 
    "size": 0, 
    "src": "/tmp/new", 
    "state": "hard", 
    "uid": 0
}

  

三、copy模块

参数: src、dest、remote_src、owner、group、mode、backup、content

[root@cl-server ~]# ansible cl -m copy -a "src=~/tt.txt dest=/tmp/"
[root@cl-server ~]# ansible cl -m copy -a 'content="i am worker2\ni am keeper2\n" dest=/tmp/ttt.txt mode=666 backup=true'

  

[root@cl-server playbooks]# cat copy_exp1.yml 
- name: copy_exp1
  hosts: cl3
  remote_user: root
  tasks:
  - name: copy_1
    copy:
      src: /home/soupman/foo.conf
      dest: /tmp/foo.conf
      owner: soupman
      group: soupman
      mode: u=rw,g=r,o=r
  - name: copy_2
    copy:
      src: /home/soupman/foo1.conf
      dest: /tmp/foo1.conf
      owner: soupman
      group: soupman
      mode: u+rw,g-rw,o-rw
  - name: copy_3
    copy:
      src: /home/soupman/foo2.conf
      dest: /tmp/foo2.conf
      owner: soupman
      group: soupman
      mode: '0644'
      backup: yes

[root@cl-node03 tmp]# ll foo*
-rw------- 1 soupman soupman 116 11月  3 10:16 foo1.conf
-rw-r--r-- 1 soupman soupman 116 11月  3 10:16 foo2.conf
-rw-r--r-- 1 root    root    119 11月  3 10:16 foo2.conf.2718.2021-11-03@10:16:53~
-rw-r--r-- 1 soupman soupman 116 11月  3 10:16 foo.conf
[root@cl-node03 tmp]# diff foo2.conf foo2.conf.2718.2021-11-03\@10\:16\:53~ 3c3 < server_port 80; --- > server_port 8080; 8a9 > [root@cl-server playbooks]# cat copy_exp2.yml - name: copy_exp1 hosts: cl3 remote_user: root tasks: - name: copy_replace copy: content: "# replace line\n" dest: /tmp/foo.conf [root@cl-node03 tmp]# cat foo.conf # replace line

 

在文件拷贝替换操作时,展示文件变更内容

[root@cl-server playbooks]#  ansible cl-node03 -m copy -a "src=/home/soupman/foo.conf dest=/tmp/foo.conf" --check 
cl-node03 | CHANGED => {
    "changed": true
}
[root@cl-server playbooks]#  ansible cl-node03 -m copy -a "src=/home/soupman/foo.conf dest=/tmp/foo.conf" --check --diff
--- before: /tmp/foo.conf
+++ after: /home/soupman/foo.conf
@@ -6,7 +6,7 @@
        root /data/web/html;
     }
    
-    location /test {
+#    location /test {
        root /data/web/test;
     }
 }

cl-node03 | CHANGED => {
    "changed": true
}

[root@cl-server playbooks]# ansible-playbook copy_exp11.yml --diff
PLAY [copy_exp1] ****************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************
ok: [cl-node03]
TASK [copy_1] *******************************************************************************************************
--- before: /tmp/foo.conf
+++ after: /home/soupman/foo.conf
@@ -6,7 +6,7 @@
        root /data/web/html;
     }
    
-    location /test {
+#    location /test {
        root /data/web/test;
     }
 }
changed: [cl-node03]
PLAY RECAP **********************************************************************************************************
cl-node03                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

  

四、fetch模块:拉取远程主机的文件到本机

= dest
        A directory to save the file into.
        For example, if the `dest' directory is `/backup' a `src' file named `/etc/profile'
        on host `host.example.com', would be saved into
        `/backup/host.example.com/etc/profile'. The host name is based on the inventory name.

= src
        The file on the remote system to fetch.
        This `must' be a file, not a directory.
        Recursive fetching may be supported in a later release.

  

## src 是远程客户端的文件,  dest 是ansible服务器的文件夹
[root@cl-server ~]# ansible cl -m fetch -a "src=/tmp/t1.txt  dest=/tmp"  
cl-node01 | CHANGED => {
    "changed": true, 
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
    "dest": "/tmp/cl-node01/tmp/t1.txt", 
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e", 
    "remote_checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", 
    "remote_md5sum": null
}
cl-node02 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "msg": "file not found: /tmp/t1.txt"
}
[root@cl-server ~]# ls /tmp/cl-node01/tmp/
t1.txt

  

[root@cl-server ~]# ansible cl-node03 -m fetch -a "src=/root/aa1.txt dest=/tmp/aa1-from-c3.txt"
cl-node03 | CHANGED => {
    "changed": true, 
    "checksum": "a2c00e132902ede363450b33497345791547683f", 
    "dest": "/tmp/aa1-from-c3.txt/cl-node03/root/aa1.txt", 
    "md5sum": "1cae4352909b7efe2c4c6f74a3ca2264", 
    "remote_checksum": "a2c00e132902ede363450b33497345791547683f", 
    "remote_md5sum": null
}
[root@cl-server ~]# cat /tmp/aa1-from-c3.txt/cl-node03/root/aa1.txt 

# 指定拉取的文件存放Ansible服务端的目录(以/结束),不使用默认路径
[root@cl-server ~]# ansible cl-node03 -m fetch -a "src=/root/aa1.txt dest=/tmp/cl3/ flat=yes"
cl-node03 | CHANGED => {
    "changed": true, 
    "checksum": "a2c00e132902ede363450b33497345791547683f", 
    "dest": "/tmp/cl3/aa1.txt", 
    "md5sum": "1cae4352909b7efe2c4c6f74a3ca2264", 
    "remote_checksum": "a2c00e132902ede363450b33497345791547683f", 
    "remote_md5sum": null
}
# flat=yes, dest不以/结束,则保存为文件
[root@cl-server ~]# ansible cl-node03 -m fetch -a "src=/root/aa1.txt dest=/tmp/cl30 flat=yes"
cl-node03 | CHANGED => {
    "changed": true, 
    "checksum": "a2c00e132902ede363450b33497345791547683f", 
    "dest": "/tmp/cl30", 
    "md5sum": "1cae4352909b7efe2c4c6f74a3ca2264", 
    "remote_checksum": "a2c00e132902ede363450b33497345791547683f", 
    "remote_md5sum": null
}

 

五、get_url模块

参数: url、 dest、 mode
[root@cl-server ~]# ansible cl-node02 -m get_url -a "url=http://nginx.org/download/nginx-1.20.2.tar.gz dest=/tmp mode=755"

 

六、git模块

[root@cl-server ~]# ansible cl-node01 -m git -a "repo=https://github.com/ansible/ansible.git dest=/tmp/ansible"

 

七、lineinfile:文件内容追加

[root@cl-server playbooks]# cat lineinfile-exp.yml 
---
- name: lineinfile append line
  hosts: cl3
  remote_user: root
  tasks:
  - name: lineinfile append line
    lineinfile:
      line: "Redis.port=6379\n"
      dest: /tmp/foo.conf  

[root@cl-server playbooks]# cat append_line.yml 
- name: file append line
  hosts: cl3
  remote_user: root
  tasks:
  - name: use_shell
    shell: sed -i '$a\redis:\n database:\ 9\n host:\ 192.168.234.6\n' /tmp/foo.conf
    ignore_errors: True

 

八、 synchronize模块

synchronize 模块来同步大文件夹, 使用了--cvs-exclude 选项来排除版本控制文件

[root@cl-server ~]# ansible cl-node01 -m synchronize -a "src=/root/playbooks/ dest=/tmp/ansible_playbooks/"
cl-node01 | CHANGED => {
    "changed": true, 
    "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh=/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null 
           --rsync-path=sudo rsync --out-format=<<CHANGED>>%i %n%L /root/playbooks/ cl-node01:/tmp/ansible_playbooks/", 
......

[root@cl-server playbooks]# vi append_line.yml  ### 文件编辑,内容变动
[root@cl-server playbooks]# touch aa.txt        ### 新增文件
[root@cl-server playbooks]# ansible cl-node01 -m synchronize -a "src=/root/playbooks/ dest=/tmp/ansible_playbooks/" ### 再次同步时,只对差异文件进行同步
cl-node01 | CHANGED => {
    "changed": true, 
    "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh=/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null 
            --rsync-path=sudo rsync --out-format=<<CHANGED>>%i %n%L /root/playbooks/ cl-node01:/tmp/ansible_playbooks/", 
    "msg": ".d..t...... ./\n<f+++++++++ aa.txt\n<f.st...... append_line.yml\n", 
    "rc": 0, 
    "stdout_lines": [
        ".d..t...... ./", 
        "<f+++++++++ aa.txt", 
        "<f.st...... append_line.yml"
    ]
}

 

指定忽略svn目录
ansible cl-node02 -m synchronize -a "src=dir1 dest=dir2 compress=yes rsync_opts=--exclude=.svn/"

指定包含需要的文件类型(--include)

ansible cl-node02 -m synchronize -a "src=dir1 dest=dir2 compress=yes rsync_opts=--cvs-exclude,--include=*.so"

 

对比 copy模块 与 synchronize模块

[root@cl-server ~]# date1=`date`;ansible cl-node02 -m copy -a "src=/root/kibana-6.8.5-x86_64.rpm dest=/tmp/";date2=`date`;echo -e "开始时间: $date1 \n\r 结束时间:$date2"
cl-node02 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "checksum": "15d5c24a8c271384d29f2ff5641117053d829a09", 
    "dest": "/tmp/kibana-6.8.5-x86_64.rpm", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "7fdb8fd3f7e14e674dc3e8b0ef4aa93f", 
    "mode": "0644", 
    "owner": "root", 
    "size": 193508862, 
    "src": "/root/.ansible/tmp/ansible-tmp-1637632247.22-2113-114829800448059/source", 
    "state": "file", 
    "uid": 0
}
开始时间: 2021年 11月 23日 星期二 09:50:46 CST 
结束时间:2021年 11月 23日 星期二 09:50:59 CST
 
[root@cl-server ~]# date1=`date`;ansible cl-node03 -m synchronize -a "src=/root/kibana-6.8.5-x86_64.rpm dest=/tmp/";date2=`date`;echo -e "开始时间: $date1 \n\r结束时间:$date2"
cl-node03 | CHANGED => {
    "changed": true, 
    "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh=/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null 
            --rsync-path=sudo rsync --out-format=<<CHANGED>>%i %n%L /root/kibana-6.8.5-x86_64.rpm cl-node03:/tmp/", 
    "msg": "<f+++++++++ kibana-6.8.5-x86_64.rpm\n", 
    "rc": 0, 
    "stdout_lines": [
        "<f+++++++++ kibana-6.8.5-x86_64.rpm"
    ]
}
开始时间: 2021年 11月 23日 星期二 09:52:55 CST 
结束时间:2021年 11月 23日 星期二 09:53:03 CST

  

synchronize
      * rsync must be installed on both the local and remote host.
      * For the `synchronize' module, the "local host" is the host `the synchronize task
        originates on`, and the "destination host" is the host `synchronize is connecting to`.
      * The "local host" can be changed to a different host by using `delegate_to`.  This
        enables copying between two remote hosts or entirely on one remote machine.
      * The user and permissions for the synchronize `src` are those of the user running the
        Ansible task on the local host (or the remote_user for a delegate_to host when
        delegate_to is used).
      * The user and permissions for the synchronize `dest` are those of the `remote_user` on
        the destination host or the `become_user` if `become=yes` is active.
      * In Ansible 2.0 a bug in the synchronize module made become occur on the "local host".
        This was fixed in Ansible 2.0.1.
      * Currently, synchronize is limited to elevating permissions via passwordless sudo.  This
        is because rsync itself is connecting to the remote machine and rsync doesn't give us a
        way to pass sudo credentials in.
      * Currently there are only a few connection types which support synchronize (ssh,
        paramiko, local, and docker) because a sync strategy has been determined for those
        connection types.  Note that the connection for these must not need a password as rsync
        itself is making the connection and rsync does not provide us a way to pass a password
        to the connection.
      * Expect that dest=~/x will be ~<remote_user>/x even if using sudo.
      * Inspect the verbose output to validate the destination user/host/path are what was
        expected.
      * To exclude files and directories from being synchronized, you may add `.rsync-filter'
        files to the source directory.
      * rsync daemon must be up and running with correct permission when using rsync protocol in
        source or destination path.
      * The `synchronize' module forces `--delay-updates` to avoid leaving a destination in a
        broken in-between state if the underlying rsync process encounters an error. Those
        synchronizing large numbers of files that are willing to trade safety for performance
        should call rsync directly.
      * link_destination is subject to the same limitations as the underlying rsync daemon. Hard
        links are only preserved if the relative subtrees of the source and destination are the
        same. Attempts to hardlink into a directory that is a subdirectory of the source will be
        prevented.