--- - name: create zfs filesystems loop: "{{ fileserver_zfs_filesystems }}" loop_control: label: "{{ item.pool | default(fileserver_zfs_default_pool) }}/{{ item.name }}" zfs: name: "{{ item.pool | default(fileserver_zfs_default_pool) }}/{{ item.name }}" state: present extra_zfs_properties: "{{ fileserver_zfs_common_properties | combine(item.properties | default({})) | dehumanize_zfs_properties }}" - name: install nfs-server and rsync apt: name: - nfs-kernel-server - rsync state: present # rpc.statd is only needed for NFSv2 and NFSv3 - name: disable rpc.statd lineinfile: path: /etc/default/nfs-common regexp: '^NEED_STATD=' line: 'NEED_STATD=no' notify: restart nfs-server - name: disable NFSv2 and NFSv3 lineinfile: path: /etc/default/nfs-kernel-server regexp: '^RPCMOUNTDOPTS="(.*?) ?(--no-nfs-version 2 --no-nfs-version 3)?"' backrefs: yes line: 'RPCMOUNTDOPTS="\1 --no-nfs-version 2 --no-nfs-version 3"' notify: restart nfs-server - name: create export root directory file: path: "{{ fileserver_nfs_root }}" state: directory - name: create bind mounts for all filesystems to be exported loop: "{{ fileserver_zfs_filesystems }}" loop_control: label: "{{ item.export_as | default(item.name) }}" when: (item.export is not defined) or (item.export | bool) mount: src: "{{ ((zfs_pools[(item.pool | default(fileserver_zfs_default_pool))].mountpoint), item.name) | path_join }}" path: "{{ fileserver_nfs_root }}/{{ item.export_as | default(item.name) }}" fstype: none opts: defaults,bind,x-systemd.automount,nofail state: mounted notify: restart nfs-server - name: generate list of all export destinations set_fact: filesearver_nfs_all_destinations: "{{ fileserver_nfs_default_destinations | map(attribute='dest') | list | union(fileserver_zfs_filesystems | selectattr('export_to', 'defined') | map(attribute='export_to') | flatten | map(attribute='dest') | list) | ansible.utils.cidr_merge }}" - name: export filesystems blockinfile: path: /etc/exports block: | {{ fileserver_nfs_root }} {% for dest in filesearver_nfs_all_destinations %} {{ dest }}(ro,fsid=0,sync,crossmnt){% endfor %}{{ '' }} {% for fs in fileserver_zfs_filesystems %} {% if (fs.export is not defined) or (fs.export | bool) %} {{ fileserver_nfs_root }}/{{ fs.export_as | default(fs.name) }} {% for d in fs.export_to | default(fileserver_nfs_default_destinations) %} {{ d.dest }}({{ d.opts | default(fileserver_nfs_default_options) | join(',') }}){% endfor %}{{ '' }} {% endif %} {% endfor %} notify: restart nfs-server - name: create fileserver groups loop: "{{ fileserver_group_ids | default({}) | dict2items }}" loop_control: label: "{{ item.key }}" group: name: "{{ item.key }}" gid: "{{ item.value }}" - name: create conanical groups for fileserver users loop: "{{ fileserver_users | default({}) | dict2items }}" loop_control: label: "{{ item.key }}" group: name: "{{ item.key }}" gid: "{{ item.value.id | default(omit) }}" state: present - name: create fileserver users loop: "{{ fileserver_users | default({}) | dict2items }}" loop_control: label: "{{ item.key }}" user: name: "{{ item.key }}" uid: "{{ item.value.id | default(omit) }}" state: present group: "{{ item.key }}" groups: "{{ item.value.groups | default(omit) }}" - name: set filesystem root-dir permissions loop: "{{ fileserver_zfs_filesystems }}" loop_control: label: "{{ item.pool | default(fileserver_zfs_default_pool) }}/{{ item.name }}" when: item.owner is defined or item.group is defined or item.mode is defined file: path: "{{ ((zfs_pools[(item.pool | default(fileserver_zfs_default_pool))].mountpoint), item.name) | path_join }}" owner: "{{ item.owner | default(omit) }}" group: "{{ item.group | default(omit) }}" mode: "{{ item.mode | default(omit) }}"