Ansible - 检查磁盘是否已安装,如果没有则格式化它

j4n*_*kvc 3 ansible

我正在寻求帮助,因为我很难完成这件事:

---
- name: Check if /data is already mounted
  debug: msg="The mount point exists"
  with_items: "{{ ansible_mounts }}"
  when: item.mount == "/data"
  register: check_mount

- name: Create /data directory if not exists
  ansible.builtin.file:
    path: /data
    state: directory
    owner: root
    group: root
    mode: '0751'

- name: Create a xfs filesystem on /dev/sda5
  community.general.filesystem:
    force: yes
    fstype: xfs
    dev: /dev/sda5
  when: not check_mount

- name: Get the /dev/sda5's UUID
  shell: blkid -s UUID -o value /dev/sda5
  register: blkid_out
  when: not check_mount

- name: Mount up device by UUID
  ansible.posix.mount:
    path: /data
    src: UUID={{ blkid_out.stdout }}
    fstype: xfs
    opts: defaults
    state: mounted
Run Code Online (Sandbox Code Playgroud)

我想做什么:

  • 检查挂载点是否存在并安装,如果不存在:
  • 创建 /data 文件夹
  • 创建文件系统
  • 获取UUID
  • 将格式化后的磁盘挂载到/data

如果挂载点存在,则不执行任何操作。

我遇到的问题是我猜我的检查没有做任何事情,但我不知道如何仅使用 ansible_mount 而不是使用 stat 来使其正确。

第一次运行完全符合我的要求,但我需要能够一遍又一遍地运行剧本,它在第二次运行后向我显示错误

    TASK [setup_disk : Create a xfs filesystem on /dev/sda5] ***********************************************************************************************************************************************************************************
fatal: [blm-web-160]: FAILED! => {"changed": false, "cmd": "/usr/sbin/mkfs.xfs -f /dev/sda5", "msg": "mkfs.xfs: /dev/sda5 contains a mounted filesystem\nUsage: mkfs.xfs\n/* blocksize */\t\t[-b size=num]\n/* metadata */\t\t[-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1]\n/* data subvol */\t[-d agcount=n,agsize=n,file,name=xxx,size=num,\n\t\t\t    (sunit=value,swidth=value|su=num,sw=num|noalign),\n\t\t\t    sectsize=num\n/* force overwrite */\t[-f]\n/* inode size */\t[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n\t\t\t    projid32bit=0|1,sparse=0|1]\n/* no discard */\t[-K]\n/* log subvol */\t[-l agnum=n,internal,size=num,logdev=xxx,version=n\n\t\t\t    sunit=value|su=num,sectsize=num,lazy-count=0|1]\n/* label */\t\t[-L label (maximum 12 characters)]\n/* naming */\t\t[-n size=num,version=2|ci,ftype=0|1]\n/* no-op info only */\t[-N]\n/* prototype file */\t[-p fname]\n/* quiet */\t\t[-q]\n/* realtime subvol */\t[-r extsize=num,size=num,rtdev=xxx]\n/* sectorsize */\t[-s size=num]\n/* version */\t\t[-V]\n\t\t\tdevicename\n<devicename> is required unless -d name=xxx is given.\n<num> is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n      xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n<value> is xxx (512 byte blocks).", "rc": 1, "stderr": "mkfs.xfs: /dev/sda5 contains a mounted filesystem\nUsage: mkfs.xfs\n/* blocksize */\t\t[-b size=num]\n/* metadata */\t\t[-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1]\n/* data subvol */\t[-d agcount=n,agsize=n,file,name=xxx,size=num,\n\t\t\t    (sunit=value,swidth=value|su=num,sw=num|noalign),\n\t\t\t    sectsize=num\n/* force overwrite */\t[-f]\n/* inode size */\t[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,\n\t\t\t    projid32bit=0|1,sparse=0|1]\n/* no discard */\t[-K]\n/* log subvol */\t[-l agnum=n,internal,size=num,logdev=xxx,version=n\n\t\t\t    sunit=value|su=num,sectsize=num,lazy-count=0|1]\n/* label */\t\t[-L label (maximum 12 characters)]\n/* naming */\t\t[-n size=num,version=2|ci,ftype=0|1]\n/* no-op info only */\t[-N]\n/* prototype file */\t[-p fname]\n/* quiet */\t\t[-q]\n/* realtime subvol */\t[-r extsize=num,size=num,rtdev=xxx]\n/* sectorsize */\t[-s size=num]\n/* version */\t\t[-V]\n\t\t\tdevicename\n<devicename> is required unless -d name=xxx is given.\n<num> is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),\n      xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).\n<value> is xxx (512 byte blocks).\n", "stderr_lines": ["mkfs.xfs: /dev/sda5 contains a mounted filesystem", "Usage: mkfs.xfs", "/* blocksize */\t\t[-b size=num]", "/* metadata */\t\t[-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1]", "/* data subvol */\t[-d agcount=n,agsize=n,file,name=xxx,size=num,", "\t\t\t    (sunit=value,swidth=value|su=num,sw=num|noalign),", "\t\t\t    sectsize=num", "/* force overwrite */\t[-f]", "/* inode size */\t[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,", "\t\t\t    projid32bit=0|1,sparse=0|1]", "/* no discard */\t[-K]", "/* log subvol */\t[-l agnum=n,internal,size=num,logdev=xxx,version=n", "\t\t\t    sunit=value|su=num,sectsize=num,lazy-count=0|1]", "/* label */\t\t[-L label (maximum 12 characters)]", "/* naming */\t\t[-n size=num,version=2|ci,ftype=0|1]", "/* no-op info only */\t[-N]", "/* prototype file */\t[-p fname]", "/* quiet */\t\t[-q]", "/* realtime subvol */\t[-r extsize=num,size=num,rtdev=xxx]", "/* sectorsize */\t[-s size=num]", "/* version */\t\t[-V]", "\t\t\tdevicename", "<devicename> is required unless -d name=xxx is given.", "<num> is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),", "      xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).", "<value> is xxx (512 byte blocks)."], "stdout": "", "stdout_lines": []}
Run Code Online (Sandbox Code Playgroud)

