Ceph has the ability to export it's filesystem via NFS using Ganesha.
Add a ceph-nfs role that will start Ganesha and export the Ceph
filesystems.
Note that, although support is going in to export RGW via NFS, this is
not working yet.
Signed-off-by: Daniel Gryniewicz <dang@redhat.com>
NOSDS = settings['osd_vms']
NMDSS = settings['mds_vms']
NRGWS = settings['rgw_vms']
+NNFSS = settings['nfs_vms']
RESTAPI = settings['restapi']
CLIENTS = settings['client_vms']
SUBNET = settings['subnet']
'osds' => (0..NOSDS - 1).map { |j| "#{OSPREFIX}osd#{j}" },
'mdss' => (0..NMDSS - 1).map { |j| "#{OSPREFIX}mds#{j}" },
'rgws' => (0..NRGWS - 1).map { |j| "#{OSPREFIX}rgw#{j}" },
+ 'nfss' => (0..NNFSS - 1).map { |j| "#{OSPREFIX}nfs#{j}" },
'clients' => (0..CLIENTS - 1).map { |j| "#{OSPREFIX}client#{j}" }
}
osd_containerized_deployment: 'true',
mds_containerized_deployment: 'true',
rgw_containerized_deployment: 'true',
+ nfs_containerized_deployment: 'true',
restapi_containerized_deployment: 'true',
ceph_mon_docker_interface: ETH,
ceph_mon_docker_subnet: "#{SUBNET}.0/24",
end
end
+ (0..NNFSS - 1).each do |i|
+ config.vm.define "nfs#{i}" do |nfs|
+ nfs.vm.hostname = "ceph-nfs#{i}"
+ if !OSVM
+ nfs.vm.network :private_network, ip: "#{SUBNET}.6#{i}"
+ end
+
+ # Virtualbox
+ nfs.vm.provider :virtualbox do |vb|
+ vb.customize ['modifyvm', :id, '--memory', "#{MEMORY}"]
+ end
+
+ # VMware
+ nfs.vm.provider :vmware_fusion do |v|
+ v.vmx['memsize'] = "#{MEMORY}"
+ end
+
+ # Libvirt
+ nfs.vm.provider :libvirt do |lv|
+ lv.memory = MEMORY
+ end
+
+ # Parallels
+ nfs.vm.provider "parallels" do |prl|
+ prl.name = "ceph-nfs#{i}"
+ prl.memory = "#{MEMORY}"
+ end
+ end
+ end
+
(0..NMDSS - 1).each do |i|
config.vm.define "#{OSPREFIX}mds#{i}" do |mds|
mds.vm.hostname = "#{OSPREFIX}ceph-mds#{i}"
#osd_group_name: osds
#rgw_group_name: rgws
#mds_group_name: mdss
+#nfs_group_name: nfss
#restapi_group_name: restapis
#rbdmirror_group_name: rbdmirrors
#client_group_name: clients
--- /dev/null
+---
+# Variables here are applicable to all host groups NOT roles
+
+# This sample file generated by generate_group_vars_sample.sh
+
+# Dummy variable to avoid error because ansible does not recognize the
+# file as a good configuration file when no variable in it.
+dummy:
+
+# You can override vars by using host or group vars
+
+###########
+# GENERAL #
+###########
+
+#fetch_directory: fetch/
+
+## Ceph options
+#
+#cephx: true
+
+#######################
+# Access type options #
+#######################
+# Enable NFS File access
+#fsal_ceph: true
+
+# Enable NFS Object access
+#fsal_rgw: false
+
+######################
+# NFS Ganesha Config #
+######################
+#ceph_nfs_export_id: 20134
+#ceph_nfs_pseudo_path: "/ceph"
+#ceph_nfs_protocols: "3,4"
+#ceph_nfs_access_type: "RW"
+
+
+###################
+# CONFIG OVERRIDE #
+###################
+
+# Ganesha configuration file override.
+# This allows you to specify more configuration options
+# using an INI style format.
+# The following sections are supported: [global], [mon], [osd], [mds], [rgw]
+#
+# Example:
+# ceph_conf_overrides:
+# global:
+# foo: 1234
+# bar: 5678
+#
+#ganesha_conf_overrides: {}
+
+##########
+# DOCKER #
+##########
+
+#nfs_containerized_deployment: false
+#nfs_containerized_deployment_with_kv: false
+#kv_type: etcd
+#kv_endpoint: 127.0.0.1
+#ceph_nfs_docker_username: ceph
+#ceph_nfs_docker_imagename: ganesha
+#ceph_nfs_docker_extra_env: "GANESHA_EPOCH={{ ganesha_epoch }}" # comma separated variables
+#ceph_docker_on_openstack: false
roles:
- ceph-rgw
+- hosts: nfss
+ become: True
+ roles:
+ - ceph-nfs
+
- hosts: restapis
become: True
roles:
- osds
- mdss
- rgws
+ - nfss
become: yes
mon_group_name: mons
rgw_group_name: rgws
mds_group_name: mdss
+ nfs_group_name: nfss
rbdmirror_group_name: rbdmirrors
# When set to true both groups of packages are purged.
systemd_unit_files.stdout != "0" and
rgw_group_name in group_names
+ - name: stop ceph nfss with systemd
+ service:
+ name: nfs-ganesha
+ state: stopped
+ when:
+ ansible_os_family == 'RedHat' and
+ systemd_unit_files.stdout != "0" and
+ nfs_group_name in group_names
+
- name: stop ceph rbd mirror with systemd
service:
name: ceph-rbd-mirror@admin.service
ansible_os_family == 'RedHat' and
rgw_group_name in group_names
+ - name: stop ceph nfss
+ shell: "service nfs-ganesha status ; if [ $? == 0 ] ; then service nfs-ganesha stop ; else echo ; fi"
+ when:
+ ansible_os_family == 'RedHat' and
+ nfs_group_name in group_names
+
# Ubuntu 14.04
- name: stop ceph osds on ubuntu
shell: |
ansible_distribution == 'Ubuntu' and
rgw_group_name in group_names
+ - name: stop ceph nfss on ubuntu
+ command: initctl stop nfs-ganesha
+ failed_when: false
+ when:
+ ansible_distribution == 'Ubuntu' and
+ nfs_group_name in group_names
+
- name: stop ceph rbd mirror on ubuntu
command: initctl stop ceph-rbd-mirorr cluster={{ cluster }} id=admin
failed_when: false
osd_group_name: osds
rgw_group_name: rgws
mds_group_name: mdss
+nfs_group_name: nfss
restapi_group_name: restapis
rbdmirror_group_name: rbdmirrors
client_group_name: clients
when:
- ansible_os_family == 'RedHat'
- rgw_group_name in group_names
+
+- name: restart ceph nfss
+ service:
+ name: nfs-ganesha
+ state: restarted
+ when:
+ - nfs_group_name in group_names
- rgw_group_name in group_names
- rgwportstate.rc == 0
- nmapexist.rc == 0
+
+- name: check if NFS ports are not filtered
+ local_action: shell set -o pipefail && nmap -p 111,2049 {{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }} | grep -sqo -e filtered -e '0 hosts up'
+ changed_when: false
+ failed_when: false
+ register: nfsportstate
+ when:
+ - nfs_group_name in group_names
+ - nmapexist.rc == 0
+
+- name: fail if NFS ports are filtered
+ fail:
+ msg: "Please allow ports 111 and 2049 on your firewall"
+ when:
+ - nfs_group_name in group_names
+ - nfsportstate.rc == 0
+ - nmapexist.rc == 0
state: "{{ (upgrade_ceph_packages|bool) | ternary('latest','present') }}"
default_release: "{{ ceph_stable_release_uca | default(ansible_distribution_release) }}{{ '-backports' if ceph_origin == 'distro' and ceph_use_distro_backports else ''}}"
when: mds_group_name in group_names
+
+- name: install NFS gateway
+ apt:
+ pkg: nfs-ganesha
+ state: "{{ (upgrade_ceph_packages|bool) | ternary('latest','present') }}"
+ update_cache: yes
+ when: nfs_group_name in group_names
when:
- rgw_group_name in group_names
- ansible_pkg_mgr == "dnf"
+
+- name: install NFS gateway
+ yum:
+ name: nfs-ganesha-ceph
+ state: "{{ (upgrade_ceph_packages|bool) | ternary('latest','present') }}"
+ when:
+ - nfs_group_name in group_names
+ - ansible_pkg_mgr == "yum"
+
+- name: install NFS gateway
+ dnf:
+ name: nfs-ganesha-ceph
+ state: "{{ (upgrade_ceph_packages|bool) | ternary('latest','present') }}"
+ when:
+ - nfs_group_name in group_names
+ - ansible_pkg_mgr == "dnf"
pkg: ceph-common
state: "{{ (upgrade_ceph_packages|bool) | ternary('latest','present') }}"
when: client_group_name in group_names
+
+- name: install red hat storage NFS gateway
+ apt:
+ name: nfs-ganesha
+ state: "{{ (upgrade_ceph_packages|bool) | ternary('latest','present') }}"
+ when: nfs_group_name in group_names
state: "{{ (upgrade_ceph_packages|bool) | ternary('latest','present') }}"
when:
- rgw_group_name in group_names
+
+- name: install NFS gateway
+ yum:
+ name: nfs-ganesha-ceph
+ state: "{{ (upgrade_ceph_packages|bool) | ternary('latest','present') }}"
+ when:
+ - nfs_group_name in group_names
- restart ceph rgws on ubuntu
- restart ceph rgws on red hat
- restart ceph rgws with systemd
+ - restart ceph nfss
- name: create rbd client directory
file:
--- /dev/null
+#jinja2: trim_blocks: "true", lstrip_blocks: "true"
+# {{ ansible_managed }}
+
+EXPORT
+{
+ Export_ID={{ ceph_nfs_export_id }};
+
+ Path = "/";
+
+ Pseudo = {{ ceph_nfs_pseudo_path }};
+
+ Access_Type = {{ ceph_nfs_access_type }};
+
+ NFS_Protocols = {{ ceph_nfs_protocols }};
+
+ Transport_Protocols = TCP;
+
+ Sectype = sys,krb5,krb5i,krb5p;
+
+ FSAL {
+ Name = CEPH;
+ }
+}
--- /dev/null
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [2016] [Red Hat, Inc.]
+
+ 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.
--- /dev/null
+# Ansible role: Ceph NFS Gateway
+
+This role bootstraps Ceph NFS Gateway(s).
+It can bootstrap dockerized Ceph NFS Gateway(s). NFS support is provided by
+the NFS Ganesha project.
+
+It can provide one or both of NFS File access (requires at least one ceph-mds
+role) or NFS Object access (requires at least one ceph-rgw role).
+
+# Requirements
+
+Nothing, it runs out of the box.
+
+# Role variables
+
+Have a look at: `defaults/main.yml`.
+
+## Mandatory variables
+
+None.
+
+# Dependencies
+
+The role `ceph.ceph-common` must be installed.
+
+# Example Playbook
+
+```
+- hosts: servers
+ remote_user: ubuntu
+ roles:
+ - { role: ceph.ceph-nfs }
+```
+
+# Contribution
+
+**THIS REPOSITORY DOES NOT ACCEPT PULL REQUESTS**
+**PULL REQUESTS MUST GO THROUGH [CEPH-ANSIBLE](https://github.com/ceph/ceph-ansible)**
+
+# License
+
+Apache
+
+# Author Information
+
+This role was created by [Daniel Gryniewicz](http://redhat.com/).
--- /dev/null
+---
+# You can override vars by using host or group vars
+
+###########
+# GENERAL #
+###########
+
+fetch_directory: fetch/
+
+## Ceph options
+#
+cephx: true
+
+#######################
+# Access type options #
+#######################
+# Enable NFS File access
+fsal_ceph: true
+
+# Enable NFS Object access
+fsal_rgw: false
+
+######################
+# NFS Ganesha Config #
+######################
+ceph_nfs_export_id: 20134
+ceph_nfs_pseudo_path: "/ceph"
+ceph_nfs_protocols: "3,4"
+ceph_nfs_access_type: "RW"
+
+
+###################
+# CONFIG OVERRIDE #
+###################
+
+# Ganesha configuration file override.
+# This allows you to specify more configuration options
+# using an INI style format.
+# The following sections are supported: [global], [mon], [osd], [mds], [rgw]
+#
+# Example:
+# ceph_conf_overrides:
+# global:
+# foo: 1234
+# bar: 5678
+#
+ganesha_conf_overrides: {}
+
+##########
+# DOCKER #
+##########
+
+nfs_containerized_deployment: false
+nfs_containerized_deployment_with_kv: false
+kv_type: etcd
+kv_endpoint: 127.0.0.1
+ceph_nfs_docker_username: ceph
+ceph_nfs_docker_imagename: ganesha
+#ceph_nfs_docker_extra_env: "GANESHA_EPOCH={{ ganesha_epoch }}" # comma separated variables
+ceph_docker_on_openstack: false
--- /dev/null
+---
+galaxy_info:
+ author: Daniel Gryniewicz
+ description: Installs Ceph NFS Gateway
+ license: Apache
+ min_ansible_version: 1.7
+ platforms:
+ - name: Ubuntu
+ versions:
+ - trusty
+ categories:
+ - system
+dependencies:
+ - { role: ceph.ceph-common, when: not nfs_containerized_deployment }
--- /dev/null
+---
+- name: set config and keys paths
+ set_fact:
+ ceph_config_keys:
+ - /etc/ceph/ceph.client.admin.keyring
+ - /etc/ceph/ceph.conf
+ - /etc/ceph/monmap
+ - /etc/ceph/ceph.mon.keyring
+ - /etc/ganesha/ganesha.conf
+
+- name: stat for ceph config and keys
+ stat:
+ path: "{{ item }}"
+ with_items: ceph_config_keys
+ changed_when: false
+ failed_when: false
+ register: statleftover
+
+- name: fail if we find existing cluster files
+ fail:
+ msg: "looks like no cluster is running but ceph files are present, please remove them"
+ with_together:
+ - ceph_config_keys
+ - statleftover.results
+ when: item.1.stat.exists == true
--- /dev/null
+---
+- name: push ceph files to the ansible server
+ fetch:
+ src: "{{ item.0 }}"
+ dest: "{{ fetch_directory }}/docker_mon_files/{{ item.0 }}"
+ flat: yes
+ with_together:
+ - ceph_config_keys
+ - statconfig.results
+ when: item.1.stat.exists == false
--- /dev/null
+---
+- name: create ganesha conf directory
+ file:
+ path: /etc/ganesha
+ state: directory
+ owner: root
+ group: root
+ mode: 0644
+
+- name: generate ganesha configuration file
+ action: config_template
+ args:
+ src: "{{ playbook_dir }}/roles/ceph-common/templates/ganesha.conf.j2"
+ dest: /etc/ganesha/ganesha.conf
+ owner: "root"
+ group: "root"
+ mode: "0644"
+ config_overrides: "{{ ganesha_conf_overrides }}"
+ config_type: ini
--- /dev/null
+---
+# NOTE (leseb): we can not use docker inspect with 'format filed' because of
+# https://github.com/ansible/ansible/issues/10156
+- name: inspect ceph version
+ shell: docker inspect "{{ ceph_nfs_docker_username }}/{{ ceph_nfs_docker_imagename }}" | awk -F '=' '/CEPH_VERSION/ { gsub ("\",", "", $2); print $2 }' | uniq
+ changed_when: false
+ failed_when: false
+ run_once: true
+ register: ceph_version
+
+- set_fact:
+ after_hammer=True
+ when: ceph_version.stdout not in ['firefly','giant', 'hammer']
+
+- name: create bootstrap directories (for or before hammer)
+ file:
+ path: "{{ item }}"
+ state: directory
+ owner: root
+ group: root
+ mode: "0755"
+ with_items:
+ - /etc/ceph/
+ - /var/lib/ceph/
+ when: not after_hammer
+
+- name: create bootstrap directories (after hammer)
+ file:
+ path: "{{ item }}"
+ state: directory
+ owner: "64045"
+ group: "64045"
+ mode: "0755"
+ with_items:
+ - /etc/ceph/
+ - /var/lib/ceph/
+ when: after_hammer
+
+- name: create ganesha directories
+ file:
+ path: "{{ item }}"
+ state: directory
+ owner: root
+ group: root
+ mode: "0755"
+ with_items:
+ - /etc/ganesha/
+ - /var/lib/nfs/ganesha
+ - /var/run/ganesha
--- /dev/null
+---
+- name: set config and keys paths
+ set_fact:
+ ceph_config_keys:
+ - /etc/ceph/ceph.conf
+ - /etc/ganesha/ganesha.conf
+
+- name: stat for config and keys
+ local_action: stat path={{ fetch_directory }}/docker_mon_files/{{ item }}
+ with_items: ceph_config_keys
+ changed_when: false
+ become: false
+ failed_when: false
+ register: statconfig
+
+- name: try to fetch config and keys
+ copy:
+ src: "{{ fetch_directory }}/docker_mon_files/{{ item.0 }}"
+ dest: "{{ item.0 }}"
+ owner: root
+ group: root
+ mode: 0644
+ changed_when: false
+ with_together:
+ - ceph_config_keys
+ - statconfig.results
+ when: item.1.stat.exists == true
--- /dev/null
+---
+- name: check if a cluster is already running
+ shell: "docker ps | grep -sq '{{ceph_nfs_docker_username}}/{{ceph_nfs_docker_imagename}}'"
+ register: ceph_health
+ changed_when: false
+ failed_when: false
+
+- name: check if it is Atomic host
+ stat: path=/run/ostree-booted
+ register: stat_ostree
+
+- name: set fact for using Atomic host
+ set_fact:
+ is_atomic: '{{ stat_ostree.stat.exists }}'
+
+- include: checks.yml
+ when:
+ ceph_health.rc != 0 and
+ not mon_containerized_deployment_with_kv
+
+- include: pre_requisite.yml
+
+- include: "{{ playbook_dir }}/roles/ceph-common/tasks/docker/fetch_image.yml"
+ vars:
+ ceph_docker_username: '{{ ceph_nfs_docker_username}}'
+ ceph_docker_imagename: '{{ ceph_nfs_docker_imagename}}'
+
+- include: dirs_permissions.yml
+
+# let the first ganesha create configs and keyrings
+- include: create_configs.yml
+ when:
+ inventory_hostname == groups.nfss[0] and
+ mon_containerized_default_ceph_conf_with_kv
+
+- include: fetch_configs.yml
+ when: not mon_containerized_deployment_with_kv
+
+- include: selinux.yml
+ when: ansible_os_family == 'RedHat'
+
+- include: start_docker_nfs.yml
+
+- include: copy_configs.yml
+ when: not mon_containerized_deployment_with_kv
--- /dev/null
+---
+- name: install pip and docker on ubuntu
+ apt:
+ name: "{{ item }}"
+ state: present
+ update_cache: yes
+ with_items:
+ - python-pip
+ - docker
+ - docker.io
+ when: ansible_distribution == 'Ubuntu'
+ tags:
+ with_pkg
+
+- name: install pip and docker on debian
+ apt:
+ name: "{{ item }}"
+ state: present
+ update_cache: yes
+ with_items:
+ - python-pip
+ - docker-engine
+ when: ansible_distribution == 'Debian'
+ tags:
+ with_pkg
+
+- name: install pip and docker on redhat
+ yum:
+ name: "{{ item }}"
+ state: present
+ with_items:
+ - python-pip
+ - docker-engine
+ when:
+ ansible_os_family == 'RedHat' and
+ ansible_pkg_mgr == "yum"
+ tags:
+ with_pkg
+
+- name: install pip and docker on redhat
+ dnf:
+ name: "{{ item }}"
+ state: present
+ with_items:
+ - python-pip
+ - docker-engine
+ when:
+ ansible_os_family == 'RedHat' and
+ ansible_pkg_mgr == "dnf"
+ tags:
+ with_pkg
+
+- name: install epel-release on redhat
+ yum:
+ name: epel-release
+ state: present
+ when: ansible_os_family == 'RedHat'
+ tags:
+ with_pkg
+
+# NOTE (jimcurtis): need at least version 1.9.0 of six or we get:
+# re:NameError: global name 'DEFAULT_DOCKER_API_VERSION' is not defined
+- name: install six
+ pip:
+ name: six
+ version: 1.9.0
+ tags:
+ with_pkg
+
+- name: pause after docker install before starting (on openstack vms)
+ pause: seconds=5
+ when: ceph_docker_on_openstack
+ tags:
+ with_pkg
+
+- name: start docker service
+ service:
+ name: docker
+ state: started
+ enabled: yes
+ tags:
+ with_pkg
--- /dev/null
+---
+- name: check if selinux is enabled
+ command: getenforce
+ register: sestatus
+ changed_when: false
+
+- name: set selinux permissions
+ shell: chcon -Rt svirt_sandbox_file_t {{ item }}
+ with_items:
+ - /etc/ceph
+ - /etc/ganesha
+ - /var/lib/ceph
+ - /var/lib/nfs/ganesha
+ - /var/run/ganesha
+ changed_when: false
+ when: sestatus.stdout != 'Disabled'
--- /dev/null
+---
+# Use systemd to manage container on Atomic host and CoreOS
+- name: generate systemd unit file
+ become: true
+ template:
+ src: "{{ playbook_dir }}/roles/ceph-nfs/templates/ceph-nfs.service.j2"
+ dest: /var/lib/nfs/ganesha/ceph-nfs@.service
+ owner: "root"
+ group: "root"
+ mode: "0644"
+ when:
+ is_atomic or
+ ansible_os_family == 'CoreOS'
+
+- name: link systemd unit file for NFS instance
+ file:
+ src: /var/lib/nfs/ganesha/ceph-nfs@.service
+ dest: /etc/systemd/system/multi-user.target.wants/ceph-nfs@{{ ansible_hostname }}.service
+ state: link
+ when:
+ is_atomic or
+ ansible_os_family == 'CoreOS'
+
+- name: enable systemd unit file for NFS instance
+ shell: systemctl enable /etc/systemd/system/multi-user.target.wants/ceph-nfs@{{ ansible_hostname }}.service
+ failed_when: false
+ changed_when: false
+ when:
+ is_atomic or
+ ansible_os_family == 'CoreOS'
+
+- name: reload systemd unit files
+ shell: systemctl daemon-reload
+ changed_when: false
+ failed_when: false
+ when:
+ is_atomic or
+ ansible_os_family == 'CoreOS'
+
+- name: systemd start NFS container
+ service:
+ name: ceph-nfs@{{ ansible_hostname }}
+ state: started
+ enabled: yes
+ changed_when: false
+ when:
+ is_atomic or
+ ansible_os_family == 'CoreOS'
+
+- name: wait for ceph.conf exists
+ wait_for:
+ path: /etc/ceph/ceph.conf
+ when: is_atomic
+
+- name: run the ceph NFS docker image
+ docker:
+ image: "{{ ceph_nfs_docker_username }}/{{ ceph_nfs_docker_imagename }}"
+ name: "{{ ansible_hostname }}"
+ net: "host"
+ state: "running"
+ privileged: true
+ ports: "{{ ceph_nfs_port }}:{{ ceph_nfs_port }},111:111"
+ env: "CEPH_DAEMON=NFS,CEPH_PUBLIC_NETWORK={{ ceph_nfs_docker_subnet }},{{ ceph_nfs_extra_envs }}"
+ volumes: "/etc/ceph:/etc/ceph,/etc/ganesha:/etc/ganesha"
+ when:
+ not is_atomic and
+ ansible_os_family != 'CoreOS' and
+ not mon_containerized_deployment_with_kv
+
+- name: run the ceph NFS docker image with kv
+ docker:
+ image: "{{ ceph_nfs_docker_username }}/{{ ceph_nfs_docker_imagename }}"
+ name: "{{ ansible_hostname }}"
+ net: "host"
+ state: "running"
+ privileged: true
+ env: "CEPH_DAEMON=NFS,CEPH_PUBLIC_NETWORK={{ ceph_nfs_docker_subnet }},{{ ceph_nfs_extra_envs }}"
+ volumes: "/etc/ganesha:/etc/ganesha"
+ when:
+ not is_atomic and
+ ansible_os_family != 'CoreOS' and
+ mon_containerized_deployment_with_kv
--- /dev/null
+---
+- include: pre_requisite.yml
+ when: not nfs_containerized_deployment
+
+- include: ./docker/main.yml
+ when: nfs_containerized_deployment
--- /dev/null
+---
+- name: create NFS gateway directories
+ file:
+ path: "{{ item }}"
+ state: directory
+ owner: "{{ dir_owner }}"
+ group: "{{ dir_group }}"
+ mode: "{{ dir_mode }}"
+ with_items:
+ - /var/lib/nfs/ganesha
+ - /var/run/ganesha
+
+- name: start NFS gateway service
+ service:
+ name: nfs-ganesha
+ state: started
+ enabled: yes
--- /dev/null
+[Unit]
+Description=NFS-Ganesha file server
+Documentation=http://github.com/nfs-ganesha/nfs-ganesha/wiki
+After=docker.service
+
+[Service]
+EnvironmentFile=-/etc/environment
+ExecStartPre=-/usr/bin/docker rm %i
+ExecStartPre=/usr/bin/mkdir -p /etc/ceph /etc/ganesha /var/lib/nfs/ganesha
+ExecStart=/usr/bin/docker run --rm --name %i --net=host \
+ {% if not mon_containerized_deployment_with_kv -%}
+ -v /etc/ceph:/etc/ceph \
+ -v /etc/ganesha:/etc/ganesha \
+ {% else -%}
+ -e KV_TYPE={{kv_type}} \
+ -e KV_IP={{kv_endpoint}}\
+ {% endif -%}
+ --privileged \
+ -e CEPH_DAEMON=NFS \
+ -e CEPH_PUBLIC_NETWORK={{ ceph_mon_docker_subnet }} \
+ --name={{ ansible_hostname }} \
+ {{ ceph_nfs_docker_username }}/{{ ceph_nfs_docker_imagename }}
+ExecStopPost=-/usr/bin/docker stop %i
+Restart=always
+RestartSec=10s
+TimeoutStartSec=120
+TimeoutStopSec=15
+
+[Install]
+WantedBy=multi-user.target
roles:
- ceph-rgw
+- hosts: nfss
+ become: True
+ roles:
+ - ceph-nfs
+
- hosts: restapis
become: True
roles:
roles:
- ceph-rgw
+- hosts: nfss
+ become: True
+ roles:
+ - ceph-nfs
+
- hosts: restapis
become: True
roles:
osd_vms: 1
mds_vms: 0
rgw_vms: 0
+nfs_vms: 0
client_vms: 0
# Deploy RESTAPI on each of the Monitors
osd_vms: 1
mds_vms: 0
rgw_vms: 0
+nfs_vms: 0
client_vms: 0
# Deploy RESTAPI on each of the Monitors
osd_vms: 3
mds_vms: 0
rgw_vms: 0
+nfs_vms: 0
client_vms: 0
# Deploy RESTAPI on each of the Monitors