main.ymlΒΆ

---
- name: "βœ… Assert the NFS server is configured"
  ansible.builtin.assert:
    that:
      - storage.nfs.server is defined
      - storage.nfs.server | length > 0
    fail_msg: |
      svc-storage-nfs-client requires `storage.nfs.server` to be set in
      the inventory (see group_vars/all/15_storage.yml). A reachable NFS
      server IP/hostname is mandatory.

- name: "πŸ“¦ Install the NFS client"
  package_install: # nocheck: package-install the controller installs it too, by delegation from the NFS server role
    id: nfs-client

- name: "πŸ”§ Match NFSv4 idmap to the ganesha test server"
  when: RUNTIME in ['dev', 'act']
  block:
    - name: "πŸ”§ Set idmapd.conf Domain = localdomain"
      ansible.builtin.lineinfile:
        path: /etc/idmapd.conf
        regexp: "^#?\\s*Domain\\s*="
        line: "Domain = localdomain"
        insertafter: "^\\[General\\]"
        create: true
        owner: root
        group: root
        mode: "0644"

    - name: "🧹 Drop stale NFSv4 idmap cache entries"
      ansible.builtin.command: nfsidmap -c
      changed_when: false
      failed_when: false

- name: "βœ… Ensure probe mount point exists"
  ansible.builtin.file:
    path: "{{ SVC_STORAGE_NFS_CLIENT_PROBE_DIR }}"
    state: directory
    owner: root
    group: root
    mode: "0700"

- name: "πŸ” Probe-mount the NFS export"
  ansible.posix.mount:
    path: "{{ SVC_STORAGE_NFS_CLIENT_PROBE_DIR }}"
    src: "{{ STORAGE_NFS_CLIENT_SRC }}"
    fstype: "{{ STORAGE_NFS_FSTYPE }}"
    opts: "{{ STORAGE_NFS_MOUNT_OPTS }},_netdev"
    boot: false
    state: ephemeral
  register: svc_storage_nfs_client_probe
  failed_when:
    - svc_storage_nfs_client_probe is failed

- name: "πŸ”§ Align the NFS client's directory delegations with the ganesha server"
  ansible.builtin.include_tasks: directory_delegations.yml
  when: lookup('nfs_flavor') == 'ganesha'

- name: "πŸ” Probe-write a marker to confirm the mount is RW"
  ansible.builtin.copy:
    dest: "{{ SVC_STORAGE_NFS_CLIENT_PROBE_DIR }}/.svc-storage-nfs-client-probe.{{ inventory_hostname }}"
    content: |
      probed-by={{ inventory_hostname }}
      probed-at={{ ansible_facts.date_time.iso8601 }}
    mode: "0644"

- name: "πŸ”— Unmount probe mount"
  ansible.posix.mount:
    path: "{{ SVC_STORAGE_NFS_CLIENT_PROBE_DIR }}"
    state: unmounted

- name: "πŸ” Detect {{ DIR_VAR_LIB }} pre-mount state"
  ansible.builtin.script:
    cmd: "{{ role_path }}/files/shell/premount_state.sh"
    executable: /bin/bash
  environment:
    DIR_VAR_LIB: "{{ DIR_VAR_LIB }}"
  register: _svc_storage_nfs_client_premount_state
  changed_when: false

- name: "βœ… Assert no pre-existing local data at {{ DIR_VAR_LIB }} (mount would hide it)"
  ansible.builtin.assert:
    that:
      - >-
        'STATE=mounted' in _svc_storage_nfs_client_premount_state.stdout
        or 'STATE=empty' in _svc_storage_nfs_client_premount_state.stdout
    fail_msg: >-
      Pre-existing local data found at {{ DIR_VAR_LIB }}; NFS mount-over
      would silently hide it. Migrate or remove the local tree manually,
      then re-run the deploy. Probe said:
      {{ _svc_storage_nfs_client_premount_state.stdout | trim }}

- name: "βœ… Ensure infinito state mount point exists"
  ansible.builtin.file:
    path: "{{ DIR_VAR_LIB }}"
    state: directory
    owner: root
    group: root
    mode: "0755"

- name: "πŸ” Detect a pending change of the {{ DIR_VAR_LIB }} mount"
  ansible.posix.mount:
    path: "{{ DIR_VAR_LIB }}"
    src: "{{ STORAGE_NFS_CLIENT_SRC }}"
    fstype: "{{ STORAGE_NFS_FSTYPE }}"
    opts: "{{ STORAGE_NFS_MOUNT_OPTS }},_netdev"
    state: mounted
  check_mode: true
  register: svc_storage_nfs_client_state_pending

- name: "πŸ”Œ Release {{ DIR_BACKUPS }} so the state mount can be remounted"
  ansible.posix.mount:
    path: "{{ DIR_BACKUPS }}"
    state: unmounted
  when: svc_storage_nfs_client_state_pending is changed

- name: "πŸ”— Persistently mount cluster-shared infinito state from NFS"
  ansible.posix.mount:
    path: "{{ DIR_VAR_LIB }}"
    src: "{{ STORAGE_NFS_CLIENT_SRC }}"
    fstype: "{{ STORAGE_NFS_FSTYPE }}"
    opts: "{{ STORAGE_NFS_MOUNT_OPTS }},_netdev"
    state: mounted

- name: "βœ… Ensure the node-local backup store exists"
  ansible.builtin.file:
    path: "{{ SVC_STORAGE_NFS_CLIENT_BACKUPS_DIR }}"
    state: directory
    mode: "0755"

- name: "πŸ”— Keep {{ DIR_BACKUPS }} node-local over the shared state"
  ansible.posix.mount:
    path: "{{ DIR_BACKUPS }}"
    src: "{{ SVC_STORAGE_NFS_CLIENT_BACKUPS_DIR }}"
    fstype: none
    opts: bind,_netdev
    state: mounted