diff --git a/roles/beegfs_role/defaults/main.yml b/roles/beegfs_role/defaults/main.yml new file mode 100644 index 0000000000..9a65af7f6a --- /dev/null +++ b/roles/beegfs_role/defaults/main.yml @@ -0,0 +1,126 @@ +# Copyright 2021 Dell Inc. or its subsidiaries. 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. +--- +# Option to enable/disable services +beegfs_enable: + mgmt: false + meta: false + oss: false + admon: false + client: false + tuning: false + +# Can be present or absent +beegfs_state: present + +# Kernel modules to ensure are loaded prior to BeeGFS deploy/startup +beegfs_kmod_preload: [] + +# Network interfaces in order of preference +# (leaving empty means InfiniBand & RDMA enabled devices are preferred) +beegfs_interfaces: [] + +# Distribution-specific parameters +beegfs_distro_vars: + RedHat: + beegfs_repo_url: "https://www.beegfs.io/release/latest-stable/dists/beegfs-rhel8.repo" + beegfs_repo_key: "https://www.beegfs.io/release/latest-stable/gpg/RPM-GPG-KEY-beegfs" + beegfs_repo_file: "/etc/yum.repos.d/beegfs-rhel8.repo" + kernel_dev_pkg: "kernel-devel" + rdma_dev_pkgs: + - "librdmacm" + - "libibmad" + - "libibumad" + - "rdma-core" + - "libibverbs" + - "libibverbs-utils" + - "libbeegfs-ib" + + Rocky: + beegfs_repo_url: "https://www.beegfs.io/release/latest-stable/dists/rocky" + beegfs_repo_key: "https://www.beegfs.io/release/latest-stable/gpg/RPM-GPG-KEY-beegfs" + beegfs_repo_file: "/etc/yum.repos.d/beegfs-rocky.repo" + kernel_dev_pkg: "kernel-devel" + rdma_dev_pkgs: + - "librdmacm" + - "libibmad" + - "libibumad" + - "rdma-core" + - "libibverbs" + - "libibverbs-utils" + - "libbeegfs-ib" + + Debian: + beegfs_repo_url: "https://www.beegfs.io/release/latest-stable/dists/beegfs-deb9.list" + beegfs_repo_key: "https://www.beegfs.io/release/latest-stable/gpg/DEB-GPG-KEY-beegfs" + beegfs_repo_file: "/etc/apt/sources.list.d/beegfs_deb9.list" + kernel_dev_pkg: "linux-headers" + rdma_dev_pkgs: + - "librdmacm-dev" + - "libibmad-dev" + - "libibumad-dev" + - "libibverbs-dev" + - "libbeegfs-ib" + +# BeeGFS repo +beegfs_add_repos: true +beegfs_repo_url: "{{ beegfs_distro_vars[ansible_os_family]['beegfs_repo_url'] }}" +beegfs_repo_key: "{{ beegfs_distro_vars[ansible_os_family]['beegfs_repo_key'] }}" +beegfs_repo_file: "{{ beegfs_distro_vars[ansible_os_family]['beegfs_repo_file'] }}" + +# Define to enable support for BeeGFS data transport over RDMA (IB, OPA, RoCE) +beegfs_rdma: true + +# Default filesystem options +beegfs_filesystem_opts: "-K -d su=128k,sw=8 -l version=2,su=128k -isize=512" +beegfs_mount_opts: "noatime,nodiratime,logbufs=8,logbsize=256k,largeio,inode64,swalloc,allocsize=131072k,nobarrier" +beegfs_force_format: false +beegfs_fstype: "xfs" + +# Storage server options +beegfs_oss_path_prefix: "/data/beegfs/beegfs_oss" +beegfs_oss: + - port: 8003 + dev: "/dev/sdb" + path: # specifying dev overrides path +beegfs_oss_tunable: "{{ beegfs_oss | selectattr('dev', 'defined') | map(attribute='dev') | map('relpath', '/dev/' ) | list }}" +# Whether to support multiple ports per OSS: +# - if this is set to false, make sure that you configure the ports to the same +# value when passing beegfs_oss as an input. +beegfs_oss_multi_port: true + +# Management options +beegfs_mgmt_path: "/data/beegfs/beegfs_mgmtd" +beegfs_mgmt_host: # Example: "{{ groups['cluster_beegfs_mgmt'] | first }}" + +# Metadata storage options +beegfs_meta_path: "/data/beegfs/beegfs_meta" +beegfs_meta_dev: # /dev/sdb +beegfs_meta_fstype: # Example: "ext4" + +# Client mount configs +beegfs_client: [] +# Each item in the beegfs_client list should look like this: +# - path: "/mnt/beegfs" # If there are multiple clients, use different path for each client. +# port: 8004 # If there are multiple clients, use different port for each client. +# mgmt_host: # Use this to override the default beegfs_mgmt_host in cases there are multiple clients. + +# Should the package manager use the `present` or `latest` flag for +# BeeGFS? This is useful for upgrading. +beegfs_update: false +beegfs_package_action: "{{ 'latest' if beegfs_update | bool else 'present' }}" + +# Path to the kernel module +beegfs_kernel_module: "/lib/modules/{{ ansible_kernel }}/updates/fs/beegfs_autobuild/beegfs.ko" +... diff --git a/roles/beegfs_role/files/beegfs-client.service.d/override.conf b/roles/beegfs_role/files/beegfs-client.service.d/override.conf new file mode 100644 index 0000000000..ba52b4fa28 --- /dev/null +++ b/roles/beegfs_role/files/beegfs-client.service.d/override.conf @@ -0,0 +1,7 @@ +# The reason for this change is to enable beegfs-client.service to persist +# through reboots in hyperconverged setup where the client and the oss server is +# running node and the client is not allowed to mount until oss server is ready. +[Service] +Type=forking +Restart=on-failure +RestartSec=5s diff --git a/roles/beegfs_role/files/beegfs-oss-tuning.service b/roles/beegfs_role/files/beegfs-oss-tuning.service new file mode 100644 index 0000000000..0bf8861883 --- /dev/null +++ b/roles/beegfs_role/files/beegfs-oss-tuning.service @@ -0,0 +1,13 @@ +[Unit] +Description=BeeGFS Tuning Service +Documentation=http://www.beegfs.com/content/documentation/ +Requires=network-online.target +After=network-online.target + +[Service] +ExecStart=/bin/bash /opt/beegfs/beegfs-oss-tuning.sh +Type=oneshot +RemainAfterExit=1 + +[Install] +WantedBy=multi-user.target diff --git a/roles/beegfs_role/handlers/main.yml b/roles/beegfs_role/handlers/main.yml new file mode 100644 index 0000000000..1b727f3e00 --- /dev/null +++ b/roles/beegfs_role/handlers/main.yml @@ -0,0 +1,69 @@ +# Copyright 2020 Dell Inc. or its subsidiaries. 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. +--- +- name: Restart BeeGFS mgmt service + systemd: + name: beegfs-mgmtd + daemon-reload: true + state: restarted + become: true + when: beegfs_enable.mgmt | bool + +- name: Restart BeeGFS meta service + systemd: + name: beegfs-meta + daemon-reload: true + state: restarted + become: true + when: beegfs_enable.meta | bool + +- name: Restart BeeGFS storage service + systemd: + name: "beegfs-storage@{{ item.port }}" + daemon-reload: true + state: restarted + become: true + with_items: "{{ beegfs_oss }}" + when: beegfs_enable.oss | bool + +- name: Restart BeeGFS admon service + systemd: + name: beegfs-admon + daemon-reload: true + state: restarted + become: true + when: beegfs_enable.admon | bool + +- name: Restart BeeGFS client service + systemd: + name: "{{ item }}" + daemon-reload: true + state: restarted + become: true + with_items: + - beegfs-helperd + - beegfs-client + when: beegfs_enable.client | bool + retries: 3 + delay: 3 + register: result + until: result is success + +- name: Restart BeeGFS tuning service + systemd: + name: beegfs-oss-tuning + daemon-reload: true + state: restarted + become: true +... diff --git a/roles/beegfs_role/meta/main.yml b/roles/beegfs_role/meta/main.yml new file mode 100644 index 0000000000..897c3725a9 --- /dev/null +++ b/roles/beegfs_role/meta/main.yml @@ -0,0 +1,44 @@ +# Copyright 2020 Dell Inc. or its subsidiaries. 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. +--- +galaxy_info: + role_name: beegfs + author: Dell Technologies + description: > + This role provisions an exisiting cluster to support Beegfs + management, metadata, object storage server and client roles. + company: Dell Technologies + license: Apache2 + min_ansible_version: 2.5.2 + platforms: + - name: EL + versions: + - 7 + - 8 + - name: Rocky + versions: + - 8 + - name: Debian + versions: + - "stretch" + - name: Ubuntu + versions: + - "xenial" + - "bionic" + galaxy_tags: + - cloud + - storage + - beegfs + +dependencies: [] diff --git a/roles/beegfs_role/tasks/admon.yml b/roles/beegfs_role/tasks/admon.yml new file mode 100644 index 0000000000..25afe5cef0 --- /dev/null +++ b/roles/beegfs_role/tasks/admon.yml @@ -0,0 +1,15 @@ +# Copyright 2020 Dell Inc. or its subsidiaries. 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. +--- +... diff --git a/roles/beegfs_role/tasks/client.yml b/roles/beegfs_role/tasks/client.yml new file mode 100644 index 0000000000..ea4f090a25 --- /dev/null +++ b/roles/beegfs_role/tasks/client.yml @@ -0,0 +1,119 @@ +# Copyright 2020 Dell Inc. or its subsidiaries. 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. +--- +- name: Install packages for BeeGFS client + package: + name: "{{ item }}" + state: "{{ beegfs_package_action }}" + with_items: + - beegfs-client + - beegfs-helperd + - beegfs-utils + become: true + notify: Restart BeeGFS client service + +- name: Define client kernel build for IB + lineinfile: + path: "/etc/beegfs/beegfs-client-autobuild.conf" + regexp: "^buildArgs=" + line: "{{ item.line }}" + when: item.condition + with_items: + - { line: "buildArgs=-j8 BEEGFS_OPENTK_IBVERBS=1", condition: "{{ beegfs_rdma | bool }}" } + - { line: "buildArgs=-j8", condition: "{{ not beegfs_rdma | bool }}" } + notify: Restart BeeGFS client service + become: true + +- name: Ensure kernel development headers are present + package: + name: "{{ beegfs_distro_vars[ansible_os_family]['kernel_dev_pkg'] }}-{{ ansible_kernel }}" + state: present + notify: Restart BeeGFS client service + become: true + +- name: Ensure gcc is installed + package: + name: "gcc" + state: present + become: true + notify: Restart BeeGFS client service + +- name: Rebuild the BeeGFS client kernel module + command: /etc/init.d/beegfs-client rebuild + args: + creates: "{{ beegfs_kernel_module }}" + become: true + notify: Restart BeeGFS client service + +- name: Ensure the BeeGFS mount point exists + file: + path: "{{ client_path }}" + state: directory + become: true + notify: Restart BeeGFS client service + +- name: Copy over beegfs-mounts config file + template: + src: beegfs-mounts.conf.j2 + dest: /etc/beegfs/beegfs-mounts.conf + mode: 0644 + become: true + notify: Restart BeeGFS client service + +- name: Make of copy of BeeGFS client config file if it doesn't exist + copy: + remote_src: true + src: /etc/beegfs/beegfs-client.conf + dest: "/etc/beegfs/beegfs-client-{{ client_mgmt_host }}.conf" + force: false + become: true + notify: Restart BeeGFS client service + +- name: Configure beegfs-client config file to point to the specified management host + lineinfile: + dest: "/etc/beegfs/beegfs-client-{{ client_mgmt_host }}.conf" + regexp: "^sysMgmtdHost" + line: "sysMgmtdHost = {{ client_mgmt_host }}" + become: true + +- name: Configure beegfs-client config file to use the specified port + lineinfile: + dest: "/etc/beegfs/beegfs-client-{{ client_mgmt_host }}.conf" + regexp: "^connClientPortUDP" + line: "connClientPortUDP = {{ client_port }}" + become: true + +- name: Configure beegfs-client config file to ensure the specifed connection interface is used + lineinfile: + dest: "/etc/beegfs/beegfs-client-{{ client_mgmt_host }}.conf" + regexp: "^connInterfacesFile" + line: "connInterfacesFile = /etc/beegfs/connInterfacesFile" + become: true + +- name: Copy default beegfs-client config file to enable beegfs_ctl in the management host + copy: + remote_src: true + dest: /etc/beegfs/beegfs-client.conf + src: "/etc/beegfs/beegfs-client-{{ client_mgmt_host }}.conf" + force: true + when: client_mgmt_host == inventory_hostname + become: true + +- name: Copy beegfs-client.service.d/ to /etc/systemd/system/ + copy: + src: beegfs-client.service.d/ + dest: /etc/systemd/system/beegfs-client.service.d/ + notify: Restart BeeGFS client service + become: true +... diff --git a/roles/beegfs_role/tasks/create.yml b/roles/beegfs_role/tasks/create.yml new file mode 100644 index 0000000000..c7d6132ac9 --- /dev/null +++ b/roles/beegfs_role/tasks/create.yml @@ -0,0 +1,210 @@ +# Copyright 2020 Dell Inc. or its subsidiaries. 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. +--- +- name: Add BeeGFS repos is beegfs_add_repos is true + block: + + - name: Ensure the BeeGFS package repo is defined + get_url: + url: "{{ beegfs_repo_url }}" + dest: "{{ beegfs_repo_file }}" + become: true + + - name: Load package repo key + block: + - name: add apt key for debian family machines + apt_key: + state: present + url: "{{ beegfs_repo_key }}" + when: ansible_os_family == "Debian" + - name: add rpm key for redhat family machines + rpm_key: + state: present + key: "{{ beegfs_repo_key }}" + when: ansible_os_family == "RedHat" + become: true + + - name: Refresh apt repos and install https repo support for Debian + apt: + name: + - base-files + - apt-transport-https + state: present + update_cache: true + become: true + when: ansible_os_family == "Debian" + + when: beegfs_add_repos | bool + +# Task flow inspired by MichaelRigart.interfaces role - thanks markgoddard +# Some systems do not support /etc/modules-load.d, in which case we fall back +# to /etc/modules. +- name: Check whether /etc/modules-load.d exists + stat: + path: /etc/modules-load.d + register: modules_load_stat + +- name: Ensure any required kernel modules are loaded + modprobe: + name: "{{ item }}" + state: present + become: true + with_items: "{{ beegfs_kmod_preload }}" + +- name: Make sure required modules are loaded at boot via /etc/modules-load.d + lineinfile: + dest: /etc/modules-load.d/beegfs.conf + line: "{{ item }}" + create: true + become: true + when: modules_load_stat.stat.exists + with_items: "{{ beegfs_kmod_preload }}" + +- name: Make sure required modules are loaded at boot via /etc/modules + lineinfile: + dest: /etc/modules + line: "{{ item }}" + become: true + when: not modules_load_stat.stat.exists + with_items: "{{ beegfs_kmod_preload }}" + +- name: Stop and delete server and client service + block: + - name: Probe installed services + service_facts: + - name: Stop BeeGFS server and client services + service: + name: "{{ item.name }}" + state: stopped + when: + - item.name in ansible_facts.services + - item.enable | bool + with_items: + - { name: "beegfs-client.service", enable: "{{ beegfs_enable.client }}" } + - { name: "beegfs-helperd.service", enable: "{{ beegfs_enable.client }}" } + - { name: "beegfs-mgmtd.service", enable: "{{ beegfs_enable.mgmt }}" } + - { name: "beegfs-meta.service", enable: "{{ beegfs_enable.meta }}" } + - { name: "beegfs-admon.service", enable: "{{ beegfs_enable.admon }}" } + - name: Stop BeeGFS storage services + vars: + service_name: "beegfs-storage@{{ item.port }}.service" + service: + name: "{{ service_name }}" + state: stopped + with_items: "{{ beegfs_oss }}" + when: service_name in ansible_facts.services + - name: Remove other beegfs folders + file: + path: "{{ item.name }}" + state: absent + when: item.enable | bool + with_items: + - { name: "{{ beegfs_meta_path }}", enable: "{{ beegfs_enable.meta }}" } + - { name: "{{ beegfs_mgmt_path }}", enable: "{{ beegfs_enable.mgmt }}" } + - name: Unload kernel module + modprobe: + name: beegfs + state: absent + - name: Delete kernel module + file: + path: "{{ beegfs_kernel_module }}" + state: absent + when: (beegfs_force_format | bool) or + (beegfs_package_action | lower == "latest") + become: true + +- include: rdma.yml + when: beegfs_rdma | bool + +- include: mgmt.yml + when: beegfs_enable.mgmt | default(false) | bool + +- include: admon.yml + when: beegfs_enable.admon | default(false) | bool + +- include: meta.yml + when: beegfs_enable.meta | default(false) | bool + +- include: oss.yml + vars: + oss_dev: "{{ oss_item.dev | default('') }}" + oss_dev_is_defined: "{{ oss_item.dev is defined }}" + oss_path: "{{ oss_item.path | default(beegfs_oss_path_prefix + oss_dev) }}" + oss_port: "{{ oss_item.port }}" + oss_replace: "{{ '-r' if (oss_item == beegfs_oss|first or beegfs_oss_multi_port) else '' }}" + with_items: "{{ beegfs_oss }}" + loop_control: + loop_var: oss_item + failed_when: > + (oss_item.dev is not defined and oss_item.path is not defined) + when: beegfs_enable.oss | default(false) | bool + +- include: tuning.yml + when: beegfs_enable.tuning | default(false) | bool + +- meta: flush_handlers + +- include: client.yml + vars: + client_mgmt_host: "{{ client_item.mgmt_host | default(beegfs_mgmt_host) }}" + client_path: "{{ client_item.path }}" + client_port: "{{ client_item.port }}" + with_items: "{{ beegfs_client }}" + loop_control: + loop_var: client_item + when: beegfs_enable.client | default(false) | bool + +- name: Create connInterfacesFile + template: + src: connInterfacesFile.j2 + dest: /etc/beegfs/connInterfacesFile + become: true + +- name: Start and enable BeeGFS server services + service: + name: "{{ item.name }}" + enabled: true + state: "{{ item.state | default(omit) }}" + become: true + when: item.enable | bool + with_items: + - { name: beegfs-mgmtd, enable: "{{ beegfs_enable.mgmt }}", state: started } + - { name: beegfs-meta, enable: "{{ beegfs_enable.meta }}", state: started } + - { name: beegfs-admon, enable: "{{ beegfs_enable.admon }}", state: started } + - { name: beegfs-oss-tuning, enable: "{{ beegfs_enable.tuning }}" } + +- name: Start and enable BeeGFS storage services + service: + name: "beegfs-storage@{{ item.port }}" + enabled: true + state: started + become: true + when: beegfs_enable.oss | bool + with_items: "{{ beegfs_oss }}" + +- name: Start and enable BeeGFS client services + service: + name: "{{ item.name }}" + enabled: true + state: started + become: true + when: item.enable | bool + with_items: + - { name: beegfs-helperd, enable: "{{ beegfs_enable.client }}" } + - { name: beegfs-client, enable: "{{ beegfs_enable.client }}" } + retries: 3 + delay: 3 + register: result + until: result is success +... diff --git a/roles/beegfs_role/tasks/destroy.yml b/roles/beegfs_role/tasks/destroy.yml new file mode 100644 index 0000000000..67afdb2d22 --- /dev/null +++ b/roles/beegfs_role/tasks/destroy.yml @@ -0,0 +1,109 @@ +# Copyright 2020 Dell Inc. or its subsidiaries. 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. +--- +- name: Unmount client mount path + mount: + path: "{{ item.path }}" + state: unmounted + become: true + when: beegfs_enable.client | bool + with_items: "{{ beegfs_client }}" + +- name: Stop and disable BeeGFS client services + service: + name: "{{ item.name }}" + enabled: false + state: stopped + become: true + when: item.enable | bool + with_items: + - { name: beegfs-helperd, enable: "{{ beegfs_enable.client }}" } + - { name: beegfs-client, enable: "{{ beegfs_enable.client }}" } + +- name: (Backward compatible) Stop and disable BeeGFS storage service + service: + name: "beegfs-storage@{{ item.dev }}" + enabled: false + state: stopped + become: true + when: + - beegfs_enable.oss | bool + - item.dev is defined + with_items: "{{ beegfs_oss }}" + +- name: Stop and disable BeeGFS storage services + service: + name: "beegfs-storage@{{ item.port }}" + enabled: false + state: stopped + become: true + when: beegfs_enable.oss | bool + with_items: "{{ beegfs_oss }}" + +- name: Stop and disable BeeGFS server services + service: + name: "{{ item.name }}" + enabled: false + state: stopped + become: true + when: item.enable | bool + with_items: + - { name: beegfs-mgmtd, enable: "{{ beegfs_enable.mgmt }}" } + - { name: beegfs-meta, enable: "{{ beegfs_enable.meta }}" } + - { name: beegfs-admon, enable: "{{ beegfs_enable.admon }}" } + - { name: beegfs-oss-tuning, enable: "{{ beegfs_enable.tuning }}" } + +- name: Clear storeStorageDirectory + lineinfile: + path: "/etc/beegfs/{{ item.port }}.d/beegfs-storage.conf" + regexp: "^storeStorageDirectory" + line: "storeStorageDirectory =" + with_items: "{{ beegfs_oss }}" + become: true + when: beegfs_enable.oss | bool + +- name: Unmount BeeGFS oss paths if mounted + vars: + oss_path: "{{ item.path | default(beegfs_oss_path_prefix + item.dev) }}" + mount: + path: "{{ oss_path }}" + state: unmounted + become: true + with_items: "{{ beegfs_oss }}" + when: + - beegfs_enable.oss | bool + - item.dev is defined + +- name: Remove all beegfs oss folders + vars: + oss_path: "{{ beegfs_oss_path_prefix + item.dev }}" + file: + path: "{{ oss_path }}" + state: absent + become: true + with_items: "{{ beegfs_oss }}" + when: + - beegfs_enable.oss | bool + - item.dev is defined + +- name: Remove other beegfs folders + file: + path: "{{ item.name }}" + state: absent + become: true + when: item.enable | bool + with_items: + - { name: "{{ beegfs_meta_path }}", enable: "{{ beegfs_enable.meta }}" } + - { name: "{{ beegfs_mgmt_path }}", enable: "{{ beegfs_enable.mgmt }}" } +... diff --git a/roles/beegfs_role/tasks/main.yml b/roles/beegfs_role/tasks/main.yml new file mode 100644 index 0000000000..ac808217f9 --- /dev/null +++ b/roles/beegfs_role/tasks/main.yml @@ -0,0 +1,22 @@ +# Copyright 2020 Dell Inc. or its subsidiaries. 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. +--- +- name: If beegfs_state is present + include: create.yml + when: beegfs_state | lower == "present" + +- name: If beegfs_state is absent + include: destroy.yml + when: beegfs_state | lower == "absent" +... diff --git a/roles/beegfs_role/tasks/meta.yml b/roles/beegfs_role/tasks/meta.yml new file mode 100644 index 0000000000..0b3f4cf461 --- /dev/null +++ b/roles/beegfs_role/tasks/meta.yml @@ -0,0 +1,72 @@ +# Copyright 2020 Dell Inc. or its subsidiaries. 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. +--- +- name: Install packages for BeeGFS metadata server + package: + name: beegfs-meta + state: "{{ beegfs_package_action }}" + become: true + notify: Restart BeeGFS meta service + +- name: Create directory for BeeGFS metadata + file: + path: "{{ beegfs_meta_path }}" + state: directory + become: true + notify: Restart BeeGFS meta service + +- name: Prepare metadata block storage + block: + - name: Ensure storage device is not currently mounted + mount: + path: "{{ beegfs_meta_path }}" + state: unmounted + notify: Restart BeeGFS meta service + - name: Format filesystem + vars: + meta_fstype: "{{ beegfs_meta_fstype | default(beegfs_fstype) }}" + filesystem: + dev: "{{ beegfs_meta_dev }}" + fstype: "{{ meta_fstype }}" + force: "{{ beegfs_force_format }}" + notify: Restart BeeGFS meta service + - name: Mount filesystem + vars: + meta_fstype: "{{ beegfs_meta_fstype | default(beegfs_fstype) }}" + mount: + src: "{{ beegfs_meta_dev }}" + path: "{{ beegfs_meta_path }}" + fstype: "{{ meta_fstype }}" + state: mounted + notify: Restart BeeGFS meta service + become: true + when: + - beegfs_meta_dev is defined + - beegfs_meta_dev != None + +- name: Run metadata service setup script + command: "/opt/beegfs/sbin/beegfs-setup-meta -p {{ beegfs_meta_path }} -m {{ beegfs_mgmt_host }} -f" + args: + creates: "{{ beegfs_meta_path }}/originalNodeID" + become: true + notify: Restart BeeGFS meta service + +- name: Specify connInterfacesFile + lineinfile: + path: /etc/beegfs/beegfs-meta.conf + regexp: "^connInterfacesFile" + line: "connInterfacesFile = /etc/beegfs/connInterfacesFile" + become: true + notify: Restart BeeGFS meta service +... diff --git a/roles/beegfs_role/tasks/mgmt.yml b/roles/beegfs_role/tasks/mgmt.yml new file mode 100644 index 0000000000..f31d675c28 --- /dev/null +++ b/roles/beegfs_role/tasks/mgmt.yml @@ -0,0 +1,43 @@ +# Copyright 2020 Dell Inc. or its subsidiaries. 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. +--- +- name: Install packages for BeeGFS management server + package: + name: beegfs-mgmtd + state: "{{ beegfs_package_action }}" + become: true + notify: Restart BeeGFS mgmt service + +- name: Create directory for BeeGFS management service data + file: + path: "{{ beegfs_mgmt_path }}" + state: directory + become: true + notify: Restart BeeGFS mgmt service + +- name: Run management service setup script + command: "/opt/beegfs/sbin/beegfs-setup-mgmtd -p {{ beegfs_mgmt_path }} -f" + args: + creates: "{{ beegfs_mgmt_path }}/originalNodeID" + become: true + notify: Restart BeeGFS mgmt service + +- name: Specify connInterfacesFile + lineinfile: + path: /etc/beegfs/beegfs-mgmtd.conf + regexp: "^connInterfacesFile" + line: "connInterfacesFile = /etc/beegfs/connInterfacesFile" + become: true + notify: Restart BeeGFS mgmt service +... diff --git a/roles/beegfs_role/tasks/oss.yml b/roles/beegfs_role/tasks/oss.yml new file mode 100644 index 0000000000..8b294c1a76 --- /dev/null +++ b/roles/beegfs_role/tasks/oss.yml @@ -0,0 +1,118 @@ +# Copyright 2020 Dell Inc. or its subsidiaries. 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. +--- +- name: Install packages for BeeGFS object storage server + package: + name: beegfs-storage + state: "{{ beegfs_package_action }}" + become: true + notify: Restart BeeGFS storage service + +- name: Create a list of devices that are mounted + set_fact: + mounted_devs: "{{ ansible_mounts | map(attribute='device') | list }}" + +- name: Create storage config dirs + file: + path: "/etc/beegfs/{{ oss_port }}.d/" + state: directory + become: true + notify: Restart BeeGFS storage service + +- name: Add template beegfs-storage conf + copy: + src: "/etc/beegfs/beegfs-storage.conf" + dest: "/etc/beegfs/{{ oss_port }}.d/beegfs-storage.conf" + remote_src: true + force: false + become: true + notify: Restart BeeGFS storage service + +- name: Prepare storage devices + block: + - name: Stat the OSS device + stat: + path: "{{ oss_dev }}" + register: oss_dev_stat + - name: Fail if OSS device does not exist + fail: + msg: OSS device {{ oss_dev }} does not exist + when: not oss_dev_stat.exists + - name: Unmount storage device if beegfs_force_format is true + mount: + path: "{{ oss_path }}" + state: unmounted + when: beegfs_force_format | bool + notify: Restart BeeGFS storage service + - name: Attempt to format if the device is not mounted or if beegfs_force_format is true + vars: + oss_dev_real: "{{ oss_dev_stat.lnk_source if oss_dev_stat.islnk else oss_dev_stat.path }}" + filesystem: + dev: "{{ oss_dev }}" + fstype: "{{ beegfs_fstype }}" + force: "{{ beegfs_force_format | bool }}" + opts: "{{ beegfs_filesystem_opts }}" + when: (oss_dev_real not in mounted_devs) or (beegfs_force_format | bool) + notify: Restart BeeGFS storage service + - name: Ensure the mount point exists + file: + path: "{{ oss_path }}" + state: directory + - name: Mount filesystem, fail if the fstype doesn't match + mount: + src: "{{ oss_dev }}" + path: "{{ oss_path }}" + fstype: "{{ beegfs_fstype }}" + state: mounted + opts: "{{ beegfs_mount_opts }}" + notify: Restart BeeGFS storage service + become: true + when: oss_dev_is_defined + +- name: Run storage service setup script + command: | + /opt/beegfs/sbin/beegfs-setup-storage -f \ + -p {{ oss_path }} {{ oss_replace }} \ + -m {{ beegfs_mgmt_host }} \ + -c /etc/beegfs/{{ oss_port }}.d/beegfs-storage.conf \ + -S {{ inventory_hostname }}-{{ oss_port }} \ + args: + creates: "{{ oss_path }}/originalNodeID" + become: true + notify: Restart BeeGFS storage service + +- name: set TCP storage port + lineinfile: + path: "/etc/beegfs/{{ oss_port }}.d/beegfs-storage.conf" + regexp: '^connStoragePortTCP' + line: "connStoragePortTCP = {{ oss_port }}" + become: true + notify: Restart BeeGFS storage service + +- name: set UDP storage port + lineinfile: + path: "/etc/beegfs/{{ oss_port }}.d/beegfs-storage.conf" + regexp: '^connStoragePortUDP' + line: "connStoragePortUDP = {{ oss_port }}" + become: true + notify: Restart BeeGFS storage service + +- name: Specify connInterfacesFile + lineinfile: + path: "/etc/beegfs/{{ oss_port }}.d/beegfs-storage.conf" + regexp: "^connInterfacesFile" + line: "connInterfacesFile = /etc/beegfs/connInterfacesFile" + become: true + notify: Restart BeeGFS storage service +... diff --git a/roles/beegfs_role/tasks/rdma.yml b/roles/beegfs_role/tasks/rdma.yml new file mode 100644 index 0000000000..380732fcf2 --- /dev/null +++ b/roles/beegfs_role/tasks/rdma.yml @@ -0,0 +1,30 @@ +# Copyright 2020 Dell Inc. or its subsidiaries. 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. +--- +- name: Ensure RDMA packages are installed + package: + name: "{{ beegfs_distro_vars[ansible_os_family]['rdma_dev_pkgs'] }}" + state: "{{ beegfs_package_action }}" + become: true + +- name: Ensure RDMA kernel modules are loaded + modprobe: + name: "{{ item }}" + state: present + become: true + with_items: + - "ib_umad" + - "ib_uverbs" + - "rdma_ucm" +... diff --git a/roles/beegfs_role/tasks/tuning.yml b/roles/beegfs_role/tasks/tuning.yml new file mode 100644 index 0000000000..8e20a99d06 --- /dev/null +++ b/roles/beegfs_role/tasks/tuning.yml @@ -0,0 +1,45 @@ +# Copyright 2020 Dell Inc. or its subsidiaries. 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. +--- +# BeeGFS tuning parameters +# from https://www.beegfs.io/wiki/StorageServerTuning +- name: BeeGFS tuning parameters + sysctl: + name: "{{ item.key }}" + value: "{{ item.value }}" + state: present + reload: true + sysctl_set: true + with_items: + - {key: 'vm.dirty_background_ratio', value: '5'} + - {key: 'vm.dirty_ratio', value: '20'} + - {key: 'vm.vfs_cache_pressure', value: '50'} + - {key: 'vm.min_free_kbytes', value: '262144'} + - {key: 'vm.zone_reclaim_mode', value: '1'} + become: true + +- name: Tune beegfs_oss_tunable devices + block: + - name: Copy beegfs-oss-tuning.sh to /opt/beegfs/ + template: + src: beegfs-oss-tuning.sh.j2 + dest: /opt/beegfs/beegfs-oss-tuning.sh + mode: a+x + notify: Restart BeeGFS tuning service + - name: Copy beegfs-oss-tuning.service to /etc/systemd/system/ + copy: + src: beegfs-oss-tuning.service + dest: /etc/systemd/system/ + notify: Restart BeeGFS tuning service + become: true diff --git a/roles/beegfs_role/templates/beegfs-mounts.conf.j2 b/roles/beegfs_role/templates/beegfs-mounts.conf.j2 new file mode 100644 index 0000000000..a966b81b9c --- /dev/null +++ b/roles/beegfs_role/templates/beegfs-mounts.conf.j2 @@ -0,0 +1,3 @@ +{% for item in beegfs_client %} +{{ item.path }} /etc/beegfs/beegfs-client-{{ item.mgmt_host | default(beegfs_mgmt_host) }}.conf +{% endfor %} diff --git a/roles/beegfs_role/templates/beegfs-oss-tuning.sh.j2 b/roles/beegfs_role/templates/beegfs-oss-tuning.sh.j2 new file mode 100644 index 0000000000..e884db8e8e --- /dev/null +++ b/roles/beegfs_role/templates/beegfs-oss-tuning.sh.j2 @@ -0,0 +1,18 @@ +# BeeGFS tuning parameters from +# https://www.beegfs.io/wiki/StorageServerTuning + +set -x + +echo always > /sys/kernel/mm/transparent_hugepage/enabled +echo always > /sys/kernel/mm/transparent_hugepage/defrag +{% if beegfs_oss_tunable | length > 0 %} +for dev in {{ beegfs_oss_tunable | join(' ') }} +do + if [ -d /sys/block/${dev} ]; then + echo mq-deadline > /sys/block/${dev}/queue/scheduler + echo 2048 > /sys/block/${dev}/queue/nr_requests + echo 4096 > /sys/block/${dev}/queue/read_ahead_kb + echo 256 > /sys/block/${dev}/queue/max_sectors_kb + fi +done +{% endif %} diff --git a/roles/beegfs_role/templates/connInterfacesFile.j2 b/roles/beegfs_role/templates/connInterfacesFile.j2 new file mode 100644 index 0000000000..d8425602ab --- /dev/null +++ b/roles/beegfs_role/templates/connInterfacesFile.j2 @@ -0,0 +1,3 @@ +{% for row in beegfs_interfaces %} +{{ row }} +{% endfor %}