Ansible — проверьте, смонтирован ли диск, если он не отформатирован

#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  

Что я пытаюсь сделать :

  • проверьте, выходит ли точка монтирования и монтируется ли она, если нет :
  • создать папку /данные
  • создайте файловую систему
  • получите UUID
  • установите отформатированный диск на /данные

ничего не делайте, если точка монтирования существует.

Проблема, с которой я столкнулся, заключается в том, что я думаю, что моя проверка ничего не делает, но я не знаю, как сделать это правильно только с помощью ansible_mount, а не со статистикой.

Первый запуск делает именно то, что я хочу, но мне нужно иметь возможность запускать playbook снова и снова, и он показывает мне ошибку после второго запуска

 TASK [setup_disk : Create a xfs filesystem on /dev/sda5] *********************************************************************************************************************************************************************************** fatal: [blm-web-160]: FAILED! =gt; {"changed": false, "cmd": "/usr/sbin/mkfs.xfs -f /dev/sda5", "msg": "mkfs.xfs: /dev/sda5 contains a mounted filesystemnUsage: mkfs.xfsn/* blocksize */tt[-b size=num]n/* metadata */tt[-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,nttt (sunit=value,swidth=value|su=num,sw=num|noalign),nttt sectsize=numn/* force overwrite */t[-f]n/* inode size */t[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,nttt projid32bit=0|1,sparse=0|1]n/* no discard */t[-K]n/* log subvol */t[-l agnum=n,internal,size=num,logdev=xxx,version=nnttt sunit=value|su=num,sectsize=num,lazy-count=0|1]n/* label */tt[-L label (maximum 12 characters)]n/* naming */tt[-n size=num,version=2|ci,ftype=0|1]n/* no-op info only */t[-N]n/* prototype file */t[-p fname]n/* quiet */tt[-q]n/* realtime subvol */t[-r extsize=num,size=num,rtdev=xxx]n/* sectorsize */t[-s size=num]n/* version */tt[-V]ntttdevicenamenlt;devicenamegt; is required unless -d name=xxx is given.nlt;numgt; 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).nlt;valuegt; is xxx (512 byte blocks).", "rc": 1, "stderr": "mkfs.xfs: /dev/sda5 contains a mounted filesystemnUsage: mkfs.xfsn/* blocksize */tt[-b size=num]n/* metadata */tt[-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,nttt (sunit=value,swidth=value|su=num,sw=num|noalign),nttt sectsize=numn/* force overwrite */t[-f]n/* inode size */t[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,nttt projid32bit=0|1,sparse=0|1]n/* no discard */t[-K]n/* log subvol */t[-l agnum=n,internal,size=num,logdev=xxx,version=nnttt sunit=value|su=num,sectsize=num,lazy-count=0|1]n/* label */tt[-L label (maximum 12 characters)]n/* naming */tt[-n size=num,version=2|ci,ftype=0|1]n/* no-op info only */t[-N]n/* prototype file */t[-p fname]n/* quiet */tt[-q]n/* realtime subvol */t[-r extsize=num,size=num,rtdev=xxx]n/* sectorsize */t[-s size=num]n/* version */tt[-V]ntttdevicenamenlt;devicenamegt; is required unless -d name=xxx is given.nlt;numgt; 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).nlt;valuegt; is xxx (512 byte blocks).n", "stderr_lines": ["mkfs.xfs: /dev/sda5 contains a mounted filesystem", "Usage: mkfs.xfs", "/* blocksize */tt[-b size=num]", "/* metadata */tt[-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,", "ttt (sunit=value,swidth=value|su=num,sw=num|noalign),", "ttt sectsize=num", "/* force overwrite */t[-f]", "/* inode size */t[-i log=n|perblock=n|size=num,maxpct=n,attr=0|1|2,", "ttt projid32bit=0|1,sparse=0|1]", "/* no discard */t[-K]", "/* log subvol */t[-l agnum=n,internal,size=num,logdev=xxx,version=n", "ttt sunit=value|su=num,sectsize=num,lazy-count=0|1]", "/* label */tt[-L label (maximum 12 characters)]", "/* naming */tt[-n size=num,version=2|ci,ftype=0|1]", "/* no-op info only */t[-N]", "/* prototype file */t[-p fname]", "/* quiet */tt[-q]", "/* realtime subvol */t[-r extsize=num,size=num,rtdev=xxx]", "/* sectorsize */t[-s size=num]", "/* version */tt[-V]", "tttdevicename", "lt;devicenamegt; is required unless -d name=xxx is given.", "lt;numgt; is xxx (bytes), xxxs (sectors), xxxb (fs blocks), xxxk (xxx KiB),", " xxxm (xxx MiB), xxxg (xxx GiB), xxxt (xxx TiB) or xxxp (xxx PiB).", "lt;valuegt; is xxx (512 byte blocks)."], "stdout": "", "stdout_lines": []}  

наверняка потому, что он пытается отформатировать что-то уже используемое.

Было бы полезно получить от кого-нибудь несколько советов 🙂

Ответ №1:

Модули Ansible, как правило, спроектированы так, чтобы быть идемпотентными. Вместо того, чтобы выполнять дополнительные проверки, чтобы убедиться, что файловая система уже существует, вам следует использовать декларативные задачи, filesystem и mount модули и будут делать правильные вещи.

 - 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  

Первый запуск:

 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   

Второй заход:

 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   

Если вам действительно нужно сделать это условным, вам нужно понять, как выглядят соответствующие переменные.

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

Как вы увидите, если отладите его, результат задачи 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  

Комментарии:

1. большое вам спасибо @flowerysong за ваши подробные объяснения, я понимаю, знаю, где я потерпел неудачу, отчасти это было из-за того, что я плохо справляюсь с ansible, еще раз спасибо, мне стало трудно без помощи, если у вас есть какие-либо ресурсы помимо официальной документации, чтобы изучить ansible на примере, который я беру 🙂