Ansible:检测 Linux 文件系统是否以只读方式挂载
Ansible: Detect if a Linux filesystem is mounted read-only
我正在尝试检测特定文件系统是在 Linux (Ubuntu 16.04) 上以只读方式挂载还是以读写方式挂载。使用 stat 模块将不起作用,因为它总是 returns posix 权限,而不管写入目录的实际能力如何。我可以使用下面相当麻烦且麻烦的代码来完成此操作,该代码尝试创建一个点文件。我希望有一个更干净、更优雅的替代方案,它还可以检测目录是否不是挂载点(这将是一个错误)。
- name: Determine whether we have write access to the shared dir
command: touch /mnt/shared-data/.WriteTest
register: shared_dir_write_test
failed_when: "shared_dir_write_test.rc != 0 and 'read-only' not in (shared_dir_write_test.stderr | lower)"
changed_when: shared_dir_write_test.rc == 0
Ansible 建议我使用 file 模块和 state=touch,但是下面的代码失败了,因为似乎没有成为一种检查 file.
的中间结果的方法
- name: Determine whether we have write access to the shared dir
file: path=/mnt/shared-data/.WriteTest state=touch
register: shared_dir_write_test
failed_when: "shared_dir_write_test.failed and 'read-only' not in (shared_dir_write_test.msg | lower)"
The conditional check 'shared_dir_write_test.failed and 'read-only'
not in (shared_dir_write_test.stderr | lower)' failed. The error was:
error while evaluating conditional (shared_dir_write_test.failed and
'read-only' not in (shared_dir_write_test.stderr | lower)): 'dict
object' has no attribute 'failed'
可从Ansible facts获取信息。实现此目的的 Ansible 代码:
- name: Determine shared-dir mount point
command: "/usr/bin/env stat -c '%m' {{ shared_dir_real_path }}"
register: shared_dir_mount_point
changed_when: False
- name: Determine the mount point's filesystem type and mount options
set_fact:
"shared_dir_mount_{{ item }}": "{{ ansible_mounts | selectattr('mount', 'equalto', shared_dir_mount_point.stdout) | map(attribute = item) | join(',') }}"
with_items:
- fstype
- options
- name: Determine the access to the shared-data directory
set_fact:
shared_dir_access_flags: "{{ ['ro', 'rw'] | intersect( shared_dir_mount_options.split(',') )}}"
- name: Verify Access mode sanity
assert:
that: shared_dir_access_flags | length == 1
然后判断挂载是R/W还是R/O我用:
when: "'rw' in shared_dir_access_flags"
或
when: "'ro' in shared_dir_access_flags"
我之前使用的另一种更简洁但可能不太干净的方法是从 /proc/self/mountinfo 获取信息。 platform-specific 比我希望的多一点,但这仅取决于记录的接口。
- name: Get Shared dir mount options
shell: "grep -F `stat -c '%m' {{ shared_dir_path }}` /proc/self/mountinfo | cut -d' ' -f 6"
register: shared_dir_mount_options
changed_when: False
那么判断mount是R/W还是R/O的表达式就变得比较麻烦了:
when: "'rw' in shared_dir_mount_options.stdout.split(',')"
或
when: "'ro' in shared_dir_mount_options.stdout.split(',')"
你可以收集 Ansible 的事实,每个挂载都有挂载选项:
ansible localhost -m setup -a "filter=ansible_mounts"
示例输出:
[root@ansible ansible]# ansible localhost -m setup -a "filter=ansible_mounts"
localhost | SUCCESS => {
"ansible_facts": {
"ansible_mounts": [
{
"block_available": 3007928,
"block_size": 4096,
"block_total": 3929600,
"block_used": 921672,
"device": "/dev/mapper/fedora-root",
"fstype": "xfs",
"inode_available": 7787042,
"inode_total": 7864320,
"inode_used": 77278,
"mount": "/",
"options": "rw,relatime,attr2,inode64,noquota",
"size_available": 12320473088,
"size_total": 16095641600,
"uuid": "5faf23bb-281b-41d9-bd20-f8da6463eba0"
},
{
"block_available": 185772,
"block_size": 4096,
"block_total": 249830,
"block_used": 64058,
"device": "/dev/sda1",
"fstype": "ext4",
"inode_available": 65179,
"inode_total": 65536,
"inode_used": 357,
"mount": "/boot",
"options": "rw,relatime,data=ordered",
"size_available": 760922112,
"size_total": 1023303680,
"uuid": "866845e7-6c62-41c9-bbd2-87b463326601"
}
]
},
"changed": false
}
[root@ansible ansible]# ansible localhost -m setup -a "filter=ansible_mounts"
我正在尝试检测特定文件系统是在 Linux (Ubuntu 16.04) 上以只读方式挂载还是以读写方式挂载。使用 stat 模块将不起作用,因为它总是 returns posix 权限,而不管写入目录的实际能力如何。我可以使用下面相当麻烦且麻烦的代码来完成此操作,该代码尝试创建一个点文件。我希望有一个更干净、更优雅的替代方案,它还可以检测目录是否不是挂载点(这将是一个错误)。
- name: Determine whether we have write access to the shared dir
command: touch /mnt/shared-data/.WriteTest
register: shared_dir_write_test
failed_when: "shared_dir_write_test.rc != 0 and 'read-only' not in (shared_dir_write_test.stderr | lower)"
changed_when: shared_dir_write_test.rc == 0
Ansible 建议我使用 file 模块和 state=touch,但是下面的代码失败了,因为似乎没有成为一种检查 file.
的中间结果的方法 - name: Determine whether we have write access to the shared dir
file: path=/mnt/shared-data/.WriteTest state=touch
register: shared_dir_write_test
failed_when: "shared_dir_write_test.failed and 'read-only' not in (shared_dir_write_test.msg | lower)"
The conditional check 'shared_dir_write_test.failed and 'read-only' not in (shared_dir_write_test.stderr | lower)' failed. The error was: error while evaluating conditional (shared_dir_write_test.failed and 'read-only' not in (shared_dir_write_test.stderr | lower)): 'dict object' has no attribute 'failed'
可从Ansible facts获取信息。实现此目的的 Ansible 代码:
- name: Determine shared-dir mount point
command: "/usr/bin/env stat -c '%m' {{ shared_dir_real_path }}"
register: shared_dir_mount_point
changed_when: False
- name: Determine the mount point's filesystem type and mount options
set_fact:
"shared_dir_mount_{{ item }}": "{{ ansible_mounts | selectattr('mount', 'equalto', shared_dir_mount_point.stdout) | map(attribute = item) | join(',') }}"
with_items:
- fstype
- options
- name: Determine the access to the shared-data directory
set_fact:
shared_dir_access_flags: "{{ ['ro', 'rw'] | intersect( shared_dir_mount_options.split(',') )}}"
- name: Verify Access mode sanity
assert:
that: shared_dir_access_flags | length == 1
然后判断挂载是R/W还是R/O我用:
when: "'rw' in shared_dir_access_flags"
或
when: "'ro' in shared_dir_access_flags"
我之前使用的另一种更简洁但可能不太干净的方法是从 /proc/self/mountinfo 获取信息。 platform-specific 比我希望的多一点,但这仅取决于记录的接口。
- name: Get Shared dir mount options
shell: "grep -F `stat -c '%m' {{ shared_dir_path }}` /proc/self/mountinfo | cut -d' ' -f 6"
register: shared_dir_mount_options
changed_when: False
那么判断mount是R/W还是R/O的表达式就变得比较麻烦了:
when: "'rw' in shared_dir_mount_options.stdout.split(',')"
或
when: "'ro' in shared_dir_mount_options.stdout.split(',')"
你可以收集 Ansible 的事实,每个挂载都有挂载选项:
ansible localhost -m setup -a "filter=ansible_mounts"
示例输出:
[root@ansible ansible]# ansible localhost -m setup -a "filter=ansible_mounts"
localhost | SUCCESS => {
"ansible_facts": {
"ansible_mounts": [
{
"block_available": 3007928,
"block_size": 4096,
"block_total": 3929600,
"block_used": 921672,
"device": "/dev/mapper/fedora-root",
"fstype": "xfs",
"inode_available": 7787042,
"inode_total": 7864320,
"inode_used": 77278,
"mount": "/",
"options": "rw,relatime,attr2,inode64,noquota",
"size_available": 12320473088,
"size_total": 16095641600,
"uuid": "5faf23bb-281b-41d9-bd20-f8da6463eba0"
},
{
"block_available": 185772,
"block_size": 4096,
"block_total": 249830,
"block_used": 64058,
"device": "/dev/sda1",
"fstype": "ext4",
"inode_available": 65179,
"inode_total": 65536,
"inode_used": 357,
"mount": "/boot",
"options": "rw,relatime,data=ordered",
"size_available": 760922112,
"size_total": 1023303680,
"uuid": "866845e7-6c62-41c9-bbd2-87b463326601"
}
]
},
"changed": false
}
[root@ansible ansible]# ansible localhost -m setup -a "filter=ansible_mounts"