---
- name: Set JSON Variables
  set_fact:
    all_mounts: '{{ all_mounts_json | from_json }}'
    volume_mounts: '{{ volume_mounts_json | from_json }}'
    bind_mounts: '{{ bind_mounts_json | from_json }}'

- name: Stop Filebeat
  service:
    name: filebeat
    state: stopped
  when: stop_filebeat_before_mount | default(false) | bool

- name: Stop Docker
  service:
    name: docker
    state: stopped
  when: stop_docker_before_mount | default(false) | bool

- name: Stop MariaDB
  service:
    name: mysql
    state: stopped
  when: stop_mariadb_before_mount | default(false) | bool

- name: Create Mount Points
  file:
    dest: '{{ item.mount_point }}'
    state: directory
    owner: '{{ item.mount_point_owner }}'
    group: '{{ item.mount_point_group }}'
    mode: '{{ item.mount_point_mode }}'
  loop: '{{ all_mounts }}'

- name: Find VFAT Partitions On Disks
  shell: >-
    if lsblk -no TYPE {{ item.source | quote }} | grep -q "^disk$"; then
      lsblk {{ item.source | quote }} -rno NAME,FSTYPE | grep -i vfat | awk '{print "/dev/" $1}';
    else
      echo "";
    fi
  register: vfat_devices
  changed_when: false
  loop: '{{ volume_mounts }}'
  loop_control:
    label: '{{ item.source }}'
  when: rotate_additional_volume_metadata | default(false) | bool

- name: Wipe VFAT Filesystem Signatures
  command: wipefs -a {{ item }}
  loop: '{{ vfat_devices.results | map(attribute="stdout") | select("!=","") | list }}'
  ignore_errors: true
  loop_control:
    label: '{{ item }}'
  when: rotate_additional_volume_metadata | default(false) | bool

- name: Find ext4 partitions on disks
  shell: >-
    if lsblk -no TYPE {{ item.source | quote }} | grep -q "^disk$"; then
    lsblk {{ item.source | quote }} -rno NAME,FSTYPE | grep -E "(ext4|^[[:space:]]*$)" | head -1 | awk '{print "/dev/" $1}';
    else
    echo {{ item.source | quote }};
    fi

  register: target_devices
  changed_when: false
  loop: '{{ volume_mounts }}'
  loop_control:
    label: '{{ item.source }}'

- name: Set target device facts
  set_fact:
    resolved_devices: >-
      {{
        resolved_devices | default([]) +
        [{
          'original_item': item.item,
          'target_device': item.stdout.strip(),
          'is_empty_partition': (item.stdout.strip() != item.item.source and item.stdout.strip() != "")
        }]
      }}
  loop: '{{ target_devices.results }}'
  loop_control:
    label: '{{ item.item.source }}'

- name: Check if filesystem exists on target devices
  command: lsblk -rno FSTYPE {{ item.target_device }}
  register: fs_check
  changed_when: false
  failed_when: false
  loop: '{{ resolved_devices | default([]) }}'
  when: item.target_device != ""
  loop_control:
    label: '{{ item.target_device }}'

- name: Format Volumes
  filesystem:
    fstype: '{{ item.item.original_item.filesystem }}'
    dev: '{{ item.item.target_device }}'
    force: false
  when:
    - format_volumes | default(true)
    - item.item.target_device != ""
    - item.stdout == "" or item.rc != 0
  loop: '{{ fs_check.results }}'
  loop_control:
    label: '{{ item.item.target_device }}'

- name: Force Unmount Volume Devices
  ansible.posix.mount:
    path: '{{ item.original_item.mount_point }}'
    state: unmounted
  loop: '{{ resolved_devices }}'
  when:
    - item.target_device != ""
    - item.original_item.mount_point is defined
  loop_control:
    label: '{{ item.original_item.mount_point }}'
  ignore_errors: true

- name: Force Unmount Bind Mounts
  ansible.posix.mount:
    path: '{{ item.mount_point }}'
    state: unmounted
  loop: '{{ bind_mounts }}'
  when: item.mount_point is defined
  loop_control:
    label: '{{ item.mount_point }}'

- name: Generate Random UUIDs and Labels Per Device
  set_fact:
    randomized_devices: >-
      {{
        resolved_devices | map('combine', {
          'new_uuid':  (1000000 | random | string) | to_uuid,
          'new_label': 'disk' ~ 9999 | random
        }) | list
      }}
  when: rotate_additional_volume_metadata | default(false) | bool

- name: Force Check Filesystem on ext4 Devices
  command: e2fsck -f -y {{ item.target_device }}
  loop: '{{ randomized_devices | default([]) }}'
  when:
    - item.original_item.filesystem == 'ext4'
    - item.target_device != ""
    - rotate_additional_volume_metadata | default(false) | bool
  loop_control:
    label: '{{ item.target_device }}'
  failed_when: false

- name: Set New UUID and Label For ext4 Devices
  command: tune2fs -U {{ item.new_uuid }} -L {{ item.new_label }} {{ item.target_device }}
  loop: '{{ randomized_devices | default([]) }}'
  when:
    - item.original_item.filesystem == 'ext4'
    - item.target_device != ""
    - rotate_additional_volume_metadata | default(false) | bool
  loop_control:
    label: '{{ item.target_device }}'

- name: Wait for udev to settle
  command: udevadm settle
  when: rotate_additional_volume_metadata | default(false) | bool

- name: Show Block Device UUIDs
  command: 'lsblk {{ item.target_device }} -no UUID'
  loop: '{{ resolved_devices | default([]) }}'
  when: item.target_device != ""
  register: block_devices
  loop_control:
    label: '{{ item.target_device }}'

- name: Mount Volumes
  mount:
    src: 'UUID={{ item.stdout.strip() }}'
    path: '{{ item.item.original_item.mount_point }}'
    fstype: '{{ item.item.original_item.filesystem }}'
    opts: '{{ item.item.original_item.mount_options }}'
    state: mounted
  loop: '{{ block_devices.results }}'
  when: item.stdout.strip() != ""
  loop_control:
    label: '{{ item.item.original_item.mount_point }}'

- name: Create Mount Source Directories
  file:
    dest: '{{ item.source }}'
    state: directory
    owner: '{{ item.mount_point_owner }}'
    group: '{{ item.mount_point_group }}'
    mode: '{{ item.mount_point_mode }}'
  loop: '{{ bind_mounts }}'

- name: Copy existing data to bind mount source if needed
  command: cp -a {{ item.mount_point }}/. {{ item.source }}/
  when:
    - item.mount_point is defined
    - item.source is defined
    - hetzner_cloud | default(false) | bool
    - item.mount_point != item.source
    - item.mount_point_owner is defined
    - item.mount_point_group is defined
  loop: '{{ bind_mounts }}'

- name: Mount Bind Mounts
  mount:
    src: '{{ item.source }}'
    path: '{{ item.mount_point }}'
    fstype: none
    opts: '{{ item.mount_options }}'
    state: mounted
  loop: '{{ bind_mounts }}'

- name: Cleanup DB Replication Files
  file:
    path: '{{ item }}'
    state: absent
  with_fileglob:
    - /var/lib/mysql/master.info
    - /var/lib/mysql/relay-log.info
    - /var/lib/mysql/relay-log.*
  ignore_errors: yes
  when: cleanup_db_replication_files | default(false) | bool

- name: Replace bind-address IP in config file
  ansible.builtin.replace:
    path: /etc/mysql/conf.d/jingrow.cnf
    regexp: '^bind-address\s*=\s*.*'
    replace: 'bind-address = {{ mariadb_bind_address }}'
  when: mariadb_bind_address is defined and mariadb_bind_address != ""

- name: Restart Filebeat
  service:
    name: filebeat
    state: started
  when: start_filebeat_after_mount | default(false) | bool

- name: Restart Docker
  service:
    name: docker
    state: started
  when: start_docker_after_mount | default(false) | bool

- name: Restart MariaDB
  service:
    name: mysql
    state: started
  when: start_mariadb_after_mount | default(false) | bool
