main.ymlΒΆ

---
- name: "πŸ“¦ Install the userspace nfs-ganesha server"
  package_install: # nocheck: package-install only the ganesha NFS flavor includes this file
    id:
      - nfs-ganesha
      - libntirpc

- name: "πŸ“„ Install the nfs-ganesha unit the AUR package does not ship"
  ansible.builtin.copy:
    src: nfs-ganesha.service
    dest: "/etc/systemd/system/{{ SVC_STORAGE_NFS_SERVER_SERVICE['ganesha']['Archlinux'] }}.service"
    owner: root
    group: root
    mode: "0644"
  when: ansible_facts['os_family'] == 'Archlinux'
  notify: "restart-nfs-ganesha"

- name: "πŸ”§ Mask the broken nfs-ganesha-config helper unit"
  ansible.builtin.systemd:
    name: nfs-ganesha-config.service
    masked: true

- name: "βœ… Ensure the ganesha config directory exists"
  ansible.builtin.file:
    path: /etc/ganesha
    state: directory
    owner: root
    group: root
    mode: "0755"

- name: "πŸ”§ Pin NFSv4 idmap Domain (else www-data renders as nobody)"
  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: "πŸ“„ Render /etc/ganesha/ganesha.conf"
  ansible.builtin.template: # nocheck: stack-host-template (per-host NFS server config (NFS host is its own group, not the stack host))
    src: ganesha.conf.j2
    dest: /etc/ganesha/ganesha.conf
    owner: root
    group: root
    mode: "0644"
  notify: "restart-nfs-ganesha"

- name: "πŸ“ Ensure the nfs-ganesha systemd drop-in dir exists"
  ansible.builtin.file:
    path: "/etc/systemd/system/{{ SVC_STORAGE_NFS_SERVER_SERVICE['ganesha'][ansible_facts['os_family']] }}.service.d"
    state: directory
    owner: root
    group: root
    mode: "0755"

- name: "🧩 Install nfs-ganesha auto-restart drop-in"
  ansible.builtin.copy:
    src: nfs-ganesha-restart.conf
    dest: "/etc/systemd/system/{{ SVC_STORAGE_NFS_SERVER_SERVICE['ganesha'][ansible_facts['os_family']] }}.service.d/restart.conf"
    owner: root
    group: root
    mode: "0644"
  notify: "restart-nfs-ganesha"

- name: "πŸ”„ Reload systemd so the drop-in is live before ganesha starts"
  ansible.builtin.systemd:
    daemon_reload: true

- name: "πŸ” Detect which rpcbind units this distro ships"
  ansible.builtin.command:
    cmd: systemctl list-unit-files rpcbind.socket rpcbind.service --no-legend
  register: _rpcbind_units
  changed_when: false
  failed_when: >-
    _rpcbind_units.rc != 0
    and ((_rpcbind_units.stderr | length) > 0 or _rpcbind_units.rc != 1)

- name: "πŸ”§ Mask rpcbind so ganesha's startup unregister cannot wedge on its local socket"
  ansible.builtin.systemd:
    name: "{{ item }}"
    masked: true
    state: stopped
  loop: "{{ _rpcbind_units.stdout_lines | map('regex_replace', '^([^ ]+).*$', '\\1') | list }}"

- name: "🟒 Enable nfs-ganesha at boot"
  ansible.builtin.systemd:
    name: "{{ SVC_STORAGE_NFS_SERVER_SERVICE['ganesha'][ansible_facts['os_family']] }}"
    enabled: true

- name: "🚿 Flush handlers so a pending config change restarts ganesha first"
  ansible.builtin.meta: flush_handlers

- name: "🟒 Ensure nfs-ganesha serves on 2049"
  ansible.builtin.script:
    cmd: "{{ SVC_STORAGE_NFS_SERVER_GANESHA_SERVE }} start"
  register: svc_storage_nfs_server_ganesha_start
  changed_when: "'CHANGED' in svc_storage_nfs_server_ganesha_start.stdout"