Ansible基础 - 03文件模块
Ansible基础 - 03文件模块
一、概述
file、 copy、 fetch、 get_url、 git、 lineinfile、 synchronize
二、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=<>%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=<>%i %n%L /root/playbooks/ cl-node01:/tmp/ansible_playbooks/",
"msg": ".d..t...... ./\n "
]
}
指定忽略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=<>%i %n%L /root/kibana-6.8.5-x86_64.rpm cl-node03:/tmp/",
"msg": "
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 ~/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.