当然是因为它尝试格式化已经在使用的东西。

如果有人提供一些建议,我们将不胜感激:)

flo*_*ong 5

Ansible 模块通常被设计为幂等的。您应该使用声明性任务,而不是进行额外的检查来查看文件系统是否已存在,并且filesystemmount模块将执行正确的操作。

- name: Create /data
  ansible.builtin.file:
    path: /data
    state: directory
    owner: root
    group: root
    mode: '0751'

- name: Create an xfs filesystem on /dev/sda5
  community.general.filesystem:
    fstype: xfs
    state: present
    dev: /dev/sda5

- name: Fetch the UUID of /dev/sda5
  command: blkid -s UUID -o value /dev/sda5
  changed_when: false
  register: blkid_out

- name: Mount /dev/sda5 by UUID
  ansible.posix.mount:
    path: /data
    src: UUID={{ blkid_out.stdout }}
    fstype: xfs
    opts: defaults
    state: mounted
Run Code Online (Sandbox Code Playgroud)

第一次运行:

ec2-user@pandora ~ $ ansible-playbook ~/test.yml

PLAY [localhost] ***************************************************************

TASK [Create /data] ************************************************************
changed: [localhost]

TASK [Create an xfs filesystem on /dev/sda5] ***********************************
changed: [localhost]

TASK [Fetch the UUID of /dev/sda5] *********************************************
ok: [localhost]

TASK [Mount /dev/sda5 by UUID] *************************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
Run Code Online (Sandbox Code Playgroud)

第二次运行:

ec2-user@pandora ~ $ ansible-playbook ~/test.yml

PLAY [localhost] ***************************************************************

TASK [Create /data] ************************************************************
changed: [localhost]

TASK [Create an xfs filesystem on /dev/sda5] ***********************************
ok: [localhost]

TASK [Fetch the UUID of /dev/sda5] *********************************************
ok: [localhost]

TASK [Mount /dev/sda5 by UUID] *************************************************
ok: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
Run Code Online (Sandbox Code Playgroud)

如果您确实需要使其成为有条件的,您需要了解所涉及的变量是什么样的。

- name: Check if /data is already mounted
  debug: msg="The mount point exists"
  with_items: "{{ ansible_mounts }}"
  when: item.mount == "/data"
  register: check_mount
Run Code Online (Sandbox Code Playgroud)

如果您调试它,您将看到,任务结果check_mount包含每个循环项的结果,因此check_mount它本身始终是一个真值。要查看它是否运行了任何内容,您需要使用when: check_mount is not skipped,而不是when: check_mount

然而,这对于条件来说不是一个好的模式,因为它需要额外的任务,并且可能有大量的循环输出。最好直接在when声明中检查您想要的条件。

- when: ansible_facts.mounts | selectattr('mount', '==', '/data') | length == 0
  block:
    - name: Create an xfs filesystem on /dev/sda5
      community.general.filesystem:
        state: present
        fstype: xfs
        dev: /dev/sda5

    - name: Fetch the UUID of /dev/sda5
      command: blkid -s UUID -o value /dev/sda5
      changed_when: false
      register: blkid_out

    - name: Mount /dev/sda5 by UUID
      ansible.posix.mount:
        path: /data
        src: UUID={{ blkid_out.stdout }}
        fstype: xfs
        opts: defaults
        state: mounted
Run Code Online (Sandbox Code Playgroud)