# Copyright 2022 OCF Ltd. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # -*- coding: utf-8 -*- # vim: ft=yaml --- ######## parse exports list, filter on target host and tag as exporter/consumer, run role with filtered export list by type # # NOTE # - mandatory fields in each list item in the exports dict are 'consumer' and 'type', all other fields are role specific # - consumers list items can be ansible inventory groups or individual hosts # - this logic will set a host that is both the exporter and the consumer to have the exporter tag # it is not expected that a host will mount its own export # however, if this is required - add another dict to the exports list with only a consumer list and explicitly no exporter list # multiple/group exporters entries logic will heavily rely on dynamic named client mount points - this will mean other roles that use mount points will have todo lookup # make this task only take exporter ansible_hostname[0] and no groups, to simplify render the autofs config # # - name: build exports list for target host, add tag for exporter or consumer action # set_fact: # _target_exports: "{{ _target_exports | default([]) + ([export_definition]) }}" # loop: "{{ autofs['exports'] }}" # loop_control: # loop_var: entry # vars: # consumer_group_match: "{{ entry['consumer'] | intersect(active_role_groups) }}" # consumer_host_match: "{{ entry['consumer'] | intersect(ansible_hostname) }}" # exporter_group_match: "{{ entry['exporter'] | default ([]) | intersect(active_role_groups) }}" # exporter_host_match: "{{ entry['exporter'] | default ([]) | intersect(ansible_hostname) }}" # toggle_exporter_group: "{{ exporter_group_match | length >0 }}" # toggle_exporter_host: "{{ exporter_host_match | length >0 }}" # toggle_exporter: "{{ ((toggle_exporter_group + toggle_exporter_host) | int >0) | ternary('exporter', 'consumer') }}" # export_definition: "{{ entry | default({}) | combine({ 'action': toggle_exporter }, recursive=True) }}" # when: # - consumer_group_match | length>0 or # consumer_host_match | length>0 or # exporter_group_match | length>0 or # exporter_host_match | length >0 - name: build exports list for target host, add tag for exporter or consumer action set_fact: _target_exports: "{{ _target_exports | default([]) + ([export_definition]) }}" loop: "{{ autofs['exports'] }}" loop_control: loop_var: entry vars: consumer_group_match: "{{ entry['consumer'] | intersect(active_role_groups) }}" consumer_host_match: "{{ entry['consumer'] | intersect(ansible_hostname) }}" exporter_host_match: "{{ entry['exporter'] | default ([]) | intersect(ansible_hostname) }}" toggle_exporter_host: "{{ exporter_host_match | length >0 }}" toggle_exporter: "{{ (toggle_exporter_host | int >0) | ternary('exporter', 'consumer') }}" export_definition: "{{ entry | default({}) | combine({ 'action': toggle_exporter }, recursive=True) }}" when: - consumer_group_match | length>0 or consumer_host_match | length>0 or exporter_host_match | length >0 # - debug: # msg: "{{ _target_exports }}" ######## run role with filtered export list by type - name: Run NFS role include_role: name: nfs vars: exports: "{{ _target_exports | selectattr('type', '==', 'nfs' ) }}" toggle_run: "{{ exports | length >0 }}" when: - autofs['nfs']['enabled'] | bool - toggle_run - name: Run Lustre role include_role: name: lustre vars: exports: "{{ _target_exports | selectattr('type', '==', 'lustre' ) }}" toggle_run: "{{ exports | length >0 }}" when: - autofs['lustre']['enabled'] | bool - toggle_run - name: Run Spectrum Scale role include_role: name: gpfs vars: exports: "{{ _target_exports | selectattr('type', '==', 'gpfs' ) }}" toggle_run: "{{ exports | length >0 }}" when: - autofs['gpfs']['enabled'] | bool - toggle_run - name: Run BeeGFS role include_role: name: beegfs vars: exports: "{{ _target_exports | selectattr('type', '==', 'beegfs' ) }}" toggle_run: "{{ exports | length >0 }}" when: - autofs['beegfs']['enabled'] | bool - toggle_run ######## configure autofs - name: Install and map autofs paths block: - name: Install autofs package package: name: autofs state: latest - name: Configure autofs master template: dest: /etc/auto.master src: templates/auto.master.j2 mode: 0644 trim_blocks: False notify: Restart autofs - name: Configure autofs process template: dest: /etc/autofs.conf src: templates/autofs.conf.j2 mode: 0644 trim_blocks: False notify: Restart autofs # bring logic inboard from the jinja template using the exporter/consumer logic # this is tailored for nfs (see vers param), likely there will be multiple replica tasks to account for different mount types, these should all add to the _map_list - name: Build autofs mapping ansible.builtin.set_fact: _map_list: "{{ _map_list | default([]) + [autofs_entry] }}" loop: "{{ _target_exports }}" loop_control: loop_var: entry vars: mount: "{{ entry['mount'] }}" fstype: "{{ entry['type'] }}" vers: "{{ autofs[fstype]['default_version'] }}" exporter: "{{ entry['exporter'] | first }}" export: "{{ entry['export'] }}" autofs_entry: "{{ mount }} -fstype={{ fstype }},vers={{ vers }} {{ exporter }}:{{ export }}" when: - _target_exports | selectattr('action', '==', 'consumer' ) - name: Configure autofs mapping template: dest: /etc/autofs-{{ config_namespace }}.map src: autofs.map.j2 mode: 0644 trim_blocks: False notify: Restart autofs - name: AutoFS configured ansible.builtin.set_fact: autofs_configured: true when: - autofs['enabled'] | bool # Refresh facts and services facts after these will have been configured by # the autofs role - name: Refresh service facts ansible.builtin.service_facts: - name: Refresh facts ansible.builtin.setup: