---
- name: Test lvm pool members
  hosts: all
  become: true
  vars:
    storage_safe_mode: false
    storage_use_partitions: true
    volume_group_size: '10g'
    volume_size: '300m'
  tags:
    - tests::lvm

  tasks:
    - name: Run the role
      include_role:
        name: linux-system-roles.storage

    - name: Mark tasks to be skipped
      set_fact:
        storage_skip_checks:
          - blivet_available
          - "{{ (lookup('env',
                        'SYSTEM_ROLES_REMOVE_CLOUD_INIT') in ['', 'false']) |
                ternary('packages_installed', '') }}"
          - service_facts

    - name: Gather package facts
      package_facts:

    - name: Set blivet package name
      set_fact:
        blivet_pkg_name: "{{ ansible_facts.packages |
          select('search', 'blivet') | select('search', 'python') | list }}"

    - name: Set blivet package version
      set_fact:
        blivet_pkg_version: "{{
          ansible_facts.packages[blivet_pkg_name[0]][0]['version'] +
          '-' + ansible_facts.packages[blivet_pkg_name[0]][0]['release'] }}"

    # end early when running with old blivet where removing PVs from a VG fails
    - name: Run test only if blivet supports this functionality
      when: (blivet_pkg_version is defined and
             ((is_fedora and blivet_pkg_version is version("3.4.3-1", ">=")) or
              (is_rhel7 and blivet_pkg_version is version("3.4.0-10", ">=")) or
              (is_rhel8 and blivet_pkg_version is version("3.4.0-10", ">=")) or
              (is_rhel9 and blivet_pkg_version is version("3.4.0-14", ">=")) or
              is_rhel10))
      vars:
        is_rhel10: "{{ ansible_facts['os_family'] == 'RedHat' and
          ansible_facts['distribution_major_version'] == '10' }}"
        is_rhel9: "{{ ansible_facts['os_family'] == 'RedHat' and
          ansible_facts['distribution_major_version'] == '9' }}"
        is_rhel8: "{{ ansible_facts['os_family'] == 'RedHat' and
          ansible_facts['distribution_major_version'] == '8' }}"
        is_rhel7: "{{ ansible_facts['os_family'] == 'RedHat' and
          ansible_facts['distribution_major_version'] == '7' }}"
        is_fedora: "{{ ansible_facts['distribution'] == 'Fedora' }}"
      block:
        - name: Get unused disks
          include_tasks: get_unused_disk.yml
          vars:
            min_size: "{{ volume_group_size }}"
            disks_needed: 3
            match_sector_size: true

        - name: Create volume group 'foo' with 3 PVs
          include_role:
            name: linux-system-roles.storage
          vars:
            storage_pools:
              - name: foo
                disks: "{{ unused_disks }}"

        - name: Verify role results
          include_tasks: verify-role-results.yml

        - name: Save UUID of the created volume group
          command: vgs --noheading -o vg_uuid foo
          changed_when: false
          register: storage_test_members_vg_uuid

        - name: Verify that nothing changes when disks don't change
          include_role:
            name: linux-system-roles.storage
          vars:
            storage_pools:
              - name: foo
                disks: "{{ unused_disks }}"

        - name: Verify role results
          include_tasks: verify-role-results.yml

        - name: Get UUID of the 'foo' volume group
          command: vgs --noheading -o vg_uuid foo
          changed_when: false
          register: storage_test_members_vg_uuid_after

        - name: Make sure the VG UUID didn't change (VG wasn't removed)
          assert:
            that: storage_test_members_vg_uuid.stdout ==
              storage_test_members_vg_uuid_after.stdout

        - name: Remove 2 PVs from the 'foo' volume group
          include_role:
            name: linux-system-roles.storage
          vars:
            storage_pools:
              - name: foo
                disks: "{{ [unused_disks[0]] }}"

        - name: Get the partition table type on disk removed from the VG
          command: blkid -p -ovalue -s PTTYPE /dev/{{ unused_disks[1] }}
          register: storage_test_removed_pttype
          changed_when: false
          failed_when: not storage_test_removed_pttype.rc in [0, 2]

        - name: Verify that removing the PV from the VG also removed the partition table
          assert:
            that: storage_test_removed_pttype.stdout == ''

        - name: Verify role results
          include_tasks: verify-role-results.yml

        - name: Get UUID of the 'foo' volume group
          command: vgs --noheading -o vg_uuid foo
          changed_when: false
          register: storage_test_members_vg_uuid_after

        - name: Make sure the VG UUID didn't change (VG wasn't removed)
          assert:
            that: storage_test_members_vg_uuid.stdout ==
              storage_test_members_vg_uuid_after.stdout

        - name: Add the second disk back to the 'foo' volume group
          include_role:
            name: linux-system-roles.storage
          vars:
            storage_pools:
              - name: foo
                disks: "{{ [unused_disks[0], unused_disks[1]] }}"

        - name: Verify role results
          include_tasks: verify-role-results.yml

        - name: Get UUID of the 'foo' volume group
          command: vgs --noheading -o vg_uuid foo
          changed_when: false
          register: storage_test_members_vg_uuid_after

        - name: Make sure the VG UUID didn't change (VG wasn't removed)
          assert:
            that: storage_test_members_vg_uuid.stdout ==
              storage_test_members_vg_uuid_after.stdout

        - name: >-
            Remove the first PV and add the third disk to the 'foo' volume group
          include_role:
            name: linux-system-roles.storage
          vars:
            storage_pools:
              - name: foo
                disks: "{{ [unused_disks[1], unused_disks[2]] }}"

        - name: Verify role results
          include_tasks: verify-role-results.yml

        - name: Get UUID of the 'foo' volume group
          command: vgs --noheading -o vg_uuid foo
          changed_when: false
          register: storage_test_members_vg_uuid_after

        - name: Make sure the VG UUID didn't change (VG wasn't removed)
          assert:
            that: storage_test_members_vg_uuid.stdout ==
              storage_test_members_vg_uuid_after.stdout

        - name: Create volume group 'foo' with 3 encrypted PVs
          include_role:
            name: linux-system-roles.storage
          vars:
            storage_safe_mode: false
            storage_pools:
              - name: foo
                encryption: true
                encryption_password: yabbadabbadoo
                disks: "{{ unused_disks }}"

        - name: Save UUID of the created volume group
          command: vgs --noheading -o vg_uuid foo
          changed_when: false
          register: storage_test_members_vg_uuid

        - name: Remove 2 PVs from the 'foo' volume group
          include_role:
            name: linux-system-roles.storage
          vars:
            storage_pools:
              - name: foo
                encryption: true
                encryption_password: yabbadabbadoo
                disks: "{{ [unused_disks[0]] }}"

        - name: Verify role results
          include_tasks: verify-role-results.yml

        - name: Get UUID of the 'foo' volume group
          command: vgs --noheading -o vg_uuid foo
          changed_when: false
          register: storage_test_members_vg_uuid_after

        - name: Make sure the VG UUID didn't change (VG wasn't removed)
          assert:
            that: storage_test_members_vg_uuid.stdout ==
              storage_test_members_vg_uuid_after.stdout

        - name: Add the disks back to the 'foo' volume group
          include_role:
            name: linux-system-roles.storage
          vars:
            storage_pools:
              - name: foo
                encryption: true
                encryption_password: yabbadabbadoo
                disks: "{{ unused_disks }}"

        - name: Verify role results
          include_tasks: verify-role-results.yml

        - name: Get UUID of the 'foo' volume group
          command: vgs --noheading -o vg_uuid foo
          changed_when: false
          register: storage_test_members_vg_uuid_after

        - name: Make sure the VG UUID didn't change (VG wasn't removed)
          assert:
            that: storage_test_members_vg_uuid.stdout ==
              storage_test_members_vg_uuid_after.stdout

        - name: Create a new volume group with a logical volume
          include_role:
            name: linux-system-roles.storage
          vars:
            storage_pools:
              - name: foo
                disks: "{{ unused_disks[0] }}"
                encryption: false
                volumes:
                  - name: test
                    size: "{{ volume_size }}"

        - name: Save UUID of the created volume group
          command: vgs --noheading -o vg_uuid foo
          changed_when: false
          register: storage_test_members_vg_uuid

        - name: Verify role results
          include_tasks: verify-role-results.yml

        - name: Add a second PV to the VG
          include_role:
            name: linux-system-roles.storage
          vars:
            storage_pools:
              - name: foo
                disks: "{{ [unused_disks[0], unused_disks[1]] }}"
                volumes:
                  - name: test
                    size: "{{ volume_size }}"

        - name: Get UUID of the 'foo' volume group
          command: vgs --noheading -o vg_uuid foo
          changed_when: false
          register: storage_test_members_vg_uuid_after

        - name: Make sure the VG UUID didn't change (VG wasn't removed)
          assert:
            that: storage_test_members_vg_uuid.stdout ==
              storage_test_members_vg_uuid_after.stdout

        - name: Remove the first PV from the VG
          include_role:
            name: linux-system-roles.storage
          vars:
            storage_pools:
              - name: foo
                disks: "{{ [unused_disks[1]] }}"
                volumes:
                  - name: test
                    size: "{{ volume_size }}"

        - name: Get the partition table type on disk removed from the VG
          command: blkid -p -ovalue -s PTTYPE /dev/{{ unused_disks[0] }}
          register: storage_test_removed_pttype
          changed_when: false
          failed_when: not storage_test_removed_pttype.rc in [0, 2]

        - name: Verify that removing the PV from the VG also removed the partition table
          assert:
            that: storage_test_removed_pttype.stdout == ''

        - name: Get UUID of the 'foo' volume group
          command: vgs --noheading -o vg_uuid foo
          changed_when: false
          register: storage_test_members_vg_uuid_after

        - name: Make sure the VG UUID didn't change (VG wasn't removed)
          assert:
            that: storage_test_members_vg_uuid.stdout ==
              storage_test_members_vg_uuid_after.stdout

        - name: Clean up
          include_role:
            name: linux-system-roles.storage
          vars:
            storage_pools:
              - name: foo
                disks: "{{ unused_disks }}"
                state: absent

        - name: Verify role results
          include_tasks: verify-role-results.yml
