---
- name: Pre-hook Ansible tasks
  hosts: localhost

  tasks:
    - name: Load Plan
      include_vars:
        file: plan.yml
        name: plan

    - name: Load Workload
      include_vars:
        file: workload.yml
        name: workload

    - name: End the play for Windows
      meta: end_host
      when: "'windows' in workload.vm.guestid"

    - name:
      getent:
        database: passwd
        key: '{{ ansible_user_id }}'
        split: ':'

    - name: Ensure SSH directory exists
      file:
        path: ~/.ssh
        state: directory
        mode: 0700
      environment:
        HOME: '{{ ansible_facts.getent_passwd[ansible_user_id][4] }}'

    - k8s_info:
        api_version: v1
        kind: Secret
        name: ssh-credentials
        namespace: migration-plans
      register: ssh_credentials

    - name: Create SSH key
      copy:
        dest: ~/.ssh/id_rsa
        content: '{{ ssh_credentials.resources[0].data.key | b64decode }}'
        mode: 0600

    - add_host:
        name: '{{ workload.vm.ipaddress }}'
        ansible_user: local_host
        groups: vms

- hosts: vms
  tasks:
    - name: Display fstab contents prior to prehook changes
      environment:
        ANSIBLE_VERBOSITY: 2
      command: cat /etc/fstab
      register: fstab_output

    - name: Print to console
      debug:
        msg: "{{fstab_output.stdout}}"

    - name: Gather bootfs device name
      ansible.builtin.set_fact:
        boot_fs: '{{ ansible_mounts | community.general.json_query(query) | first }}'
      vars:
        query: "[?mount=='/boot'].device"

    # new tasks for swap partitions - no previous tasks file
    - name: Detect swap partitions
      ansible.builtin.shell: swapon -s | grep partition | awk '{ print $1 }'
      become: true
      register: swap_status
      tags:
        - skip_ansible_lint

    - name: Set label for swap partitions
      ansible.builtin.command:
        cmd: swaplabel {{ item }} -L Swap{{ i }}
      become: true
      notify: Sync partition data
      loop: '{{ swap_status.stdout_lines }}'
      loop_control:
        index_var: i
      tags:
        - skip_ansible_lint

    - name: Remove all swap from /etc/fstab
      ansible.builtin.lineinfile:
        path: /etc/fstab
        regexp: '\sswap\s'
        state: absent
      become: true

    - name: Add default swap file to /etc/fstab
      ansible.posix.mount:
        path: none
        src: '/pagefile.sys'
        fstype: swap
        opts: defaults
        state: present
      become: true

    - name: Add swap partitions to /etc/fstab using labels
      ansible.posix.mount:
        path: none
        src: 'LABEL=Swap{{ i }}'
        fstype: swap
        opts: defaults
        state: present
      become: true
      loop: '{{ swap_status.stdout_lines }}'
      loop_control:
        index_var: i
      tags:
        - skip_ansible_lint

    # tasks file for rootfs_label
    - name: Set label for UEFI / filesystem
      ansible.builtin.command:
        cmd: xfs_io -c "label -s System" /
      become: true
      notify: Sync partition data
      tags:
        - skip_ansible_lint

    # tasks file for bootfs_label
    - name: Check if system is UEFI or MBR
      ansible.builtin.stat:
        path: /sys/firmware/efi
      register: _is_efi

    - name: Set label for MBR BIOS /boot filesystem
      ansible.builtin.command:
        cmd: e2label {{ boot_fs }} Boot
      when: _is_efi.stat.exists == false
      become: true
      notify: Sync partition data
      tags:
        - skip_ansible_lint

    - name: Set label for UEFI ESP filesystem
      ansible.builtin.command:
        cmd: fatlabel /dev/sda1 ESP
      when: _is_efi.stat.exists == true
      become: true
      notify: Sync partition data
      tags:
        - skip_ansible_lint

    # tasks file for storagefs_label
    - name: Show mounts
      ansible.builtin.debug:
        msg: '{{ ansible_facts.mounts }}'

    - name: Set label for extra XFS filesystem(s)
      ansible.builtin.command:
        cmd: xfs_io -c "label -s Storage{{ i - 1 }}" "{{ item.mount }}"
      become: true
      when: item.fstype == "xfs" and 'bind' not in item.options and item.mount != '/' and item.mount != '/boot'
      loop: '{{ ansible_facts.mounts }}'
      loop_control:
        index_var: i
      notify: Sync partition data
      tags:
        - skip_ansible_lint

    - name: Set label for extra Ext4 filesystem(s)
      ansible.builtin.command:
        cmd: e2label {{ item.device }} "Storage{{ i - 1 }}"
      become: true
      when: (item.fstype == "ext4" or item.fstype == "ext2") and item.mount != '/' and item.mount != '/boot'
      loop: '{{ ansible_facts.mounts }}'
      loop_control:
        index_var: i
      notify: Sync partition data
      tags:
        - skip_ansible_lint

    # tasks file for mutate_fstab
    - name: Check if system is UEFI or MBR
      ansible.builtin.stat:
        path: /sys/firmware/efi
      register: _is_efi

    - name: Convert / mount to label in /etc/fstab
      ansible.posix.mount:
        path: /
        src: LABEL=System
        fstype: xfs
        opts: defaults,usrquota,prjquota
        dump: 1
        passno: 1
        state: present
      become: true

    - name: Convert /boot to label in /etc/fstab
      ansible.posix.mount:
        path: /boot
        src: LABEL=Boot
        fstype: ext2
        opts: rw,acl,user_xattr
        dump: 1
        passno: 2
        state: present
      become: true
      when: _is_efi.stat.exists == false
      tags:
        - skip_ansible_lint

    - name: Convert /boot/efi mount to label in /etc/fstab
      ansible.posix.mount:
        path: /boot/efi
        src: LABEL=ESP
        fstype: vfat
        opts: rw,umask=0002,utf8=true
        dump: 1
        passno: 2
        state: present
      become: true
      when: _is_efi.stat.exists == true
      tags:
        - skip_ansible_lint

    - name: Convert extra XFS storage mounts to use labels in /etc/fstab
      ansible.posix.mount:
        path: '{{ item.mount }}'
        src: 'LABEL=Storage{{ i - 1 }}'
        fstype: '{{ item.fstype }}'
        opts: defaults,usrquota,prjquota
        dump: 1
        passno: 2
        state: present
      become: true
      when: item.fstype == "xfs" and 'bind' not in item.options and item.mount != '/' and item.mount != '/boot'
      loop: '{{ ansible_facts.mounts }}'
      loop_control:
        index_var: i
      tags:
        - skip_ansible_lint

    # different section for Ext4, since it's mount options are slightly different
    - name: Convert extra Ext4 storage mounts to use labels in /etc/fstab
      ansible.posix.mount:
        path: '{{ item.mount }}'
        src: 'LABEL=Storage{{ i - 1 }}'
        fstype: '{{ item.fstype }}'
        opts: rw,acl,user_xattr,quota,project
        dump: 1
        passno: 2
        state: present
      become: true
      when: (item.fstype == "ext4" or item.fstype == "ext2") and item.mount != '/' and item.mount != '/boot'
      loop: '{{ ansible_facts.mounts }}'
      loop_control:
        index_var: i
      tags:
        - skip_ansible_lint

    - name: Display fstab contents AFTER prehook changes
      environment:
        ANSIBLE_VERBOSITY: 2
      command: cat /etc/fstab
      register: fstab_output

    - name: Print to console
      debug:
        msg: "{{fstab_output.stdout}}"

  handlers:
    - name: Sync partition data
      ansible.builtin.command:
        cmd: partprobe
      become: true
      changed_when: true
