deep_scrub_choked
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
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 [2014] [Sébastien Han]
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,3 @@
|
||||
# Ansible role: ceph-client
|
||||
|
||||
Documentation is available at http://docs.ceph.com/ceph-ansible/.
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
###########
|
||||
# GENERAL #
|
||||
###########
|
||||
|
||||
# Even though Client nodes should not have the admin key
|
||||
# at their disposal, some people might want to have it
|
||||
# distributed on Client nodes. Setting 'copy_admin_key' to 'true'
|
||||
# will copy the admin key to the /etc/ceph/ directory
|
||||
copy_admin_key: false
|
||||
|
||||
user_config: false
|
||||
# When pg_autoscale_mode is set to True, you must add the target_size_ratio key with a correct value
|
||||
# `pg_num` and `pgp_num` keys will be ignored, even if specified.
|
||||
# eg:
|
||||
# test:
|
||||
# name: "test"
|
||||
# application: "rbd"
|
||||
# target_size_ratio: 0.2
|
||||
test:
|
||||
name: "test"
|
||||
application: "rbd"
|
||||
test2:
|
||||
name: "test2"
|
||||
application: "rbd"
|
||||
pools:
|
||||
- "{{ test }}"
|
||||
- "{{ test2 }}"
|
||||
|
||||
# Generate a keyring using ceph-authtool CLI or python.
|
||||
# Eg:
|
||||
# $ ceph-authtool --gen-print-key
|
||||
# or
|
||||
# $ python2 -c "import os ; import struct ; import time; import base64 ; key = os.urandom(16) ; header = struct.pack('<hiih',1,int(time.time()),0,len(key)) ; print(base64.b64encode(header + key))"
|
||||
#
|
||||
# To use a particular secret, you have to add 'key' to the dict below, so something like:
|
||||
# - { name: client.test, key: "AQAin8tUMICVFBAALRHNrV0Z4MXupRw4v9JQ6Q==" ...
|
||||
|
||||
keys:
|
||||
- { name: client.test, caps: { mon: "profile rbd", osd: "allow class-read object_prefix rbd_children, profile rbd pool=test" }, mode: "{{ ceph_keyring_permissions }}" }
|
||||
- { name: client.test2, caps: { mon: "profile rbd", osd: "allow class-read object_prefix rbd_children, profile rbd pool=test2" }, mode: "{{ ceph_keyring_permissions }}" }
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
galaxy_info:
|
||||
company: Red Hat
|
||||
author: Sébastien Han
|
||||
description: Installs A Ceph Client
|
||||
license: Apache
|
||||
min_ansible_version: '2.7'
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- 'all'
|
||||
galaxy_tags:
|
||||
- system
|
||||
dependencies: []
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
- name: Set_fact delegated_node
|
||||
ansible.builtin.set_fact:
|
||||
delegated_node: "{{ groups[mon_group_name][0] if groups.get(mon_group_name, []) | length > 0 else inventory_hostname }}"
|
||||
|
||||
- name: Set_fact admin_key_presence
|
||||
ansible.builtin.set_fact:
|
||||
admin_key_presence: "{{ True if groups.get(mon_group_name, []) | length > 0 else copy_admin_key }}"
|
||||
|
||||
- name: Create cephx key(s)
|
||||
ceph_key:
|
||||
name: "{{ item.name }}"
|
||||
caps: "{{ item.caps }}"
|
||||
secret: "{{ item.key | default('') }}"
|
||||
cluster: "{{ cluster }}"
|
||||
dest: "{{ ceph_conf_key_directory }}"
|
||||
import_key: "{{ admin_key_presence }}"
|
||||
mode: "{{ item.mode | default(ceph_keyring_permissions) }}"
|
||||
owner: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
group: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
with_items:
|
||||
- "{{ keys }}"
|
||||
delegate_to: "{{ delegated_node }}"
|
||||
when:
|
||||
- cephx | bool
|
||||
- keys | length > 0
|
||||
- inventory_hostname == groups.get('_filtered_clients') | first
|
||||
no_log: "{{ no_log_on_ceph_key_tasks }}"
|
||||
|
||||
- name: Slurp client cephx key(s)
|
||||
ansible.builtin.slurp:
|
||||
src: "{{ ceph_conf_key_directory }}/{{ cluster }}.{{ item.name }}.keyring"
|
||||
with_items: "{{ keys }}"
|
||||
register: slurp_client_keys
|
||||
delegate_to: "{{ delegated_node }}"
|
||||
when:
|
||||
- cephx | bool
|
||||
- keys | length > 0
|
||||
- inventory_hostname == groups.get('_filtered_clients') | first
|
||||
no_log: "{{ no_log_on_ceph_key_tasks }}"
|
||||
|
||||
- name: Pool related tasks
|
||||
when:
|
||||
- admin_key_presence | bool
|
||||
- inventory_hostname == groups.get('_filtered_clients', []) | first
|
||||
block:
|
||||
- name: Import ceph-facts role
|
||||
ansible.builtin.import_role:
|
||||
name: ceph-facts
|
||||
tasks_from: get_def_crush_rule_name.yml
|
||||
|
||||
- name: Create ceph pool(s)
|
||||
ceph_pool:
|
||||
name: "{{ item.name }}"
|
||||
cluster: "{{ cluster }}"
|
||||
pg_num: "{{ item.pg_num | default(omit) }}"
|
||||
pgp_num: "{{ item.pgp_num | default(omit) }}"
|
||||
size: "{{ item.size | default(omit) }}"
|
||||
min_size: "{{ item.min_size | default(omit) }}"
|
||||
pool_type: "{{ item.type | default('replicated') }}"
|
||||
rule_name: "{{ item.rule_name | default(omit) }}"
|
||||
erasure_profile: "{{ item.erasure_profile | default(omit) }}"
|
||||
pg_autoscale_mode: "{{ item.pg_autoscale_mode | default(omit) }}"
|
||||
target_size_ratio: "{{ item.target_size_ratio | default(omit) }}"
|
||||
application: "{{ item.application | default(omit) }}"
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
with_items: "{{ pools }}"
|
||||
changed_when: false
|
||||
delegate_to: "{{ delegated_node }}"
|
||||
|
||||
- name: Get client cephx keys
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ item.source }}"
|
||||
content: "{{ item.content | b64decode }}"
|
||||
mode: "{{ item.item.get('mode', '0600') }}"
|
||||
owner: "{{ ceph_uid }}"
|
||||
group: "{{ ceph_uid }}"
|
||||
with_items: "{{ hostvars[groups['_filtered_clients'][0]]['slurp_client_keys']['results'] }}"
|
||||
when: not item.get('skipped', False)
|
||||
no_log: "{{ no_log_on_ceph_key_tasks }}"
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: Include pre_requisite.yml
|
||||
ansible.builtin.include_tasks: pre_requisite.yml
|
||||
when: groups.get(mon_group_name, []) | length > 0
|
||||
|
||||
- name: Include create_users_keys.yml
|
||||
ansible.builtin.include_tasks: create_users_keys.yml
|
||||
when:
|
||||
- user_config | bool
|
||||
- not rolling_update | default(False) | bool
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
- name: Copy ceph admin keyring
|
||||
when:
|
||||
- cephx | bool
|
||||
- copy_admin_key | bool
|
||||
block:
|
||||
- name: Get keys from monitors
|
||||
ceph_key_info:
|
||||
name: client.admin
|
||||
cluster: "{{ cluster }}"
|
||||
output_format: plain
|
||||
state: info
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
register: _admin_key
|
||||
delegate_to: "{{ groups.get(mon_group_name)[0] }}"
|
||||
run_once: true
|
||||
no_log: "{{ no_log_on_ceph_key_tasks }}"
|
||||
|
||||
- name: Copy ceph key(s) if needed
|
||||
ansible.builtin.copy:
|
||||
dest: "/etc/ceph/{{ cluster }}.client.admin.keyring"
|
||||
content: "{{ _admin_key.stdout + '\n' }}"
|
||||
owner: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
group: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
mode: "{{ ceph_keyring_permissions }}"
|
||||
no_log: "{{ no_log_on_ceph_key_tasks }}"
|
||||
@@ -0,0 +1,201 @@
|
||||
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 [2014] [Sébastien Han]
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,3 @@
|
||||
# Ansible role: ceph-common
|
||||
|
||||
Documentation is available at http://docs.ceph.com/ceph-ansible/.
|
||||
@@ -0,0 +1 @@
|
||||
---
|
||||
@@ -0,0 +1,29 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1
|
||||
|
||||
mQINBFX4hgkBEADLqn6O+UFp+ZuwccNldwvh5PzEwKUPlXKPLjQfXlQRig1flpCH
|
||||
E0HJ5wgGlCtYd3Ol9f9+qU24kDNzfbs5bud58BeE7zFaZ4s0JMOMuVm7p8JhsvkU
|
||||
C/Lo/7NFh25e4kgJpjvnwua7c2YrA44ggRb1QT19ueOZLK5wCQ1mR+0GdrcHRCLr
|
||||
7Sdw1d7aLxMT+5nvqfzsmbDullsWOD6RnMdcqhOxZZvpay8OeuK+yb8FVQ4sOIzB
|
||||
FiNi5cNOFFHg+8dZQoDrK3BpwNxYdGHsYIwU9u6DWWqXybBnB9jd2pve9PlzQUbO
|
||||
eHEa4Z+jPqxY829f4ldaql7ig8e6BaInTfs2wPnHJ+606g2UH86QUmrVAjVzlLCm
|
||||
nqoGymoAPGA4ObHu9X3kO8viMBId9FzooVqR8a9En7ZE0Dm9O7puzXR7A1f5sHoz
|
||||
JdYHnr32I+B8iOixhDUtxIY4GA8biGATNaPd8XR2Ca1hPuZRVuIiGG9HDqUEtXhV
|
||||
fY5qjTjaThIVKtYgEkWMT+Wet3DPPiWT3ftNOE907e6EWEBCHgsEuuZnAbku1GgD
|
||||
LBH4/a/yo9bNvGZKRaTUM/1TXhM5XgVKjd07B4cChgKypAVHvef3HKfCG2U/DkyA
|
||||
LjteHt/V807MtSlQyYaXUTGtDCrQPSlMK5TjmqUnDwy6Qdq8dtWN3DtBWQARAQAB
|
||||
tCpDZXBoLmNvbSAocmVsZWFzZSBrZXkpIDxzZWN1cml0eUBjZXBoLmNvbT6JAjgE
|
||||
EwECACIFAlX4hgkCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEOhKwsBG
|
||||
DzmUXdIQAI8YPcZMBWdv489q8CzxlfRIRZ3Gv/G/8CH+EOExcmkVZ89mVHngCdAP
|
||||
DOYCl8twWXC1lwJuLDBtkUOHXNuR5+Jcl5zFOUyldq1Hv8u03vjnGT7lLJkJoqpG
|
||||
l9QD8nBqRvBU7EM+CU7kP8+09b+088pULil+8x46PwgXkvOQwfVKSOr740Q4J4nm
|
||||
/nUOyTNtToYntmt2fAVWDTIuyPpAqA6jcqSOC7Xoz9cYxkVWnYMLBUySXmSS0uxl
|
||||
3p+wK0lMG0my/gb+alke5PAQjcE5dtXYzCn+8Lj0uSfCk8Gy0ZOK2oiUjaCGYN6D
|
||||
u72qDRFBnR3jaoFqi03bGBIMnglGuAPyBZiI7LJgzuT9xumjKTJW3kN4YJxMNYu1
|
||||
FzmIyFZpyvZ7930vB2UpCOiIaRdZiX4Z6ZN2frD3a/vBxBNqiNh/BO+Dex+PDfI4
|
||||
TqwF8zlcjt4XZ2teQ8nNMR/D8oiYTUW8hwR4laEmDy7ASxe0p5aijmUApWq5UTsF
|
||||
+s/QbwugccU0iR5orksM5u9MZH4J/mFGKzOltfGXNLYI6D5Mtwrnyi0BsF5eY0u6
|
||||
vkdivtdqrq2DXY+ftuqLOQ7b+t1RctbcMHGPptlxFuN9ufP5TiTWSpfqDwmHCLsT
|
||||
k2vFiMwcHdLpQ1IH8ORVRgPPsiBnBOJ/kIiXG2SxPUTjjEGOVgeA
|
||||
=/Tod
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
@@ -0,0 +1,34 @@
|
||||
pub 4096R/FD431D51 2009-10-22
|
||||
Key fingerprint = 567E 347A D004 4ADE 55BA 8A5F 199E 2F91 FD43 1D51
|
||||
uid Red Hat, Inc. (release key 2) <security@redhat.com>
|
||||
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.5 (GNU/Linux)
|
||||
|
||||
mQINBErgSTsBEACh2A4b0O9t+vzC9VrVtL1AKvUWi9OPCjkvR7Xd8DtJxeeMZ5eF
|
||||
0HtzIG58qDRybwUe89FZprB1ffuUKzdE+HcL3FbNWSSOXVjZIersdXyH3NvnLLLF
|
||||
0DNRB2ix3bXG9Rh/RXpFsNxDp2CEMdUvbYCzE79K1EnUTVh1L0Of023FtPSZXX0c
|
||||
u7Pb5DI5lX5YeoXO6RoodrIGYJsVBQWnrWw4xNTconUfNPk0EGZtEnzvH2zyPoJh
|
||||
XGF+Ncu9XwbalnYde10OCvSWAZ5zTCpoLMTvQjWpbCdWXJzCm6G+/hx9upke546H
|
||||
5IjtYm4dTIVTnc3wvDiODgBKRzOl9rEOCIgOuGtDxRxcQkjrC+xvg5Vkqn7vBUyW
|
||||
9pHedOU+PoF3DGOM+dqv+eNKBvh9YF9ugFAQBkcG7viZgvGEMGGUpzNgN7XnS1gj
|
||||
/DPo9mZESOYnKceve2tIC87p2hqjrxOHuI7fkZYeNIcAoa83rBltFXaBDYhWAKS1
|
||||
PcXS1/7JzP0ky7d0L6Xbu/If5kqWQpKwUInXtySRkuraVfuK3Bpa+X1XecWi24JY
|
||||
HVtlNX025xx1ewVzGNCTlWn1skQN2OOoQTV4C8/qFpTW6DTWYurd4+fE0OJFJZQF
|
||||
buhfXYwmRlVOgN5i77NTIJZJQfYFj38c/Iv5vZBPokO6mffrOTv3MHWVgQARAQAB
|
||||
tDNSZWQgSGF0LCBJbmMuIChyZWxlYXNlIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0
|
||||
LmNvbT6JAjYEEwECACAFAkrgSTsCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK
|
||||
CRAZni+R/UMdUWzpD/9s5SFR/ZF3yjY5VLUFLMXIKUztNN3oc45fyLdTI3+UClKC
|
||||
2tEruzYjqNHhqAEXa2sN1fMrsuKec61Ll2NfvJjkLKDvgVIh7kM7aslNYVOP6BTf
|
||||
C/JJ7/ufz3UZmyViH/WDl+AYdgk3JqCIO5w5ryrC9IyBzYv2m0HqYbWfphY3uHw5
|
||||
un3ndLJcu8+BGP5F+ONQEGl+DRH58Il9Jp3HwbRa7dvkPgEhfFR+1hI+Btta2C7E
|
||||
0/2NKzCxZw7Lx3PBRcU92YKyaEihfy/aQKZCAuyfKiMvsmzs+4poIX7I9NQCJpyE
|
||||
IGfINoZ7VxqHwRn/d5mw2MZTJjbzSf+Um9YJyA0iEEyD6qjriWQRbuxpQXmlAJbh
|
||||
8okZ4gbVFv1F8MzK+4R8VvWJ0XxgtikSo72fHjwha7MAjqFnOq6eo6fEC/75g3NL
|
||||
Ght5VdpGuHk0vbdENHMC8wS99e5qXGNDued3hlTavDMlEAHl34q2H9nakTGRF5Ki
|
||||
JUfNh3DVRGhg8cMIti21njiRh7gyFI2OccATY7bBSr79JhuNwelHuxLrCFpY7V25
|
||||
OFktl15jZJaMxuQBqYdBgSay2G0U6D1+7VsWufpzd/Abx1/c3oi9ZaJvW22kAggq
|
||||
dzdA27UUYjWvx42w9menJwh/0jeQcTecIUd0d0rFcw/c1pvgMMl/Q73yzKgKYw==
|
||||
=zbHE
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
galaxy_info:
|
||||
company: Red Hat
|
||||
author: Sébastien Han
|
||||
description: Installs Ceph
|
||||
license: Apache
|
||||
min_ansible_version: '2.7'
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- 'all'
|
||||
galaxy_tags:
|
||||
- system
|
||||
dependencies: []
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
- name: Configure cluster name
|
||||
ansible.builtin.lineinfile:
|
||||
dest: /etc/sysconfig/ceph
|
||||
insertafter: EOF
|
||||
create: true
|
||||
line: "CLUSTER={{ cluster }}"
|
||||
regexp: "^CLUSTER="
|
||||
mode: "0644"
|
||||
when: ansible_facts['os_family'] in ["RedHat", "Suse"]
|
||||
|
||||
# NOTE(leseb): we are performing the following check
|
||||
# to ensure any Jewel installation will not fail.
|
||||
# The following commit https://github.com/ceph/ceph/commit/791eba81a5467dd5de4f1680ed0deb647eb3fb8b
|
||||
# fixed a package issue where the path was the wrong.
|
||||
# This bug is not yet on all the distros package so we are working around it
|
||||
# Impacted versions:
|
||||
# - Jewel from UCA: https://bugs.launchpad.net/ubuntu/+source/ceph/+bug/1582773
|
||||
# - Jewel from latest Canonical 16.04 distro
|
||||
# - All previous versions from Canonical
|
||||
# - Infernalis from ceph.com
|
||||
- name: Debian based systems - configure cluster name
|
||||
when: ansible_facts['os_family'] == "Debian"
|
||||
block:
|
||||
- name: Check /etc/default/ceph exist
|
||||
ansible.builtin.stat:
|
||||
path: /etc/default/ceph
|
||||
register: etc_default_ceph
|
||||
check_mode: false
|
||||
|
||||
- name: Configure cluster name
|
||||
when: etc_default_ceph.stat.exists
|
||||
block:
|
||||
- name: When /etc/default/ceph is not dir
|
||||
ansible.builtin.lineinfile:
|
||||
dest: /etc/default/ceph
|
||||
insertafter: EOF
|
||||
create: true
|
||||
regexp: "^CLUSTER="
|
||||
line: "CLUSTER={{ cluster }}"
|
||||
mode: "0644"
|
||||
when: not etc_default_ceph.stat.isdir
|
||||
|
||||
- name: When /etc/default/ceph is dir
|
||||
ansible.builtin.lineinfile:
|
||||
dest: /etc/default/ceph/ceph
|
||||
insertafter: EOF
|
||||
create: true
|
||||
regexp: "^CLUSTER="
|
||||
line: "CLUSTER={{ cluster }}"
|
||||
mode: "0644"
|
||||
when: etc_default_ceph.stat.isdir
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
- name: Configure TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES for debian
|
||||
ansible.builtin.lineinfile:
|
||||
dest: "{{ etc_default_ceph.stat.isdir | ternary('/etc/default/ceph/ceph', '/etc/default/ceph') }}"
|
||||
insertafter: EOF
|
||||
create: true
|
||||
regexp: "^TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES="
|
||||
line: "TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES={{ ceph_tcmalloc_max_total_thread_cache }}"
|
||||
mode: "0644"
|
||||
when:
|
||||
- ansible_facts['os_family'] == 'Debian'
|
||||
- etc_default_ceph.stat.exists
|
||||
notify:
|
||||
- Restart ceph mons
|
||||
- Restart ceph mgrs
|
||||
- Restart ceph osds
|
||||
- Restart ceph mdss
|
||||
- Restart ceph rgws
|
||||
- Restart ceph rbdmirrors
|
||||
|
||||
- name: Configure TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES for redhat
|
||||
ansible.builtin.lineinfile:
|
||||
dest: "/etc/sysconfig/ceph"
|
||||
insertafter: EOF
|
||||
create: true
|
||||
regexp: "^TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES="
|
||||
line: "TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES={{ ceph_tcmalloc_max_total_thread_cache }}"
|
||||
mode: "0644"
|
||||
when: ansible_facts['os_family'] == 'RedHat'
|
||||
notify:
|
||||
- Restart ceph mons
|
||||
- Restart ceph mgrs
|
||||
- Restart ceph osds
|
||||
- Restart ceph mdss
|
||||
- Restart ceph rgws
|
||||
- Restart ceph rbdmirrors
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
- name: Config repository for Red Hat based OS
|
||||
when: ansible_facts['os_family'] == 'RedHat'
|
||||
block:
|
||||
- name: Include installs/configure_redhat_repository_installation.yml
|
||||
ansible.builtin.include_tasks: installs/configure_redhat_repository_installation.yml
|
||||
when: ceph_origin == 'repository'
|
||||
|
||||
- name: Include installs/configure_redhat_local_installation.yml
|
||||
ansible.builtin.include_tasks: installs/configure_redhat_local_installation.yml
|
||||
when: ceph_origin == 'local'
|
||||
|
||||
- name: Config repository for Debian based OS
|
||||
when: ansible_facts['os_family'] == 'Debian'
|
||||
tags: package-install
|
||||
block:
|
||||
- name: Include installs/configure_debian_repository_installation.yml
|
||||
ansible.builtin.include_tasks: installs/configure_debian_repository_installation.yml
|
||||
when: ceph_origin == 'repository'
|
||||
|
||||
- name: Update apt cache if cache_valid_time has expired
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
cache_valid_time: 3600
|
||||
register: result
|
||||
until: result is succeeded
|
||||
|
||||
- name: Include installs/configure_suse_repository_installation.yml
|
||||
ansible.builtin.include_tasks: installs/configure_suse_repository_installation.yml
|
||||
when:
|
||||
- ansible_facts['os_family'] == 'Suse'
|
||||
- ceph_origin == 'repository'
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Create rbd client directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ rbd_client_directory_owner }}"
|
||||
group: "{{ rbd_client_directory_group }}"
|
||||
mode: "{{ rbd_client_directory_mode }}"
|
||||
with_items:
|
||||
- "{{ rbd_client_admin_socket_path }}"
|
||||
- "{{ rbd_client_log_path }}"
|
||||
when: rbd_client_directories | bool
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
- name: Include debian_community_repository.yml
|
||||
ansible.builtin.include_tasks: debian_community_repository.yml
|
||||
when: ceph_repository == 'community'
|
||||
|
||||
- name: Include debian_dev_repository.yml
|
||||
ansible.builtin.include_tasks: debian_dev_repository.yml
|
||||
when: ceph_repository == 'dev'
|
||||
|
||||
- name: Include debian_custom_repository.yml
|
||||
ansible.builtin.include_tasks: debian_custom_repository.yml
|
||||
when: ceph_repository == 'custom'
|
||||
|
||||
- name: Include debian_uca_repository.yml
|
||||
ansible.builtin.include_tasks: debian_uca_repository.yml
|
||||
when: ceph_repository == 'uca'
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
- name: Make sure /tmp exists
|
||||
ansible.builtin.file:
|
||||
path: /tmp
|
||||
state: directory
|
||||
mode: "0755"
|
||||
when: use_installer | bool
|
||||
|
||||
- name: Use mktemp to create name for rundep
|
||||
ansible.builtin.tempfile:
|
||||
path: /tmp
|
||||
prefix: rundep.
|
||||
register: rundep_location
|
||||
when: use_installer | bool
|
||||
|
||||
- name: Copy rundep
|
||||
ansible.builtin.copy:
|
||||
src: "{{ ansible_dir }}/rundep"
|
||||
dest: "{{ rundep_location.path }}"
|
||||
mode: preserve
|
||||
when: use_installer | bool
|
||||
|
||||
- name: Install ceph dependencies
|
||||
ansible.builtin.script: "{{ ansible_dir }}/rundep_installer.sh {{ rundep_location.path }}"
|
||||
when: use_installer | bool
|
||||
|
||||
- name: Ensure rsync is installed
|
||||
ansible.builtin.package:
|
||||
name: rsync
|
||||
state: present
|
||||
register: result
|
||||
until: result is succeeded
|
||||
|
||||
- name: Synchronize ceph install
|
||||
ansible.posix.synchronize:
|
||||
src: "{{ ceph_installation_dir }}/"
|
||||
dest: "/"
|
||||
|
||||
- name: Create user group ceph
|
||||
ansible.builtin.group:
|
||||
name: 'ceph'
|
||||
|
||||
- name: Create user ceph
|
||||
ansible.builtin.user:
|
||||
name: 'ceph'
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
- name: Configure epel repository
|
||||
ansible.builtin.package:
|
||||
name: epel-release
|
||||
register: result
|
||||
until: result is succeeded
|
||||
tags: with_pkg
|
||||
when:
|
||||
- ansible_facts['distribution'] == 'Rocky'
|
||||
|
||||
- name: Install python3-packaging
|
||||
ansible.builtin.yum:
|
||||
name: python3-packaging
|
||||
enablerepo: powertools
|
||||
state: present
|
||||
when: ansible_facts['distribution_major_version'] | int < 9
|
||||
|
||||
- name: Include redhat_community_repository.yml
|
||||
ansible.builtin.include_tasks: redhat_community_repository.yml
|
||||
when: ceph_repository == 'community'
|
||||
|
||||
- name: Include redhat_dev_repository.yml
|
||||
ansible.builtin.include_tasks: redhat_dev_repository.yml
|
||||
when: ceph_repository == 'dev'
|
||||
|
||||
- name: Include redhat_custom_repository.yml
|
||||
ansible.builtin.include_tasks: redhat_custom_repository.yml
|
||||
when: ceph_repository == 'custom'
|
||||
|
||||
# Remove yum caches so yum doesn't get confused if we are reinstalling a different ceph version
|
||||
- name: Purge yum cache
|
||||
ansible.builtin.command: yum clean all # noqa: [303]
|
||||
changed_when: false
|
||||
when: ansible_facts['pkg_mgr'] == 'yum'
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
- name: Include suse_obs_repository.yml
|
||||
ansible.builtin.include_tasks: suse_obs_repository.yml
|
||||
when: ceph_repository == 'obs'
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
- name: Install dependencies for apt modules
|
||||
ansible.builtin.package:
|
||||
name: ['apt-transport-https', 'ca-certificates', 'gnupg', 'software-properties-common']
|
||||
update_cache: true
|
||||
register: result
|
||||
until: result is succeeded
|
||||
|
||||
- name: Configure debian ceph community repository stable key
|
||||
ansible.builtin.apt_key:
|
||||
data: "{{ lookup('file', role_path + '/files/cephstable.asc') }}"
|
||||
state: present
|
||||
register: result
|
||||
until: result is succeeded
|
||||
|
||||
- name: Configure debian ceph stable community repository
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "deb {{ ceph_stable_repo }} {{ ceph_stable_distro_source | default(ansible_facts['distribution_release']) }} main"
|
||||
state: present
|
||||
update_cache: true
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Configure debian custom apt key
|
||||
ansible.builtin.apt_key:
|
||||
url: "{{ ceph_custom_key }}"
|
||||
state: present
|
||||
register: result
|
||||
until: result is succeeded
|
||||
when: ceph_custom_key is defined
|
||||
|
||||
- name: Configure debian custom repository
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "deb {{ ceph_custom_repo }} {{ ansible_facts['distribution_release'] }} main"
|
||||
state: present
|
||||
update_cache: true
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Fetch ceph debian development repository
|
||||
ansible.builtin.uri:
|
||||
url: "https://shaman.ceph.com/api/repos/ceph/{{ ceph_dev_branch }}/{{ ceph_dev_sha1 }}/{{ ansible_facts['distribution'] | lower }}/{{ ansible_facts['distribution_release'] }}/repo?arch={{ ansible_facts['architecture'] }}"
|
||||
return_content: true
|
||||
register: ceph_dev_deb_repo
|
||||
|
||||
- name: Configure ceph debian development repository
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "{{ ceph_dev_deb_repo.content }}"
|
||||
state: present
|
||||
update_cache: true
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Add ubuntu cloud archive key package
|
||||
ansible.builtin.package:
|
||||
name: ubuntu-cloud-keyring
|
||||
register: result
|
||||
until: result is succeeded
|
||||
|
||||
- name: Add ubuntu cloud archive repository
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "deb {{ ceph_stable_repo_uca }} {{ ceph_stable_release_uca }} main"
|
||||
state: present
|
||||
update_cache: true
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
- name: Install ceph for debian
|
||||
ansible.builtin.apt:
|
||||
name: "{{ debian_ceph_pkgs | unique }}"
|
||||
update_cache: false
|
||||
state: "{{ (upgrade_ceph_packages | bool) | ternary('latest', 'present') }}"
|
||||
default_release: "{{ ceph_stable_release_uca | default('') if ceph_origin == 'repository' and ceph_repository == 'uca' else '' }}{{ ansible_facts['distribution_release'] ~ '-backports' if ceph_origin == 'distro' and ceph_use_distro_backports | bool else '' }}"
|
||||
register: result
|
||||
until: result is succeeded
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
- name: Install ceph bundle
|
||||
community.general.swupd:
|
||||
name: storage-cluster
|
||||
state: present
|
||||
register: result
|
||||
until: result is succeeded
|
||||
@@ -0,0 +1,13 @@
|
||||
- name: Install dependencies
|
||||
ansible.builtin.apt:
|
||||
name: "{{ debian_package_dependencies }}"
|
||||
state: present
|
||||
update_cache: true
|
||||
cache_valid_time: 3600
|
||||
register: result
|
||||
until: result is succeeded
|
||||
|
||||
- name: Include install_debian_packages.yml
|
||||
ansible.builtin.include_tasks: install_debian_packages.yml
|
||||
when:
|
||||
- (ceph_origin == 'repository' or ceph_origin == 'distro')
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
- name: Install redhat dependencies
|
||||
ansible.builtin.package:
|
||||
name: "{{ redhat_package_dependencies }}"
|
||||
state: present
|
||||
register: result
|
||||
until: result is succeeded
|
||||
when: ansible_facts['distribution'] == 'RedHat'
|
||||
|
||||
- name: Install centos dependencies
|
||||
ansible.builtin.yum:
|
||||
name: "{{ centos_package_dependencies }}"
|
||||
state: present
|
||||
register: result
|
||||
until: result is succeeded
|
||||
when: ansible_facts['distribution'] == 'CentOS'
|
||||
|
||||
- name: Install redhat ceph packages
|
||||
ansible.builtin.package:
|
||||
name: "{{ redhat_ceph_pkgs | unique }}"
|
||||
state: "{{ (upgrade_ceph_packages | bool) | ternary('latest', 'present') }}"
|
||||
register: result
|
||||
until: result is succeeded
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Install SUSE/openSUSE dependencies
|
||||
ansible.builtin.package:
|
||||
name: "{{ suse_package_dependencies }}"
|
||||
state: present
|
||||
register: result
|
||||
until: result is succeeded
|
||||
|
||||
- name: Install SUSE/openSUSE ceph packages
|
||||
ansible.builtin.package:
|
||||
name: "{{ suse_ceph_pkgs | unique }}"
|
||||
state: "{{ (upgrade_ceph_packages | bool) | ternary('latest', 'present') }}"
|
||||
register: result
|
||||
until: result is succeeded
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
- name: Install yum plugin priorities
|
||||
ansible.builtin.package:
|
||||
name: yum-plugin-priorities
|
||||
register: result
|
||||
until: result is succeeded
|
||||
tags: with_pkg
|
||||
when: ansible_facts['distribution_major_version'] | int == 7
|
||||
|
||||
- name: Configure red hat ceph community repository stable key
|
||||
ansible.builtin.rpm_key:
|
||||
key: "{{ ceph_stable_key }}"
|
||||
state: present
|
||||
register: result
|
||||
until: result is succeeded
|
||||
|
||||
- name: Configure red hat ceph stable community repository
|
||||
ansible.builtin.yum_repository:
|
||||
name: ceph_stable
|
||||
description: Ceph Stable $basearch repo
|
||||
gpgcheck: true
|
||||
state: present
|
||||
gpgkey: "{{ ceph_stable_key }}"
|
||||
baseurl: "{{ ceph_mirror }}/rpm-{{ ceph_stable_release }}/el{{ ansible_facts['distribution_major_version'] }}/$basearch"
|
||||
file: ceph_stable
|
||||
priority: 2
|
||||
register: result
|
||||
until: result is succeeded
|
||||
|
||||
- name: Configure red hat ceph stable noarch community repository
|
||||
ansible.builtin.yum_repository:
|
||||
name: ceph_stable_noarch
|
||||
description: Ceph Stable noarch repo
|
||||
gpgcheck: true
|
||||
state: present
|
||||
gpgkey: "{{ ceph_stable_key }}"
|
||||
baseurl: "{{ ceph_mirror }}/rpm-{{ ceph_stable_release }}/el{{ ansible_facts['distribution_major_version'] }}/noarch"
|
||||
file: ceph_stable
|
||||
priority: 2
|
||||
register: result
|
||||
until: result is succeeded
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
- name: Configure red hat custom rpm key
|
||||
ansible.builtin.rpm_key:
|
||||
key: "{{ ceph_custom_key }}"
|
||||
state: present
|
||||
register: result
|
||||
until: result is succeeded
|
||||
when: ceph_custom_key is defined
|
||||
|
||||
- name: Configure red hat custom repository
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ ceph_custom_repo }}"
|
||||
dest: /etc/yum.repos.d
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
- name: Fetch ceph red hat development repository
|
||||
ansible.builtin.uri:
|
||||
# Use the centos repo since we don't currently have a dedicated red hat repo
|
||||
url: "https://shaman.ceph.com/api/repos/ceph/{{ ceph_dev_branch }}/{{ ceph_dev_sha1 }}/centos/{{ ansible_facts['distribution_major_version'] }}/repo?arch={{ ansible_facts['architecture'] }}"
|
||||
return_content: true
|
||||
register: ceph_dev_yum_repo
|
||||
|
||||
- name: Configure ceph red hat development repository
|
||||
ansible.builtin.copy:
|
||||
content: "{{ ceph_dev_yum_repo.content }}"
|
||||
dest: /etc/yum.repos.d/ceph-dev.repo
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
backup: true
|
||||
|
||||
- name: Remove ceph_stable repositories
|
||||
ansible.builtin.yum_repository:
|
||||
name: '{{ item }}'
|
||||
file: ceph_stable
|
||||
state: absent
|
||||
with_items:
|
||||
- ceph_stable
|
||||
- ceph_stable_noarch
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: Configure openSUSE ceph OBS repository
|
||||
community.general.zypper_repository:
|
||||
name: "OBS:filesystems:ceph:{{ ceph_release }}"
|
||||
state: present
|
||||
repo: "{{ ceph_obs_repo }}"
|
||||
auto_import_keys: true
|
||||
autorefresh: true
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
- name: Include configure_repository.yml
|
||||
ansible.builtin.include_tasks: configure_repository.yml
|
||||
tags: package-configure
|
||||
|
||||
- name: Include installs/install_redhat_packages.yml
|
||||
ansible.builtin.include_tasks: installs/install_redhat_packages.yml
|
||||
when:
|
||||
- ansible_facts['os_family'] == 'RedHat'
|
||||
- (ceph_origin == 'repository' or ceph_origin == 'distro')
|
||||
tags: package-install
|
||||
|
||||
- name: Include installs/install_suse_packages.yml
|
||||
ansible.builtin.include_tasks: installs/install_suse_packages.yml
|
||||
when: ansible_facts['os_family'] == 'Suse'
|
||||
tags: package-install
|
||||
|
||||
- name: Include installs/install_on_debian.yml
|
||||
ansible.builtin.include_tasks: installs/install_on_debian.yml
|
||||
tags: package-install
|
||||
when: ansible_facts['os_family'] == 'Debian'
|
||||
|
||||
- name: Include_tasks installs/install_on_clear.yml
|
||||
ansible.builtin.include_tasks: installs/install_on_clear.yml
|
||||
when: ansible_facts['os_family'] == 'ClearLinux'
|
||||
tags: package-install
|
||||
|
||||
- name: Get ceph version
|
||||
ansible.builtin.command: ceph --version
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
register: ceph_version
|
||||
|
||||
- name: Set_fact ceph_version
|
||||
ansible.builtin.set_fact:
|
||||
ceph_version: "{{ ceph_version.stdout.split(' ')[2] }}"
|
||||
|
||||
- name: Set_fact ceph_release - override ceph_release with ceph_stable_release
|
||||
ansible.builtin.set_fact:
|
||||
ceph_release: "{{ ceph_stable_release }}"
|
||||
when:
|
||||
- ceph_origin == 'repository'
|
||||
- ceph_repository not in ['dev', 'custom']
|
||||
tags: always
|
||||
|
||||
- name: Include create_rbd_client_dir.yml
|
||||
ansible.builtin.include_tasks: create_rbd_client_dir.yml
|
||||
|
||||
- name: Include configure_cluster_name.yml
|
||||
ansible.builtin.include_tasks: configure_cluster_name.yml
|
||||
|
||||
- name: Include configure_memory_allocator.yml
|
||||
ansible.builtin.include_tasks: configure_memory_allocator.yml
|
||||
when:
|
||||
- (ceph_tcmalloc_max_total_thread_cache | int) > 0
|
||||
- (ceph_origin == 'repository' or ceph_origin == 'distro')
|
||||
|
||||
- name: Include selinux.yml
|
||||
ansible.builtin.include_tasks: selinux.yml
|
||||
when:
|
||||
- ansible_facts['os_family'] == 'RedHat'
|
||||
- inventory_hostname in groups.get(nfs_group_name, [])
|
||||
or inventory_hostname in groups.get(rgwloadbalancer_group_name, [])
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
- name: If selinux is not disabled
|
||||
when: ansible_facts['selinux']['status'] == 'enabled'
|
||||
block:
|
||||
- name: Install policycoreutils-python
|
||||
ansible.builtin.package:
|
||||
name: policycoreutils-python
|
||||
state: present
|
||||
register: result
|
||||
until: result is succeeded
|
||||
when: ansible_facts['distribution_major_version'] == '7'
|
||||
|
||||
- name: Install python3-policycoreutils on RHEL 8
|
||||
ansible.builtin.package:
|
||||
name: python3-policycoreutils
|
||||
state: present
|
||||
register: result
|
||||
until: result is succeeded
|
||||
when:
|
||||
- inventory_hostname in groups.get(nfs_group_name, [])
|
||||
or inventory_hostname in groups.get(rgwloadbalancer_group_name, [])
|
||||
- ansible_facts['distribution_major_version'] == '8'
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
# ceph-common is always installed, if a package isn't to be installed we replace
|
||||
# it with 'ceph-common' and run the install with the | unique filter.
|
||||
debian_ceph_pkgs:
|
||||
- "ceph"
|
||||
- "ceph-common"
|
||||
- "{{ (osd_group_name in group_names) | ternary('ceph-volume', 'ceph-common') }}"
|
||||
- "{{ (ceph_test | bool) | ternary('ceph-test', 'ceph-common') }}"
|
||||
- "{{ (rgw_group_name in group_names) | ternary('radosgw', 'ceph-common') }}"
|
||||
- "{{ (rbdmirror_group_name in group_names) | ternary('ceph-base', 'ceph-common') }}"
|
||||
|
||||
redhat_ceph_pkgs:
|
||||
- "{{ (ceph_test | bool) | ternary('ceph-test', 'ceph-common') }}"
|
||||
- "ceph-common"
|
||||
- "{{ (mon_group_name in group_names) | ternary('ceph-mon', 'ceph-common') }}"
|
||||
- "{{ (osd_group_name in group_names) | ternary('ceph-osd', 'ceph-common') }}"
|
||||
- "{{ (osd_group_name in group_names) | ternary('ceph-volume', 'ceph-common') }}"
|
||||
- "{{ (client_group_name in group_names) | ternary('ceph-fuse', 'ceph-common') }}"
|
||||
- "{{ (client_group_name in group_names) | ternary('ceph-base', 'ceph-common') }}"
|
||||
- "{{ (rgw_group_name in group_names) | ternary('ceph-radosgw', 'ceph-common') }}"
|
||||
- "{{ (rbdmirror_group_name in group_names) | ternary('ceph-base', 'ceph-common') }}"
|
||||
|
||||
suse_ceph_pkgs:
|
||||
- "{{ (ceph_test | bool) | ternary('ceph-test', 'ceph-common') }}"
|
||||
- "ceph-common"
|
||||
- "{{ (mon_group_name in group_names) | ternary('ceph-mon', 'ceph-common') }}"
|
||||
- "{{ (osd_group_name in group_names) | ternary('ceph-osd', 'ceph-common') }}"
|
||||
- "{{ (osd_group_name in group_names) | ternary('ceph-volume', 'ceph-common') }}"
|
||||
- "{{ (client_group_name in group_names) | ternary('ceph-fuse', 'ceph-common') }}"
|
||||
- "{{ (client_group_name in group_names) | ternary('ceph-base', 'ceph-common') }}"
|
||||
- "{{ (rgw_group_name in group_names) | ternary('ceph-radosgw', 'ceph-common') }}"
|
||||
- "{{ (rbdmirror_group_name in group_names) | ternary('ceph-base', 'ceph-common') }}"
|
||||
@@ -0,0 +1,201 @@
|
||||
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 [2014] [Guillaume Abrioux]
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,3 @@
|
||||
# Ansible role: ceph-config
|
||||
|
||||
Documentation is available at http://docs.ceph.com/ceph-ansible/.
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
galaxy_info:
|
||||
company: Red Hat
|
||||
author: Guillaume Abrioux
|
||||
description: Handles ceph-ansible initial configuration
|
||||
license: Apache
|
||||
min_ansible_version: '2.7'
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- 'all'
|
||||
galaxy_tags:
|
||||
- system
|
||||
dependencies: []
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
- name: Create ceph initial directories
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ ceph_uid }}"
|
||||
group: "{{ ceph_uid }}"
|
||||
mode: "0755"
|
||||
loop:
|
||||
- /etc/ceph
|
||||
- /var/lib/ceph/
|
||||
- /var/lib/ceph/mon
|
||||
- /var/lib/ceph/osd
|
||||
- /var/lib/ceph/mds
|
||||
- /var/lib/ceph/tmp
|
||||
- /var/lib/ceph/crash
|
||||
- /var/lib/ceph/radosgw
|
||||
- /var/lib/ceph/bootstrap-rgw
|
||||
- /var/lib/ceph/bootstrap-mgr
|
||||
- /var/lib/ceph/bootstrap-mds
|
||||
- /var/lib/ceph/bootstrap-osd
|
||||
- /var/lib/ceph/bootstrap-rbd
|
||||
- /var/lib/ceph/bootstrap-rbd-mirror
|
||||
- /var/run/ceph
|
||||
- /var/log/ceph
|
||||
@@ -0,0 +1,194 @@
|
||||
---
|
||||
- name: Include create_ceph_initial_dirs.yml
|
||||
ansible.builtin.include_tasks: create_ceph_initial_dirs.yml
|
||||
when: containerized_deployment | bool
|
||||
|
||||
- name: Include_tasks rgw_systemd_environment_file.yml
|
||||
ansible.builtin.include_tasks: rgw_systemd_environment_file.yml
|
||||
when: inventory_hostname in groups.get(rgw_group_name, [])
|
||||
|
||||
- name: Config file operations related to OSDs
|
||||
when:
|
||||
- inventory_hostname in groups.get(osd_group_name, [])
|
||||
# the rolling_update.yml playbook sets num_osds to the number of currently
|
||||
# running osds
|
||||
- not rolling_update | bool
|
||||
block:
|
||||
- name: Reset num_osds
|
||||
ansible.builtin.set_fact:
|
||||
num_osds: 0
|
||||
|
||||
- name: Count number of osds for lvm scenario
|
||||
ansible.builtin.set_fact:
|
||||
num_osds: "{{ num_osds | int + (lvm_volumes | length | int) }}"
|
||||
when: lvm_volumes | default([]) | length > 0
|
||||
|
||||
- name: Ceph-volume pre-requisites tasks
|
||||
when:
|
||||
- devices | default([]) | length > 0
|
||||
block:
|
||||
- name: Look up for ceph-volume rejected devices
|
||||
ceph_volume:
|
||||
cluster: "{{ cluster }}"
|
||||
action: "inventory"
|
||||
register: rejected_devices
|
||||
environment:
|
||||
CEPH_VOLUME_DEBUG: "{{ ceph_volume_debug }}"
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
PYTHONIOENCODING: utf-8
|
||||
|
||||
- name: Set_fact rejected_devices
|
||||
ansible.builtin.set_fact:
|
||||
_rejected_devices: "{{ _rejected_devices | default([]) + [item.path] }}"
|
||||
with_items: "{{ rejected_devices.stdout | default('{}') | from_json }}"
|
||||
when: "'Used by ceph-disk' in item.rejected_reasons"
|
||||
|
||||
- name: Set_fact _devices
|
||||
ansible.builtin.set_fact:
|
||||
_devices: "{{ devices | difference(_rejected_devices | default([])) }}"
|
||||
|
||||
- name: Run 'ceph-volume lvm batch --report' to see how many osds are to be created
|
||||
ceph_volume:
|
||||
cluster: "{{ cluster }}"
|
||||
objectstore: "{{ osd_objectstore }}"
|
||||
batch_devices: "{{ _devices }}"
|
||||
osds_per_device: "{{ osds_per_device | default(1) | int }}"
|
||||
block_db_size: "{{ block_db_size }}"
|
||||
report: true
|
||||
action: "batch"
|
||||
register: lvm_batch_report
|
||||
environment:
|
||||
CEPH_VOLUME_DEBUG: "{{ ceph_volume_debug }}"
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
PYTHONIOENCODING: utf-8
|
||||
when: _devices | default([]) | length > 0
|
||||
|
||||
- name: Set_fact num_osds from the output of 'ceph-volume lvm batch --report' (legacy report)
|
||||
ansible.builtin.set_fact:
|
||||
num_osds: "{{ num_osds | int + ((lvm_batch_report.stdout | default('{}') | from_json).osds | default([]) | length | int) + (_rejected_devices | default([]) | length | int) }}"
|
||||
when:
|
||||
- (lvm_batch_report.stdout | default('{}') | from_json) is mapping
|
||||
- (lvm_batch_report.stdout | default('{}') | from_json).changed | default(true) | bool
|
||||
|
||||
- name: Set_fact num_osds from the output of 'ceph-volume lvm batch --report' (new report)
|
||||
ansible.builtin.set_fact:
|
||||
num_osds: "{{ num_osds | int + ((lvm_batch_report.stdout | default('{}') | from_json) | default([]) | length | int) + (_rejected_devices | default([]) | length | int) }}"
|
||||
when:
|
||||
- (lvm_batch_report.stdout | default('{}') | from_json) is not mapping
|
||||
- (lvm_batch_report.stdout | default('{}') | from_json).changed | default(true) | bool
|
||||
|
||||
- name: Run 'ceph-volume lvm list' to see how many osds have already been created
|
||||
ceph_volume:
|
||||
action: "list"
|
||||
register: lvm_list
|
||||
environment:
|
||||
CEPH_VOLUME_DEBUG: "{{ ceph_volume_debug }}"
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
PYTHONIOENCODING: utf-8
|
||||
changed_when: false
|
||||
|
||||
- name: Set_fact num_osds (add existing osds)
|
||||
ansible.builtin.set_fact:
|
||||
num_osds: "{{ num_osds | int + (lvm_list.stdout | default('{}') | from_json | dict2items | map(attribute='value') | flatten | map(attribute='devices') | sum(start=[]) | difference(lvm_volumes | default([]) | map(attribute='data')) | length | int) }}"
|
||||
|
||||
- name: Set osd related config facts
|
||||
when: inventory_hostname in groups.get(osd_group_name, [])
|
||||
block:
|
||||
- name: Set_fact _osd_memory_target
|
||||
ansible.builtin.set_fact:
|
||||
_osd_memory_target: "{{ ((ansible_facts['memtotal_mb'] * 1048576 * safety_factor | float) / num_osds | float) | int }}"
|
||||
when:
|
||||
- _osd_memory_target is undefined
|
||||
- num_osds | default(0) | int > 0
|
||||
- ((ansible_facts['memtotal_mb'] * 1048576 * safety_factor | float) / num_osds | float) > (osd_memory_target | float)
|
||||
- ceph_conf_overrides.get('osd', {}).get('osd_memory_target', '') == ''
|
||||
|
||||
- name: Set osd_memory_target to cluster host config
|
||||
ceph_config:
|
||||
action: set
|
||||
who: "osd.*/{{ ansible_facts['hostname'] }}:host"
|
||||
option: "osd_memory_target"
|
||||
value: "{{ _osd_memory_target }}"
|
||||
when:
|
||||
- ceph_config_osd_memory_target | default(true)
|
||||
- _osd_memory_target is defined
|
||||
- running_mon is defined
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
delegate_to: "{{ running_mon }}"
|
||||
|
||||
- name: Set rgw configs
|
||||
when: inventory_hostname in groups.get(rgw_group_name, [])
|
||||
block:
|
||||
- name: Render rgw configs
|
||||
vars:
|
||||
_rgw_binding_socket: "{{ item.radosgw_address | default(_radosgw_address) | string + ':' + item.radosgw_frontend_port | default(radosgw_frontend_port) | string }}"
|
||||
_rgw_beast_endpoint: "{{ 'ssl_' if radosgw_frontend_ssl_certificate else '' }}endpoint={{ _rgw_binding_socket }}"
|
||||
_rgw_beast_ssl_option: "{{ ' ssl_certificate=' + radosgw_frontend_ssl_certificate if radosgw_frontend_ssl_certificate else '' }}"
|
||||
ansible.builtin.set_fact:
|
||||
_ceph_ansible_rgw_conf: >-
|
||||
{{ _ceph_ansible_rgw_conf | default({}) | combine({
|
||||
'client.rgw.' + rgw_zone + '.' + ansible_facts['hostname'] + '.' + item.instance_name: {
|
||||
'log_file': '/var/log/ceph/' + cluster + '-rgw-' + rgw_zone + '-' + ansible_facts['hostname'] + '.' + item.instance_name + '.log',
|
||||
'rgw_frontends': 'beast ' + _rgw_beast_endpoint + _rgw_beast_ssl_option,
|
||||
}
|
||||
}, recursive=true) }}
|
||||
loop: "{{ rgw_instances }}"
|
||||
|
||||
- name: Set config to cluster
|
||||
ceph_config:
|
||||
action: set
|
||||
who: "{{ item.0.key }}"
|
||||
option: "{{ item.1.key }}"
|
||||
value: "{{ item.1.value }}"
|
||||
loop: "{{ _ceph_ansible_rgw_conf | dict2dict }}"
|
||||
when:
|
||||
- rgw_conf_to_cluster | default(true) | bool
|
||||
- running_mon is defined
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
delegate_to: "{{ running_mon }}"
|
||||
|
||||
- name: Set rgw configs to file
|
||||
ansible.builtin.set_fact:
|
||||
ceph_conf_overrides: "{{ ceph_conf_overrides | default({}) | combine(_ceph_ansible_rgw_conf, recursive=true) }}"
|
||||
when: not rgw_conf_to_cluster | default(true) | bool
|
||||
|
||||
- name: Create ceph conf directory
|
||||
ansible.builtin.file:
|
||||
path: "/etc/ceph"
|
||||
state: directory
|
||||
owner: "ceph"
|
||||
group: "ceph"
|
||||
mode: "{{ ceph_directories_mode }}"
|
||||
when: not containerized_deployment | bool
|
||||
|
||||
- name: Import_role ceph-facts
|
||||
ansible.builtin.import_role:
|
||||
name: ceph-facts
|
||||
tasks_from: set_radosgw_address.yml
|
||||
when:
|
||||
- set_radosgw_address | default(true)
|
||||
- inventory_hostname in groups.get(rgw_group_name, [])
|
||||
|
||||
- name: Generate Ceph file
|
||||
openstack.config_template.config_template:
|
||||
src: "ceph.conf.j2"
|
||||
dest: "{{ ceph_conf_key_directory }}/{{ cluster }}.conf"
|
||||
owner: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
group: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
mode: "0644"
|
||||
config_overrides: "{{ ceph_conf_overrides }}"
|
||||
config_type: ini
|
||||
notify:
|
||||
- Restart ceph mons
|
||||
- Restart ceph osds
|
||||
- Restart ceph mdss
|
||||
- Restart ceph rgws
|
||||
- Restart ceph mgrs
|
||||
- Restart ceph rbdmirrors
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
- name: Create rados gateway instance directories
|
||||
ansible.builtin.file:
|
||||
path: "/var/lib/ceph/radosgw/{{ cluster }}-rgw.{{ rgw_zone }}.{{ ansible_facts['hostname'] }}.{{ item.instance_name }}"
|
||||
state: directory
|
||||
owner: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
group: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
mode: "{{ ceph_directories_mode | default('0755') }}"
|
||||
with_items: "{{ rgw_instances }}"
|
||||
|
||||
- name: Generate environment file
|
||||
ansible.builtin.copy:
|
||||
dest: "/var/lib/ceph/radosgw/{{ cluster }}-rgw.{{ rgw_zone }}.{{ ansible_facts['hostname'] }}.{{ item.instance_name }}/EnvironmentFile"
|
||||
owner: "root"
|
||||
group: "root"
|
||||
mode: "0644"
|
||||
content: |
|
||||
INST_NAME={{ item.instance_name }}
|
||||
with_items: "{{ rgw_instances }}"
|
||||
when:
|
||||
- containerized_deployment | bool
|
||||
- rgw_instances is defined
|
||||
@@ -0,0 +1,31 @@
|
||||
#jinja2: trim_blocks: "true", lstrip_blocks: "true"
|
||||
# {{ ansible_managed }}
|
||||
|
||||
[global]
|
||||
{% if not cephx | bool %}
|
||||
auth cluster required = none
|
||||
auth service required = none
|
||||
auth client required = none
|
||||
{% endif %}
|
||||
{# NOTE (leseb): the blank lines in-between are needed otherwise we won't get any line break #}
|
||||
|
||||
{% set nb_mon = groups.get(mon_group_name, []) | length | int %}
|
||||
|
||||
fsid = {{ fsid }}
|
||||
mon host = {% if nb_mon > 0 %}
|
||||
{% for name, addr in _monitor_addresses.items() -%}
|
||||
{% if mon_host_v1.enabled | bool %}
|
||||
{% set _v1 = ',v1:' + addr + mon_host_v1.suffix %}
|
||||
{% endif %}
|
||||
[{{ "v2:" + addr + mon_host_v2.suffix }}{{ _v1 | default('') }}]
|
||||
{%- if not loop.last -%},{%- endif %}
|
||||
{%- endfor %}
|
||||
{% elif nb_mon == 0 %}
|
||||
{{ external_cluster_mon_ips }}
|
||||
{% endif %}
|
||||
|
||||
{% if inventory_hostname in groups.get(client_group_name, []) %}
|
||||
[client.libvirt]
|
||||
admin socket = {{ rbd_client_admin_socket_path }}/$cluster-$type.$id.$pid.$cctid.asok # must be writable by QEMU and allowed by SELinux or AppArmor
|
||||
log file = {{ rbd_client_log_file }} # must be writable by QEMU and allowed by SELinux or AppArmor
|
||||
{% endif %}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Ansible role: ceph-container-common
|
||||
|
||||
Documentation is available at http://docs.ceph.com/ceph-ansible/.
|
||||
@@ -0,0 +1 @@
|
||||
---
|
||||
@@ -0,0 +1,5 @@
|
||||
[Unit]
|
||||
Description=ceph target allowing to start/stop all ceph*@.service instances at once
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
galaxy_info:
|
||||
company: Red Hat
|
||||
author: Sébastien Han
|
||||
description: Installs Ceph
|
||||
license: Apache
|
||||
min_ansible_version: '2.7'
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- 'all'
|
||||
galaxy_tags:
|
||||
- system
|
||||
dependencies: []
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
- name: Pulling Ceph container image
|
||||
ansible.builtin.command: "{{ timeout_command }} {{ container_binary }} pull {{ ceph_docker_registry }}/{{ ceph_docker_image }}:{{ ceph_docker_image_tag }}"
|
||||
changed_when: false
|
||||
register: docker_image
|
||||
until: docker_image.rc == 0
|
||||
retries: "{{ docker_pull_retry }}"
|
||||
delay: 10
|
||||
when: (ceph_docker_dev_image is undefined or not ceph_docker_dev_image | bool)
|
||||
environment:
|
||||
HTTP_PROXY: "{{ ceph_docker_http_proxy | default('') }}"
|
||||
HTTPS_PROXY: "{{ ceph_docker_https_proxy | default('') }}"
|
||||
NO_PROXY: "{{ ceph_docker_no_proxy }}"
|
||||
|
||||
- name: Pulling alertmanager/prometheus/grafana container images
|
||||
ansible.builtin.command: "{{ timeout_command }} {{ container_binary }} pull {{ item }}"
|
||||
changed_when: false
|
||||
register: monitoring_images
|
||||
until: monitoring_images.rc == 0
|
||||
retries: "{{ docker_pull_retry }}"
|
||||
delay: 10
|
||||
loop:
|
||||
- "{{ alertmanager_container_image }}"
|
||||
- "{{ prometheus_container_image }}"
|
||||
- "{{ grafana_container_image }}"
|
||||
when:
|
||||
- dashboard_enabled | bool
|
||||
- inventory_hostname in groups.get(monitoring_group_name, [])
|
||||
environment:
|
||||
HTTP_PROXY: "{{ ceph_docker_http_proxy | default('') }}"
|
||||
HTTPS_PROXY: "{{ ceph_docker_https_proxy | default('') }}"
|
||||
NO_PROXY: "{{ ceph_docker_no_proxy }}"
|
||||
|
||||
- name: Pulling node-exporter container image
|
||||
ansible.builtin.command: "{{ timeout_command }} {{ container_binary }} pull {{ node_exporter_container_image }}"
|
||||
changed_when: false
|
||||
register: node_exporter_image
|
||||
until: node_exporter_image.rc == 0
|
||||
retries: "{{ docker_pull_retry }}"
|
||||
delay: 10
|
||||
when:
|
||||
- dashboard_enabled | bool
|
||||
- inventory_hostname in groups.get(mon_group_name, []) or
|
||||
inventory_hostname in groups.get(osd_group_name, []) or
|
||||
inventory_hostname in groups.get(mds_group_name, []) or
|
||||
inventory_hostname in groups.get(rgw_group_name, []) or
|
||||
inventory_hostname in groups.get(mgr_group_name, []) or
|
||||
inventory_hostname in groups.get(rbdmirror_group_name, []) or
|
||||
inventory_hostname in groups.get(nfs_group_name, []) or
|
||||
inventory_hostname in groups.get(monitoring_group_name, [])
|
||||
environment:
|
||||
HTTP_PROXY: "{{ ceph_docker_http_proxy | default('') }}"
|
||||
HTTPS_PROXY: "{{ ceph_docker_https_proxy | default('') }}"
|
||||
NO_PROXY: "{{ ceph_docker_no_proxy }}"
|
||||
|
||||
- name: Export local ceph dev image
|
||||
ansible.builtin.command: >
|
||||
{{ container_binary }} save -o "/tmp/{{ ceph_docker_username }}-{{ ceph_docker_imagename }}-{{ ceph_docker_image_tag }}.tar"
|
||||
"{{ ceph_docker_username }}/{{ ceph_docker_imagename }}:{{ ceph_docker_image_tag }}"
|
||||
delegate_to: localhost
|
||||
changed_when: false
|
||||
when: (ceph_docker_dev_image is defined and ceph_docker_dev_image)
|
||||
run_once: true
|
||||
|
||||
- name: Copy ceph dev image file
|
||||
ansible.builtin.copy:
|
||||
src: "/tmp/{{ ceph_docker_username }}-{{ ceph_docker_imagename }}-{{ ceph_docker_image_tag }}.tar"
|
||||
dest: "/tmp/{{ ceph_docker_username }}-{{ ceph_docker_imagename }}-{{ ceph_docker_image_tag }}.tar"
|
||||
mode: "0644"
|
||||
when: (ceph_docker_dev_image is defined and ceph_docker_dev_image | bool)
|
||||
|
||||
- name: Load ceph dev image
|
||||
ansible.builtin.command: "{{ container_binary }} load -i /tmp/{{ ceph_docker_username }}-{{ ceph_docker_imagename }}-{{ ceph_docker_image_tag }}.tar"
|
||||
changed_when: false
|
||||
when: (ceph_docker_dev_image is defined and ceph_docker_dev_image | bool)
|
||||
|
||||
- name: Remove tmp ceph dev image file
|
||||
ansible.builtin.file:
|
||||
name: "/tmp/{{ ceph_docker_username }}-{{ ceph_docker_imagename }}-{{ ceph_docker_image_tag }}.tar"
|
||||
state: absent
|
||||
when: (ceph_docker_dev_image is defined and ceph_docker_dev_image | bool)
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
- name: Generate systemd ceph target file
|
||||
ansible.builtin.copy:
|
||||
src: ceph.target
|
||||
dest: /etc/systemd/system/ceph.target
|
||||
mode: "0644"
|
||||
|
||||
- name: Enable ceph.target
|
||||
ansible.builtin.service:
|
||||
name: ceph.target
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
|
||||
- name: Include prerequisites.yml
|
||||
ansible.builtin.include_tasks: prerequisites.yml
|
||||
|
||||
- name: Include registry.yml
|
||||
ansible.builtin.include_tasks: registry.yml
|
||||
when: ceph_docker_registry_auth | bool
|
||||
|
||||
- name: Include fetch_image.yml
|
||||
ansible.builtin.include_tasks: fetch_image.yml
|
||||
tags: fetch_container_image
|
||||
|
||||
- name: Get ceph version
|
||||
ansible.builtin.command: >
|
||||
{{ container_binary }} run --rm --net=host --entrypoint /usr/bin/ceph
|
||||
{{ ceph_client_docker_registry }}/{{ ceph_client_docker_image }}:{{ ceph_client_docker_image_tag }}
|
||||
--version
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
register: ceph_version
|
||||
|
||||
- name: Set_fact ceph_version ceph_version.stdout.split
|
||||
ansible.builtin.set_fact:
|
||||
ceph_version: "{{ ceph_version.stdout.split(' ')[2] }}"
|
||||
|
||||
- name: Include release.yml
|
||||
ansible.builtin.include_tasks: release.yml
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
- name: Lvmetad tasks related
|
||||
when:
|
||||
- inventory_hostname in groups.get(osd_group_name, [])
|
||||
- lvmetad_disabled | default(False) | bool
|
||||
- ansible_facts['os_family'] == 'RedHat'
|
||||
- ansible_facts['distribution_major_version'] | int == 7
|
||||
block:
|
||||
- name: Stop lvmetad
|
||||
ansible.builtin.service:
|
||||
name: lvm2-lvmetad
|
||||
state: stopped
|
||||
|
||||
- name: Disable and mask lvmetad service
|
||||
ansible.builtin.systemd:
|
||||
name: lvm2-lvmetad
|
||||
enabled: false
|
||||
masked: true
|
||||
|
||||
- name: Remove ceph udev rules
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
with_items:
|
||||
- /usr/lib/udev/rules.d/95-ceph-osd.rules
|
||||
- /usr/lib/udev/rules.d/60-ceph-by-parttypeuuid.rules
|
||||
|
||||
- name: Ensure tmpfiles.d is present
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/tmpfiles.d/ceph-common.conf
|
||||
line: "d /run/ceph 0755 167 167 -"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
state: present
|
||||
create: true
|
||||
|
||||
- name: Restore certificates selinux context
|
||||
when:
|
||||
- ansible_facts['os_family'] == 'RedHat'
|
||||
- inventory_hostname in groups.get(mon_group_name, [])
|
||||
or inventory_hostname in groups.get(rgw_group_name, [])
|
||||
ansible.builtin.command: /usr/sbin/restorecon -RF /etc/pki/ca-trust/extracted
|
||||
changed_when: false
|
||||
|
||||
- name: Install python3 on osd nodes
|
||||
ansible.builtin.package:
|
||||
name: python3
|
||||
state: present
|
||||
when:
|
||||
- inventory_hostname in groups.get(osd_group_name, [])
|
||||
- ansible_facts['os_family'] == 'RedHat'
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Container registry authentication
|
||||
ansible.builtin.command: '{{ container_binary }} login -u {{ ceph_docker_registry_username }} --password-stdin {{ ceph_docker_registry }}'
|
||||
args:
|
||||
stdin: '{{ ceph_docker_registry_password }}'
|
||||
stdin_add_newline: false
|
||||
changed_when: false
|
||||
environment:
|
||||
HTTP_PROXY: "{{ ceph_docker_http_proxy | default('') }}"
|
||||
HTTPS_PROXY: "{{ ceph_docker_https_proxy | default('') }}"
|
||||
NO_PROXY: "{{ ceph_docker_no_proxy }}"
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
- name: Set_fact ceph_release jewel
|
||||
ansible.builtin.set_fact:
|
||||
ceph_release: jewel
|
||||
when: ceph_version.split('.')[0] is version('10', '==')
|
||||
|
||||
- name: Set_fact ceph_release kraken
|
||||
ansible.builtin.set_fact:
|
||||
ceph_release: kraken
|
||||
when: ceph_version.split('.')[0] is version('11', '==')
|
||||
|
||||
- name: Set_fact ceph_release luminous
|
||||
ansible.builtin.set_fact:
|
||||
ceph_release: luminous
|
||||
when: ceph_version.split('.')[0] is version('12', '==')
|
||||
|
||||
- name: Set_fact ceph_release mimic
|
||||
ansible.builtin.set_fact:
|
||||
ceph_release: mimic
|
||||
when: ceph_version.split('.')[0] is version('13', '==')
|
||||
|
||||
- name: Set_fact ceph_release nautilus
|
||||
ansible.builtin.set_fact:
|
||||
ceph_release: nautilus
|
||||
when: ceph_version.split('.')[0] is version('14', '==')
|
||||
|
||||
- name: Set_fact ceph_release octopus
|
||||
ansible.builtin.set_fact:
|
||||
ceph_release: octopus
|
||||
when: ceph_version.split('.')[0] is version('15', '==')
|
||||
|
||||
- name: Set_fact ceph_release pacific
|
||||
ansible.builtin.set_fact:
|
||||
ceph_release: pacific
|
||||
when: ceph_version.split('.')[0] is version('16', '==')
|
||||
|
||||
- name: Set_fact ceph_release quincy
|
||||
ansible.builtin.set_fact:
|
||||
ceph_release: quincy
|
||||
when: ceph_version.split('.')[0] is version('17', '==')
|
||||
|
||||
- name: Set_fact ceph_release reef
|
||||
ansible.builtin.set_fact:
|
||||
ceph_release: reef
|
||||
when: ceph_version.split('.')[0] is version('18', '==')
|
||||
|
||||
- name: Set_fact ceph_release squid
|
||||
ansible.builtin.set_fact:
|
||||
ceph_release: squid
|
||||
when: ceph_version.split('.')[0] is version('19', '==')
|
||||
@@ -0,0 +1,3 @@
|
||||
# Ansible role: ceph-container-engine
|
||||
|
||||
Documentation is available at http://docs.ceph.com/ceph-ansible/.
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
galaxy_info:
|
||||
company: Red Hat
|
||||
author: Guillaume Abrioux
|
||||
description: Handles container installation prerequisites
|
||||
license: Apache
|
||||
min_ansible_version: '2.7'
|
||||
platforms:
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- xenial
|
||||
- name: EL
|
||||
versions:
|
||||
- 'all'
|
||||
galaxy_tags:
|
||||
- system
|
||||
dependencies: []
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
- name: Include pre_requisites/prerequisites.yml
|
||||
ansible.builtin.include_tasks: pre_requisites/prerequisites.yml
|
||||
when: not is_atomic | bool
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
- name: Uninstall old docker versions
|
||||
ansible.builtin.package:
|
||||
name: ['docker', 'docker-engine', 'docker.io', 'containerd', 'runc']
|
||||
state: absent
|
||||
when: container_package_name == 'docker-ce'
|
||||
|
||||
- name: Allow apt to use a repository over https (debian)
|
||||
ansible.builtin.package:
|
||||
name: ['apt-transport-https', 'ca-certificates', 'gnupg', 'software-properties-common']
|
||||
update_cache: true
|
||||
register: result
|
||||
until: result is succeeded
|
||||
|
||||
- name: Add docker's gpg key
|
||||
ansible.builtin.apt_key:
|
||||
url: "https://download.docker.com/linux/{{ ansible_facts['distribution'] | lower }}/gpg"
|
||||
register: result
|
||||
until: result is succeeded
|
||||
when: container_package_name == 'docker-ce'
|
||||
|
||||
- name: Add docker repository
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "deb https://download.docker.com/linux/{{ ansible_facts['distribution'] | lower }} {{ ansible_facts['distribution_release'] }} stable"
|
||||
when: container_package_name == 'docker-ce'
|
||||
|
||||
- name: Add podman ppa repository
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "ppa:projectatomic/ppa"
|
||||
when:
|
||||
- container_package_name == 'podman'
|
||||
- ansible_facts['distribution'] == 'Ubuntu'
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
- name: Include specific variables
|
||||
ansible.builtin.include_vars: "{{ item }}"
|
||||
with_first_found:
|
||||
- "{{ ansible_facts['distribution'] }}-{{ ansible_facts['distribution_major_version'] }}.yml"
|
||||
- "{{ ansible_facts['os_family'] }}.yml"
|
||||
when: container_package_name is undefined and container_service_name is undefined
|
||||
|
||||
- name: Debian based systems tasks
|
||||
ansible.builtin.include_tasks: debian_prerequisites.yml
|
||||
when:
|
||||
- ansible_facts['os_family'] == 'Debian'
|
||||
tags: with_pkg
|
||||
|
||||
- name: Install container packages
|
||||
ansible.builtin.package:
|
||||
name: '{{ container_package_name }}'
|
||||
update_cache: true
|
||||
register: result
|
||||
until: result is succeeded
|
||||
tags: with_pkg
|
||||
|
||||
- name: Install lvm2 package
|
||||
ansible.builtin.package:
|
||||
name: lvm2
|
||||
register: result
|
||||
until: result is succeeded
|
||||
tags: with_pkg
|
||||
when: inventory_hostname in groups.get(osd_group_name, [])
|
||||
|
||||
- name: Extra configuration for docker
|
||||
when: container_service_name == 'docker'
|
||||
block:
|
||||
- name: Create the systemd docker override directory
|
||||
ansible.builtin.file:
|
||||
path: /etc/systemd/system/docker.service.d
|
||||
state: directory
|
||||
mode: "0755"
|
||||
when: ceph_docker_http_proxy is defined or ceph_docker_https_proxy is defined
|
||||
|
||||
- name: Create the systemd docker override file
|
||||
ansible.builtin.template:
|
||||
src: docker-proxy.conf.j2
|
||||
dest: /etc/systemd/system/docker.service.d/proxy.conf
|
||||
mode: "0600"
|
||||
owner: root
|
||||
group: root
|
||||
register: proxy_created
|
||||
when: ceph_docker_http_proxy is defined or ceph_docker_https_proxy is defined
|
||||
|
||||
- name: Remove docker proxy configuration
|
||||
ansible.builtin.file:
|
||||
path: /etc/systemd/system/docker.service.d/proxy.conf
|
||||
state: absent
|
||||
register: proxy_removed
|
||||
when:
|
||||
- ceph_docker_http_proxy is not defined
|
||||
- ceph_docker_https_proxy is not defined
|
||||
|
||||
# using xxx.changed here instead of an ansible handler because we need to
|
||||
# have an immediate effect and not wait the end of the play.
|
||||
# using flush_handlers via the meta action plugin isn't enough too because
|
||||
# it flushes all handlers and not only the one notified in this role.
|
||||
- name: Restart docker
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ container_service_name }}"
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
when: proxy_created.changed | bool or proxy_removed.changed | bool
|
||||
|
||||
- name: Start container service
|
||||
ansible.builtin.service:
|
||||
name: '{{ container_service_name }}'
|
||||
state: started
|
||||
enabled: true
|
||||
tags:
|
||||
with_pkg
|
||||
@@ -0,0 +1,8 @@
|
||||
[Service]
|
||||
{% if ceph_docker_http_proxy is defined %}
|
||||
Environment="HTTP_PROXY={{ ceph_docker_http_proxy }}"
|
||||
{% endif %}
|
||||
{% if ceph_docker_https_proxy is defined %}
|
||||
Environment="HTTPS_PROXY={{ ceph_docker_https_proxy }}"
|
||||
{% endif %}
|
||||
Environment="NO_PROXY={{ ceph_docker_no_proxy }}"
|
||||
@@ -0,0 +1 @@
|
||||
RedHat-8.yml
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
container_package_name: podman
|
||||
container_service_name: podman
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
container_package_name: docker-ce
|
||||
container_service_name: docker
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
container_package_name: podman
|
||||
container_service_name: podman
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
container_package_name: docker
|
||||
container_service_name: docker
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
container_package_name: docker.io
|
||||
container_service_name: docker
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
galaxy_info:
|
||||
company: Red Hat
|
||||
author: Guillaume Abrioux
|
||||
description: Deploy ceph-crash
|
||||
license: Apache
|
||||
min_ansible_version: '2.7'
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- 'all'
|
||||
galaxy_tags:
|
||||
- system
|
||||
dependencies: []
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
- name: Create and copy client.crash keyring
|
||||
when: cephx | bool
|
||||
block:
|
||||
- name: Create client.crash keyring
|
||||
ceph_key:
|
||||
name: "client.crash"
|
||||
caps:
|
||||
mon: 'allow profile crash'
|
||||
mgr: 'allow profile crash'
|
||||
cluster: "{{ cluster }}"
|
||||
dest: "{{ ceph_conf_key_directory }}"
|
||||
import_key: true
|
||||
mode: "{{ ceph_keyring_permissions }}"
|
||||
owner: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
group: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
delegate_to: "{{ groups.get(mon_group_name, [])[0] }}"
|
||||
run_once: true
|
||||
no_log: "{{ no_log_on_ceph_key_tasks }}"
|
||||
|
||||
- name: Get keys from monitors
|
||||
ceph_key_info:
|
||||
name: client.crash
|
||||
cluster: "{{ cluster }}"
|
||||
output_format: plain
|
||||
state: info
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
register: _crash_keys
|
||||
delegate_to: "{{ groups.get(mon_group_name)[0] }}"
|
||||
run_once: true
|
||||
no_log: "{{ no_log_on_ceph_key_tasks }}"
|
||||
|
||||
- name: Copy ceph key(s) if needed
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ ceph_conf_key_directory }}/{{ cluster }}.client.crash.keyring"
|
||||
content: "{{ _crash_keys.stdout + '\n' }}"
|
||||
owner: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
group: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
mode: "{{ ceph_keyring_permissions }}"
|
||||
no_log: "{{ no_log_on_ceph_key_tasks }}"
|
||||
|
||||
- name: Start ceph-crash daemon
|
||||
when: containerized_deployment | bool
|
||||
block:
|
||||
- name: Create /var/lib/ceph/crash/posted
|
||||
ansible.builtin.file:
|
||||
path: /var/lib/ceph/crash/posted
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: "{{ ceph_uid }}"
|
||||
group: "{{ ceph_uid }}"
|
||||
|
||||
- name: Include_tasks systemd.yml
|
||||
ansible.builtin.include_tasks: systemd.yml
|
||||
|
||||
- name: Start the ceph-crash service
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ 'ceph-crash@' + ansible_facts['hostname'] if containerized_deployment | bool else 'ceph-crash.service' }}"
|
||||
state: started
|
||||
enabled: true
|
||||
masked: false
|
||||
daemon_reload: true
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
- name: Generate systemd unit file for ceph-crash container
|
||||
ansible.builtin.template:
|
||||
src: "{{ role_path }}/templates/ceph-crash.service.j2"
|
||||
dest: /etc/systemd/system/ceph-crash@.service
|
||||
owner: "root"
|
||||
group: "root"
|
||||
mode: "0644"
|
||||
notify: Restart ceph crash
|
||||
@@ -0,0 +1,52 @@
|
||||
[Unit]
|
||||
Description=Ceph crash dump collector
|
||||
{% if container_binary == 'docker' %}
|
||||
After=docker.service network-online.target local-fs.target time-sync.target
|
||||
Requires=docker.service
|
||||
{% else %}
|
||||
After=network-online.target local-fs.target time-sync.target
|
||||
{% endif %}
|
||||
Wants=network-online.target local-fs.target time-sync.target
|
||||
|
||||
[Service]
|
||||
{% if container_binary == 'podman' %}
|
||||
ExecStartPre=-/usr/bin/rm -f /%t/%n-pid /%t/%n-cid
|
||||
ExecStartPre=-/usr/bin/{{ container_binary }} rm --storage ceph-crash-%i
|
||||
{% endif %}
|
||||
ExecStartPre=-/usr/bin/{{ container_binary }} rm -f ceph-crash-%i
|
||||
ExecStart=/usr/bin/{{ container_binary }} run --rm --name ceph-crash-%i \
|
||||
{% if container_binary == 'podman' %}
|
||||
-d --log-driver journald --conmon-pidfile /%t/%n-pid --cidfile /%t/%n-cid \
|
||||
{% endif %}
|
||||
--pids-limit={{ 0 if container_binary == 'podman' else -1 }} \
|
||||
--security-opt label=disable \
|
||||
--net=host \
|
||||
{% if cluster != 'ceph' %}
|
||||
-e CEPH_ARGS="--cluster {{ cluster }}" \
|
||||
{% endif %}
|
||||
{% for v in ceph_common_container_params['volumes'] %}
|
||||
-v {{ v }} \
|
||||
{% endfor %}
|
||||
{% for k, v in ceph_common_container_params['envs'].items() %}
|
||||
-e {{ k }}={{ v }} \
|
||||
{% endfor %}
|
||||
--entrypoint=/usr/bin/ceph-crash {{ ceph_docker_registry }}/{{ ceph_docker_image }}:{{ ceph_docker_image_tag }}
|
||||
{% if container_binary == 'podman' %}
|
||||
ExecStop=-/usr/bin/sh -c "/usr/bin/{{ container_binary }} rm -f `cat /%t/%n-cid`"
|
||||
{% else %}
|
||||
ExecStop=-/usr/bin/{{ container_binary }} stop ceph-crash-%i
|
||||
{% endif %}
|
||||
StartLimitInterval=10min
|
||||
StartLimitBurst=30
|
||||
{% if container_binary == 'podman' %}
|
||||
Type=forking
|
||||
PIDFile=/%t/%n-pid
|
||||
{% endif %}
|
||||
KillMode=none
|
||||
Restart=always
|
||||
RestartSec=10s
|
||||
TimeoutStartSec=120
|
||||
TimeoutStopSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=ceph.target
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
galaxy_info:
|
||||
company: Red Hat
|
||||
author: Boris Ranto
|
||||
description: Configures Ceph Dashboard
|
||||
license: Apache
|
||||
min_ansible_version: '2.4'
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- 'all'
|
||||
galaxy_tags:
|
||||
- system
|
||||
dependencies: []
|
||||
@@ -0,0 +1,331 @@
|
||||
---
|
||||
- name: Import ceph-facts role
|
||||
ansible.builtin.import_role:
|
||||
name: ceph-facts
|
||||
tasks_from: container_binary.yml
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
delegate_facts: true
|
||||
|
||||
- name: Set_fact container_exec_cmd
|
||||
ansible.builtin.set_fact:
|
||||
container_exec_cmd: "{{ container_binary }} exec ceph-mon-{{ hostvars[groups[mon_group_name][0]]['ansible_facts']['hostname'] }}"
|
||||
when: containerized_deployment | bool
|
||||
|
||||
- name: Set_fact container_run_cmd
|
||||
ansible.builtin.set_fact:
|
||||
ceph_cmd: "{{ hostvars[groups[mon_group_name][0]]['container_binary'] + ' run --interactive --net=host --rm -v /etc/ceph:/etc/ceph:z --entrypoint=ceph ' + ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else 'ceph' }}"
|
||||
|
||||
- name: Get current mgr backend - ipv4
|
||||
ansible.builtin.set_fact:
|
||||
dashboard_server_addr: "{{ hostvars[item]['ansible_facts']['all_ipv4_addresses'] | ips_in_ranges(dashboard_network.split(',')) | first }}"
|
||||
when: ip_version == 'ipv4'
|
||||
loop: "{{ groups.get(mgr_group_name) if groups.get(mgr_group_name, []) | length > 0 else groups.get(mon_group_name) }}"
|
||||
delegate_to: "{{ item }}"
|
||||
delegate_facts: true
|
||||
|
||||
- name: Get current mgr backend - ipv6
|
||||
ansible.builtin.set_fact:
|
||||
dashboard_server_addr: "{{ hostvars[item]['ansible_facts']['all_ipv6_addresses'] | ips_in_ranges(dashboard_network.split(',')) | last }}"
|
||||
when: ip_version == 'ipv6'
|
||||
loop: "{{ groups.get(mgr_group_name) if groups.get(mgr_group_name, []) | length > 0 else groups.get(mon_group_name) }}"
|
||||
delegate_to: "{{ item }}"
|
||||
delegate_facts: true
|
||||
|
||||
- name: Include ceph-facts role
|
||||
ansible.builtin.include_role:
|
||||
name: ceph-facts
|
||||
tasks_from: set_radosgw_address.yml
|
||||
loop: "{{ groups.get(rgw_group_name, []) }}"
|
||||
run_once: true
|
||||
loop_control:
|
||||
loop_var: ceph_dashboard_call_item
|
||||
when: inventory_hostname in groups.get(rgw_group_name, [])
|
||||
|
||||
- name: Disable SSL for dashboard
|
||||
when: dashboard_protocol == "http"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
block:
|
||||
- name: Get SSL status for dashboard
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} config get mgr mgr/dashboard/ssl"
|
||||
changed_when: false
|
||||
register: current_ssl_for_dashboard
|
||||
|
||||
- name: Disable SSL for dashboard
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} config set mgr mgr/dashboard/ssl false"
|
||||
changed_when: false
|
||||
when: current_ssl_for_dashboard.stdout == "true"
|
||||
|
||||
- name: With SSL for dashboard
|
||||
when: dashboard_protocol == "https"
|
||||
block:
|
||||
- name: Enable SSL for dashboard
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} config set mgr mgr/dashboard/ssl true"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
changed_when: false
|
||||
|
||||
- name: Copy dashboard SSL certificate file
|
||||
ansible.builtin.copy:
|
||||
src: "{{ dashboard_crt }}"
|
||||
dest: "/etc/ceph/ceph-dashboard.crt"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0440"
|
||||
remote_src: "{{ dashboard_tls_external | bool }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
when: dashboard_crt | length > 0
|
||||
|
||||
- name: Copy dashboard SSL certificate key
|
||||
ansible.builtin.copy:
|
||||
src: "{{ dashboard_key }}"
|
||||
dest: "/etc/ceph/ceph-dashboard.key"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0440"
|
||||
remote_src: "{{ dashboard_tls_external | bool }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
when: dashboard_key | length > 0
|
||||
|
||||
- name: Generate and copy self-signed certificate
|
||||
when: dashboard_key | length == 0 or dashboard_crt | length == 0
|
||||
run_once: true
|
||||
block:
|
||||
- name: Set_fact subj_alt_names
|
||||
ansible.builtin.set_fact:
|
||||
subj_alt_names: >
|
||||
{% for host in groups[mgr_group_name] | default(groups[mon_group_name]) -%} DNS:{{ hostvars[host]['ansible_facts']['hostname'] }},DNS:{{ hostvars[host]['ansible_facts']['fqdn'] }},IP:{{ hostvars[host]['dashboard_server_addr'] }}{% if not loop.last %},{% endif %}{%- endfor -%}
|
||||
|
||||
- name: Create tempfile for openssl certificate and key generation
|
||||
ansible.builtin.tempfile:
|
||||
state: file
|
||||
register: openssl_config_file
|
||||
|
||||
- name: Copy the openssl configuration file
|
||||
ansible.builtin.copy:
|
||||
src: "{{ '/etc/pki/tls/openssl.cnf' if ansible_facts['os_family'] == 'RedHat' else '/etc/ssl/openssl.cnf' }}"
|
||||
dest: '{{ openssl_config_file.path }}'
|
||||
remote_src: true
|
||||
mode: "0644"
|
||||
|
||||
- name: Add subjectAltName to the openssl configuration
|
||||
community.general.ini_file:
|
||||
path: '{{ openssl_config_file.path }}'
|
||||
section: v3_ca
|
||||
option: subjectAltName
|
||||
value: '{{ subj_alt_names | trim }}'
|
||||
mode: "0644"
|
||||
|
||||
- name: Generate a Self Signed OpenSSL certificate for dashboard
|
||||
ansible.builtin.shell: |
|
||||
test -f /etc/ceph/ceph-dashboard.key -a -f /etc/ceph/ceph-dashboard.crt || \
|
||||
openssl req -new -nodes -x509 -subj '/O=IT/CN={{ dashboard_certificate_cn }}/' -config {{ openssl_config_file.path }} -days 3650 -keyout /etc/ceph/ceph-dashboard.key -out /etc/ceph/ceph-dashboard.crt -extensions v3_ca
|
||||
changed_when: false
|
||||
|
||||
- name: Remove the openssl tempfile
|
||||
ansible.builtin.file:
|
||||
path: '{{ openssl_config_file.path }}'
|
||||
state: absent
|
||||
|
||||
- name: Slurp self-signed generated certificate for dashboard
|
||||
ansible.builtin.slurp:
|
||||
src: "/etc/ceph/{{ item }}"
|
||||
run_once: true
|
||||
with_items:
|
||||
- 'ceph-dashboard.key'
|
||||
- 'ceph-dashboard.crt'
|
||||
register: slurp_self_signed_crt
|
||||
|
||||
- name: Copy self-signed generated certificate on mons
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ item.0.source }}"
|
||||
content: "{{ item.0.content | b64decode }}"
|
||||
owner: "{{ ceph_uid }}"
|
||||
group: "{{ ceph_uid }}"
|
||||
mode: "{{ '0600' if item.0.source.split('.')[-1] == 'key' else '0664' }}"
|
||||
delegate_to: "{{ item.1 }}"
|
||||
with_nested:
|
||||
- "{{ slurp_self_signed_crt.results }}"
|
||||
- "{{ groups[mon_group_name] }}"
|
||||
|
||||
- name: Import dashboard certificate file
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} config-key set mgr/dashboard/crt -i /etc/ceph/ceph-dashboard.crt"
|
||||
changed_when: false
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
|
||||
- name: Import dashboard certificate key
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} config-key set mgr/dashboard/key -i /etc/ceph/ceph-dashboard.key"
|
||||
changed_when: false
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
|
||||
- name: Set the dashboard port
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} config set mgr mgr/dashboard/server_port {{ dashboard_port }}"
|
||||
changed_when: false
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
|
||||
- name: Set the dashboard SSL port
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} config set mgr mgr/dashboard/ssl_server_port {{ dashboard_port }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
changed_when: false
|
||||
failed_when: false # Do not fail if the option does not exist, it only exists post-14.2.0
|
||||
|
||||
- name: Config the current dashboard backend
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} config set mgr mgr/dashboard/{{ hostvars[item]['ansible_facts']['hostname'] }}/server_addr {{ hostvars[item]['dashboard_server_addr'] }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
changed_when: false
|
||||
run_once: true
|
||||
with_items: '{{ groups[mgr_group_name] | default(groups[mon_group_name]) }}'
|
||||
|
||||
- name: Disable mgr dashboard module (restart)
|
||||
ceph_mgr_module:
|
||||
name: dashboard
|
||||
cluster: "{{ cluster }}"
|
||||
state: disable
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
|
||||
- name: Enable mgr dashboard module (restart)
|
||||
ceph_mgr_module:
|
||||
name: dashboard
|
||||
cluster: "{{ cluster }}"
|
||||
state: enable
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
|
||||
- name: Create dashboard admin user
|
||||
ceph_dashboard_user:
|
||||
name: "{{ dashboard_admin_user }}"
|
||||
cluster: "{{ cluster }}"
|
||||
password: "{{ dashboard_admin_password }}"
|
||||
roles: ["{{ 'read-only' if dashboard_admin_user_ro | bool else 'administrator' }}"]
|
||||
run_once: true
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
|
||||
- name: Disable unused dashboard features
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard feature disable {{ item }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
changed_when: false
|
||||
with_items: "{{ dashboard_disabled_features }}"
|
||||
|
||||
- name: Set grafana api user
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-grafana-api-username {{ grafana_admin_user }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
changed_when: false
|
||||
|
||||
- name: Set grafana api password
|
||||
ansible.builtin.command: "{{ ceph_cmd }} --cluster {{ cluster }} dashboard set-grafana-api-password -i -"
|
||||
args:
|
||||
stdin: "{{ grafana_admin_password }}"
|
||||
stdin_add_newline: false
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
changed_when: false
|
||||
|
||||
- name: Disable ssl verification for grafana
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-grafana-api-ssl-verify False"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
changed_when: false
|
||||
when:
|
||||
- dashboard_protocol == "https"
|
||||
- dashboard_grafana_api_no_ssl_verify | bool
|
||||
|
||||
- name: Set alertmanager host
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-alertmanager-api-host http://{{ grafana_server_addrs | first }}:{{ alertmanager_port }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
changed_when: false
|
||||
|
||||
- name: Set prometheus host
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-prometheus-api-host http://{{ grafana_server_addrs | first }}:{{ prometheus_port }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
changed_when: false
|
||||
|
||||
- name: Include grafana layout tasks
|
||||
ansible.builtin.include_tasks: configure_grafana_layouts.yml
|
||||
with_items: '{{ grafana_server_addrs }}'
|
||||
vars:
|
||||
grafana_server_addr: '{{ item }}'
|
||||
|
||||
- name: Config monitoring api url vip
|
||||
run_once: true
|
||||
block:
|
||||
- name: Config grafana api url vip
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-grafana-api-url {{ dashboard_protocol }}://{{ dashboard_frontend_vip }}:{{ grafana_port }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
changed_when: false
|
||||
when: dashboard_frontend_vip is defined and dashboard_frontend_vip | length > 0
|
||||
|
||||
- name: Config alertmanager api url
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-alertmanager-api-host {{ dashboard_protocol }}://{{ alertmanager_frontend_vip }}:{{ alertmanager_port }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
changed_when: false
|
||||
when: alertmanager_frontend_vip is defined and alertmanager_frontend_vip | length > 0
|
||||
|
||||
- name: Config prometheus api url
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-prometheus-api-host {{ dashboard_protocol }}://{{ prometheus_frontend_vip }}:{{ prometheus_port }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
changed_when: false
|
||||
when: prometheus_frontend_vip is defined and prometheus_frontend_vip | length > 0
|
||||
|
||||
- name: Dashboard object gateway management frontend
|
||||
when: groups.get(rgw_group_name, []) | length > 0
|
||||
run_once: true
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
block:
|
||||
- name: Set the rgw credentials
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-rgw-credentials"
|
||||
changed_when: false
|
||||
register: result
|
||||
until: result is succeeded
|
||||
retries: 5
|
||||
|
||||
- name: Set the rgw admin resource
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-rgw-api-admin-resource {{ dashboard_rgw_api_admin_resource }}"
|
||||
changed_when: false
|
||||
when: dashboard_rgw_api_admin_resource | length > 0
|
||||
|
||||
- name: Disable ssl verification for rgw
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-rgw-api-ssl-verify False"
|
||||
changed_when: false
|
||||
when:
|
||||
- dashboard_rgw_api_no_ssl_verify | bool
|
||||
- radosgw_frontend_ssl_certificate | length > 0
|
||||
|
||||
- name: Disable mgr dashboard module (restart)
|
||||
ceph_mgr_module:
|
||||
name: dashboard
|
||||
cluster: "{{ cluster }}"
|
||||
state: disable
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
|
||||
- name: Enable mgr dashboard module (restart)
|
||||
ceph_mgr_module:
|
||||
name: dashboard
|
||||
cluster: "{{ cluster }}"
|
||||
state: enable
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Set grafana url
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard set-grafana-api-url {{ dashboard_protocol }}://{{ grafana_server_fqdn | default(grafana_server_addr, true) }}:{{ grafana_port }}"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
changed_when: false
|
||||
|
||||
- name: Inject grafana dashboard layouts
|
||||
ansible.builtin.command: "{{ container_exec_cmd }} ceph --cluster {{ cluster }} dashboard grafana dashboards update"
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
run_once: true
|
||||
changed_when: false
|
||||
when: containerized_deployment | bool
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: Include configure_dashboard.yml
|
||||
ansible.builtin.include_tasks: configure_dashboard.yml
|
||||
|
||||
- name: Print dashboard URL
|
||||
ansible.builtin.debug:
|
||||
msg: "The dashboard has been deployed! You can access your dashboard web UI at {{ dashboard_protocol }}://{{ ansible_facts['fqdn'] }}:{{ dashboard_port }}/ as an '{{ dashboard_admin_user }}' user with '{{ dashboard_admin_password }}' password."
|
||||
run_once: true
|
||||
@@ -0,0 +1,3 @@
|
||||
# Ansible role: ceph-defaults
|
||||
|
||||
Documentation is available at http://docs.ceph.com/ceph-ansible/.
|
||||
@@ -0,0 +1,658 @@
|
||||
---
|
||||
# You can override vars by using host or group vars
|
||||
|
||||
###########
|
||||
# GENERAL #
|
||||
###########
|
||||
|
||||
######################################
|
||||
# Releases name to number dictionary #
|
||||
######################################
|
||||
ceph_release_num:
|
||||
dumpling: 0.67
|
||||
emperor: 0.72
|
||||
firefly: 0.80
|
||||
giant: 0.87
|
||||
hammer: 0.94
|
||||
infernalis: 9
|
||||
jewel: 10
|
||||
kraken: 11
|
||||
luminous: 12
|
||||
mimic: 13
|
||||
nautilus: 14
|
||||
octopus: 15
|
||||
pacific: 16
|
||||
quincy: 17
|
||||
reef: 18
|
||||
squid: 19
|
||||
dev: 99
|
||||
|
||||
|
||||
# The 'cluster' variable determines the name of the cluster.
|
||||
# Changing the default value to something else means that you will
|
||||
# need to change all the command line calls as well, for example if
|
||||
# your cluster name is 'foo':
|
||||
# "ceph health" will become "ceph --cluster foo health"
|
||||
#
|
||||
# An easier way to handle this is to use the environment variable CEPH_ARGS
|
||||
# So run: "export CEPH_ARGS="--cluster foo"
|
||||
# With that you will be able to run "ceph health" normally
|
||||
cluster: ceph
|
||||
|
||||
# Inventory host group variables
|
||||
mon_group_name: mons
|
||||
osd_group_name: osds
|
||||
rgw_group_name: rgws
|
||||
mds_group_name: mdss
|
||||
nfs_group_name: nfss
|
||||
rbdmirror_group_name: rbdmirrors
|
||||
client_group_name: clients
|
||||
mgr_group_name: mgrs
|
||||
rgwloadbalancer_group_name: rgwloadbalancers
|
||||
monitoring_group_name: monitoring
|
||||
adopt_label_group_names:
|
||||
- "{{ mon_group_name }}"
|
||||
- "{{ osd_group_name }}"
|
||||
- "{{ rgw_group_name }}"
|
||||
- "{{ mds_group_name }}"
|
||||
- "{{ nfs_group_name }}"
|
||||
- "{{ rbdmirror_group_name }}"
|
||||
- "{{ client_group_name }}"
|
||||
- "{{ mgr_group_name }}"
|
||||
- "{{ rgwloadbalancer_group_name }}"
|
||||
- "{{ monitoring_group_name }}"
|
||||
|
||||
# If configure_firewall is true, then ansible will try to configure the
|
||||
# appropriate firewalling rules so that Ceph daemons can communicate
|
||||
# with each others.
|
||||
configure_firewall: true
|
||||
|
||||
# Open ports on corresponding nodes if firewall is installed on it
|
||||
ceph_mon_firewall_zone: public
|
||||
ceph_mgr_firewall_zone: public
|
||||
ceph_osd_firewall_zone: public
|
||||
ceph_rgw_firewall_zone: public
|
||||
ceph_mds_firewall_zone: public
|
||||
ceph_nfs_firewall_zone: public
|
||||
ceph_rbdmirror_firewall_zone: public
|
||||
ceph_dashboard_firewall_zone: public
|
||||
ceph_rgwloadbalancer_firewall_zone: public
|
||||
|
||||
# cephadm account for remote connections
|
||||
cephadm_ssh_user: root
|
||||
cephadm_ssh_priv_key_path: "/home/{{ cephadm_ssh_user }}/.ssh/id_rsa"
|
||||
cephadm_ssh_pub_key_path: "{{ cephadm_ssh_priv_key_path }}.pub"
|
||||
cephadm_mgmt_network: "{{ public_network }}"
|
||||
|
||||
############
|
||||
# PACKAGES #
|
||||
############
|
||||
debian_package_dependencies: []
|
||||
|
||||
centos_package_dependencies:
|
||||
- epel-release
|
||||
- "{{ (ansible_facts['distribution_major_version'] is version('8', '>=')) | ternary('python3-libselinux', 'libselinux-python') }}"
|
||||
|
||||
redhat_package_dependencies: []
|
||||
|
||||
suse_package_dependencies: []
|
||||
|
||||
# Whether or not to install the ceph-test package.
|
||||
ceph_test: false
|
||||
|
||||
# Enable the ntp service by default to avoid clock skew on ceph nodes
|
||||
# Disable if an appropriate NTP client is already installed and configured
|
||||
ntp_service_enabled: true
|
||||
|
||||
# Set type of NTP client daemon to use, valid entries are chronyd, ntpd or timesyncd
|
||||
ntp_daemon_type: chronyd
|
||||
|
||||
# This variable determines if ceph packages can be updated. If False, the
|
||||
# package resources will use "state=present". If True, they will use
|
||||
# "state=latest".
|
||||
upgrade_ceph_packages: false
|
||||
|
||||
ceph_use_distro_backports: false # DEBIAN ONLY
|
||||
ceph_directories_mode: "0755"
|
||||
|
||||
###########
|
||||
# INSTALL #
|
||||
###########
|
||||
# ORIGIN SOURCE
|
||||
#
|
||||
# Choose between:
|
||||
# - 'repository' means that you will get ceph installed through a new repository. Later below choose between 'community', 'dev' or 'obs'
|
||||
# - 'distro' means that no separate repo file will be added
|
||||
# you will get whatever version of Ceph is included in your Linux distro.
|
||||
# 'local' means that the ceph binaries will be copied over from the local machine
|
||||
ceph_origin: dummy
|
||||
valid_ceph_origins:
|
||||
- repository
|
||||
- distro
|
||||
- local
|
||||
|
||||
|
||||
ceph_repository: dummy
|
||||
valid_ceph_repository:
|
||||
- community
|
||||
- dev
|
||||
- uca
|
||||
- custom
|
||||
- obs
|
||||
|
||||
|
||||
# REPOSITORY: COMMUNITY VERSION
|
||||
#
|
||||
# Enabled when ceph_repository == 'community'
|
||||
#
|
||||
ceph_mirror: https://download.ceph.com
|
||||
ceph_stable_key: https://download.ceph.com/keys/release.asc
|
||||
ceph_stable_release: squid
|
||||
ceph_stable_repo: "{{ ceph_mirror }}/debian-{{ ceph_stable_release }}"
|
||||
|
||||
nfs_ganesha_stable: true # use stable repos for nfs-ganesha
|
||||
centos_release_nfs: centos-release-nfs-ganesha4
|
||||
nfs_ganesha_stable_deb_repo: http://ppa.launchpad.net/nfs-ganesha/nfs-ganesha-4/ubuntu
|
||||
nfs_ganesha_apt_keyserver: keyserver.ubuntu.com
|
||||
nfs_ganesha_apt_key_id: EA914D611053D07BD332E18010353E8834DC57CA
|
||||
libntirpc_stable_deb_repo: http://ppa.launchpad.net/nfs-ganesha/libntirpc-4/ubuntu
|
||||
|
||||
# Use the option below to specify your applicable package tree, eg. when using non-LTS Ubuntu versions
|
||||
# # for a list of available Debian distributions, visit http://download.ceph.com/debian-{{ ceph_stable_release }}/dists/
|
||||
# for more info read: https://github.com/ceph/ceph-ansible/issues/305
|
||||
# ceph_stable_distro_source: "{{ ansible_facts['distribution_release'] }}"
|
||||
|
||||
# REPOSITORY: UBUNTU CLOUD ARCHIVE
|
||||
#
|
||||
# Enabled when ceph_repository == 'uca'
|
||||
#
|
||||
# This allows the install of Ceph from the Ubuntu Cloud Archive. The Ubuntu Cloud Archive
|
||||
# usually has newer Ceph releases than the normal distro repository.
|
||||
#
|
||||
#
|
||||
ceph_stable_repo_uca: "http://ubuntu-cloud.archive.canonical.com/ubuntu"
|
||||
ceph_stable_openstack_release_uca: queens
|
||||
ceph_stable_release_uca: "{{ ansible_facts['distribution_release'] }}-updates/{{ ceph_stable_openstack_release_uca }}"
|
||||
|
||||
# REPOSITORY: openSUSE OBS
|
||||
#
|
||||
# Enabled when ceph_repository == 'obs'
|
||||
#
|
||||
# This allows the install of Ceph from the openSUSE OBS repository. The OBS repository
|
||||
# usually has newer Ceph releases than the normal distro repository.
|
||||
#
|
||||
#
|
||||
ceph_obs_repo: "https://download.opensuse.org/repositories/filesystems:/ceph:/{{ ceph_stable_release }}/openSUSE_Leap_{{ ansible_facts['distribution_version'] }}/"
|
||||
|
||||
# REPOSITORY: DEV
|
||||
#
|
||||
# Enabled when ceph_repository == 'dev'
|
||||
#
|
||||
ceph_dev_branch: main # development branch you would like to use e.g: main, wip-hack
|
||||
ceph_dev_sha1: latest # distinct sha1 to use, defaults to 'latest' (as in latest built)
|
||||
|
||||
nfs_ganesha_dev: false # use development repos for nfs-ganesha
|
||||
|
||||
# Set this to choose the version of ceph dev libraries used in the nfs-ganesha packages from shaman
|
||||
# flavors so far include: ceph_main, ceph_jewel, ceph_kraken, ceph_luminous
|
||||
nfs_ganesha_flavor: "ceph_main"
|
||||
|
||||
|
||||
# REPOSITORY: CUSTOM
|
||||
#
|
||||
# Enabled when ceph_repository == 'custom'
|
||||
#
|
||||
# Use a custom repository to install ceph. For RPM, ceph_custom_repo should be
|
||||
# a URL to the .repo file to be installed on the targets. For deb,
|
||||
# ceph_custom_repo should be the URL to the repo base.
|
||||
#
|
||||
# ceph_custom_key: https://server.domain.com/ceph-custom-repo/key.asc
|
||||
ceph_custom_repo: https://server.domain.com/ceph-custom-repo
|
||||
|
||||
|
||||
# ORIGIN: LOCAL CEPH INSTALLATION
|
||||
#
|
||||
# Enabled when ceph_repository == 'local'
|
||||
#
|
||||
# Path to DESTDIR of the ceph install
|
||||
# ceph_installation_dir: "/path/to/ceph_installation/"
|
||||
# Whether or not to use installer script rundep_installer.sh
|
||||
# This script takes in rundep and installs the packages line by line onto the machine
|
||||
# If this is set to false then it is assumed that the machine ceph is being copied onto will already have
|
||||
# all runtime dependencies installed
|
||||
# use_installer: false
|
||||
# Root directory for ceph-ansible
|
||||
# ansible_dir: "/path/to/ceph-ansible"
|
||||
|
||||
|
||||
######################
|
||||
# CEPH CONFIGURATION #
|
||||
######################
|
||||
|
||||
## Ceph options
|
||||
#
|
||||
# Each cluster requires a unique, consistent filesystem ID. By
|
||||
# default, the playbook generates one for you.
|
||||
# If you want to customize how the fsid is
|
||||
# generated, you may find it useful to disable fsid generation to
|
||||
# avoid cluttering up your ansible repo. If you set `generate_fsid` to
|
||||
# false, you *must* generate `fsid` in another way.
|
||||
# ACTIVATE THE FSID VARIABLE FOR NON-VAGRANT DEPLOYMENT
|
||||
fsid: "{{ cluster_uuid.stdout }}"
|
||||
generate_fsid: true
|
||||
|
||||
ceph_conf_key_directory: /etc/ceph
|
||||
|
||||
ceph_uid: "{{ '64045' if not containerized_deployment | bool and ansible_facts['os_family'] == 'Debian' else '167' }}"
|
||||
|
||||
# Permissions for keyring files in /etc/ceph
|
||||
ceph_keyring_permissions: '0600'
|
||||
|
||||
cephx: true
|
||||
|
||||
# Cluster configuration
|
||||
ceph_cluster_conf:
|
||||
global:
|
||||
public_network: "{{ public_network | default(omit) }}"
|
||||
cluster_network: "{{ cluster_network | default(omit) }}"
|
||||
osd_pool_default_crush_rule: "{{ osd_pool_default_crush_rule }}"
|
||||
ms_bind_ipv6: "{{ (ip_version == 'ipv6') | string }}"
|
||||
ms_bind_ipv4: "{{ (ip_version == 'ipv4') | string }}"
|
||||
osd_crush_chooseleaf_type: "{{ '0' if common_single_host_mode | default(false) else omit }}"
|
||||
|
||||
## Client options
|
||||
#
|
||||
rbd_cache: "true"
|
||||
rbd_cache_writethrough_until_flush: "true"
|
||||
rbd_concurrent_management_ops: 20
|
||||
|
||||
rbd_client_directories: true # this will create rbd_client_log_path and rbd_client_admin_socket_path directories with proper permissions
|
||||
|
||||
# Permissions for the rbd_client_log_path and
|
||||
# rbd_client_admin_socket_path. Depending on your use case for Ceph
|
||||
# you may want to change these values. The default, which is used if
|
||||
# any of the variables are unset or set to a false value (like `null`
|
||||
# or `false`) is to automatically determine what is appropriate for
|
||||
# the Ceph version with non-OpenStack workloads -- ceph:ceph and 0770
|
||||
# for infernalis releases, and root:root and 1777 for pre-infernalis
|
||||
# releases.
|
||||
#
|
||||
# For other use cases, including running Ceph with OpenStack, you'll
|
||||
# want to set these differently:
|
||||
#
|
||||
# For OpenStack on RHEL, you'll want:
|
||||
# rbd_client_directory_owner: "qemu"
|
||||
# rbd_client_directory_group: "libvirtd" (or "libvirt", depending on your version of libvirt)
|
||||
# rbd_client_directory_mode: "0755"
|
||||
#
|
||||
# For OpenStack on Ubuntu or Debian, set:
|
||||
# rbd_client_directory_owner: "libvirt-qemu"
|
||||
# rbd_client_directory_group: "kvm"
|
||||
# rbd_client_directory_mode: "0755"
|
||||
#
|
||||
# If you set rbd_client_directory_mode, you must use a string (e.g.,
|
||||
# 'rbd_client_directory_mode: "0755"', *not*
|
||||
# 'rbd_client_directory_mode: 0755', or Ansible will complain: mode
|
||||
# must be in octal or symbolic form
|
||||
rbd_client_directory_owner: ceph
|
||||
rbd_client_directory_group: ceph
|
||||
rbd_client_directory_mode: "0755"
|
||||
|
||||
rbd_client_log_path: /var/log/ceph
|
||||
rbd_client_log_file: "{{ rbd_client_log_path }}/qemu-guest-$pid.log" # must be writable by QEMU and allowed by SELinux or AppArmor
|
||||
rbd_client_admin_socket_path: /var/run/ceph # must be writable by QEMU and allowed by SELinux or AppArmor
|
||||
|
||||
## Monitor options
|
||||
# set to either ipv4 or ipv6, whichever your network is using
|
||||
ip_version: ipv4
|
||||
|
||||
mon_host_v1:
|
||||
enabled: true
|
||||
suffix: ':6789'
|
||||
mon_host_v2:
|
||||
suffix: ':3300'
|
||||
|
||||
enable_ceph_volume_debug: false
|
||||
|
||||
##########
|
||||
# CEPHFS #
|
||||
##########
|
||||
# When pg_autoscale_mode is set to True, you must add the target_size_ratio key with a correct value
|
||||
# `pg_num` and `pgp_num` keys will be ignored, even if specified.
|
||||
# eg:
|
||||
# cephfs_data_pool:
|
||||
# name: "{{ cephfs_data if cephfs_data is defined else 'cephfs_data' }}"
|
||||
# target_size_ratio: 0.2
|
||||
cephfs: cephfs # name of the ceph filesystem
|
||||
cephfs_data_pool:
|
||||
name: "{{ cephfs_data if cephfs_data is defined else 'cephfs_data' }}"
|
||||
cephfs_metadata_pool:
|
||||
name: "{{ cephfs_metadata if cephfs_metadata is defined else 'cephfs_metadata' }}"
|
||||
cephfs_pools:
|
||||
- "{{ cephfs_data_pool }}"
|
||||
- "{{ cephfs_metadata_pool }}"
|
||||
|
||||
## OSD options
|
||||
#
|
||||
lvmetad_disabled: false
|
||||
is_hci: false
|
||||
hci_safety_factor: 0.2
|
||||
non_hci_safety_factor: 0.7
|
||||
safety_factor: "{{ hci_safety_factor if is_hci | bool else non_hci_safety_factor }}"
|
||||
osd_memory_target: 4294967296
|
||||
journal_size: 5120 # OSD journal size in MB
|
||||
block_db_size: -1 # block db size in bytes for the ceph-volume lvm batch. -1 means use the default of 'as big as possible'.
|
||||
public_network: 0.0.0.0/0
|
||||
cluster_network: "{{ public_network | regex_replace(' ', '') }}"
|
||||
osd_mkfs_type: xfs
|
||||
osd_mkfs_options_xfs: -f -i size=2048
|
||||
osd_mount_options_xfs: noatime,largeio,inode64,swalloc
|
||||
osd_objectstore: bluestore
|
||||
|
||||
# Any device containing these patterns in their path will be excluded.
|
||||
osd_auto_discovery_exclude: "dm-*|loop*|md*|rbd*"
|
||||
|
||||
## MDS options
|
||||
#
|
||||
mds_max_mds: 1
|
||||
|
||||
## Rados Gateway options
|
||||
#
|
||||
radosgw_frontend_type: beast # For additional frontends see: https://docs.ceph.com/en/latest/radosgw/frontends/
|
||||
|
||||
radosgw_frontend_port: 8080
|
||||
# The server private key, public certificate and any other CA or intermediate certificates should be in one file, in PEM format.
|
||||
radosgw_frontend_ssl_certificate: ""
|
||||
radosgw_frontend_ssl_certificate_data: "" # certificate contents to be written to path defined by radosgw_frontend_ssl_certificate
|
||||
radosgw_frontend_options: ""
|
||||
radosgw_thread_pool_size: 512
|
||||
|
||||
|
||||
# You must define either radosgw_interface, radosgw_address.
|
||||
# These variables must be defined at least in all.yml and overrided if needed (inventory host file or group_vars/*.yml).
|
||||
# Eg. If you want to specify for each radosgw node which address the radosgw will bind to you can set it in your **inventory host file** by using 'radosgw_address' variable.
|
||||
# Preference will go to radosgw_address if both radosgw_address and radosgw_interface are defined.
|
||||
radosgw_interface: interface
|
||||
radosgw_address: x.x.x.x
|
||||
radosgw_address_block: subnet
|
||||
radosgw_keystone_ssl: false # activate this when using keystone PKI keys
|
||||
radosgw_num_instances: 1
|
||||
rgw_zone: default # This is used for rgw instance client names.
|
||||
|
||||
|
||||
## Testing mode
|
||||
# enable this mode _only_ when you have a single node
|
||||
# if you don't want it keep the option commented
|
||||
# common_single_host_mode: true
|
||||
|
||||
## Handlers - restarting daemons after a config change
|
||||
# if for whatever reasons the content of your ceph configuration changes
|
||||
# ceph daemons will be restarted as well. At the moment, we can not detect
|
||||
# which config option changed so all the daemons will be restarted. Although
|
||||
# this restart will be serialized for each node, in between a health check
|
||||
# will be performed so we make sure we don't move to the next node until
|
||||
# ceph is not healthy
|
||||
# Obviously between the checks (for monitors to be in quorum and for osd's pgs
|
||||
# to be clean) we have to wait. These retries and delays can be configurable
|
||||
# for both monitors and osds.
|
||||
#
|
||||
# Monitor handler checks
|
||||
handler_health_mon_check_retries: 10
|
||||
handler_health_mon_check_delay: 20
|
||||
#
|
||||
# OSD handler checks
|
||||
handler_health_osd_check_retries: 40
|
||||
handler_health_osd_check_delay: 30
|
||||
handler_health_osd_check: true
|
||||
#
|
||||
# MDS handler checks
|
||||
handler_health_mds_check_retries: 5
|
||||
handler_health_mds_check_delay: 10
|
||||
#
|
||||
# RGW handler checks
|
||||
handler_health_rgw_check_retries: 5
|
||||
handler_health_rgw_check_delay: 10
|
||||
handler_rgw_use_haproxy_maintenance: false
|
||||
|
||||
# NFS handler checks
|
||||
handler_health_nfs_check_retries: 5
|
||||
handler_health_nfs_check_delay: 10
|
||||
|
||||
# RBD MIRROR handler checks
|
||||
handler_health_rbd_mirror_check_retries: 5
|
||||
handler_health_rbd_mirror_check_delay: 10
|
||||
|
||||
# MGR handler checks
|
||||
handler_health_mgr_check_retries: 5
|
||||
handler_health_mgr_check_delay: 10
|
||||
|
||||
## health mon/osds check retries/delay:
|
||||
|
||||
health_mon_check_retries: 20
|
||||
health_mon_check_delay: 10
|
||||
health_osd_check_retries: 20
|
||||
health_osd_check_delay: 10
|
||||
|
||||
##############
|
||||
# RBD-MIRROR #
|
||||
##############
|
||||
|
||||
ceph_rbd_mirror_pool: "rbd"
|
||||
|
||||
###############
|
||||
# NFS-GANESHA #
|
||||
###############
|
||||
#
|
||||
# Access type options
|
||||
#
|
||||
# Enable NFS File access
|
||||
# If set to true, then ganesha is set up to export the root of the
|
||||
# Ceph filesystem, and ganesha's attribute and directory caching is disabled
|
||||
# as much as possible since libcephfs clients also caches the same
|
||||
# information.
|
||||
#
|
||||
# Set this to true to enable File access via NFS. Requires an MDS role.
|
||||
nfs_file_gw: false
|
||||
# Set this to true to enable Object access via NFS. Requires an RGW role.
|
||||
nfs_obj_gw: "{{ False if groups.get(mon_group_name, []) | length == 0 else True }}"
|
||||
|
||||
|
||||
###################
|
||||
# CONFIG OVERRIDE #
|
||||
###################
|
||||
|
||||
# Ceph configuration file override.
|
||||
# This allows you to specify more configuration options
|
||||
# using an INI style format.
|
||||
#
|
||||
# When configuring RGWs, make sure you use the form [client.rgw.*]
|
||||
# instead of [client.radosgw.*].
|
||||
# For more examples check the profiles directory of https://github.com/ceph/ceph-ansible.
|
||||
#
|
||||
# The following sections are supported: [global], [mon], [osd], [mds], [client]
|
||||
#
|
||||
# Example:
|
||||
# ceph_conf_overrides:
|
||||
# global:
|
||||
# foo: 1234
|
||||
# bar: 5678
|
||||
# "client.rgw.{{ rgw_zone }}.{{ hostvars[groups.get(rgw_group_name)[0]]['ansible_facts']['hostname'] }}":
|
||||
# rgw_zone: zone1
|
||||
#
|
||||
ceph_conf_overrides: {}
|
||||
|
||||
|
||||
#############
|
||||
# OS TUNING #
|
||||
#############
|
||||
|
||||
disable_transparent_hugepage: "{{ false if osd_objectstore == 'bluestore' }}"
|
||||
os_tuning_params:
|
||||
- { name: fs.file-max, value: 26234859 }
|
||||
- { name: vm.zone_reclaim_mode, value: 0 }
|
||||
- { name: vm.swappiness, value: 10 }
|
||||
- { name: vm.min_free_kbytes, value: "{{ vm_min_free_kbytes }}" }
|
||||
|
||||
# For Debian & Red Hat/CentOS installs set TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES
|
||||
# Set this to a byte value (e.g. 134217728)
|
||||
# A value of 0 will leave the package default.
|
||||
ceph_tcmalloc_max_total_thread_cache: 134217728
|
||||
|
||||
|
||||
##########
|
||||
# DOCKER #
|
||||
##########
|
||||
ceph_docker_image: "ceph/ceph"
|
||||
ceph_docker_image_tag: v19
|
||||
ceph_docker_registry: quay.io
|
||||
ceph_docker_registry_auth: false
|
||||
# ceph_docker_registry_username:
|
||||
# ceph_docker_registry_password:
|
||||
# ceph_docker_http_proxy:
|
||||
# ceph_docker_https_proxy:
|
||||
ceph_docker_no_proxy: "localhost,127.0.0.1"
|
||||
## Client only docker image - defaults to {{ ceph_docker_image }}
|
||||
ceph_client_docker_image: "{{ ceph_docker_image }}"
|
||||
ceph_client_docker_image_tag: "{{ ceph_docker_image_tag }}"
|
||||
ceph_client_docker_registry: "{{ ceph_docker_registry }}"
|
||||
containerized_deployment: false
|
||||
container_binary:
|
||||
timeout_command: "{{ 'timeout --foreground -s KILL ' ~ docker_pull_timeout if (docker_pull_timeout != '0') and (ceph_docker_dev_image is undefined or not ceph_docker_dev_image) else '' }}"
|
||||
ceph_common_container_params:
|
||||
envs:
|
||||
NODE_NAME: "{{ ansible_facts['hostname'] }}"
|
||||
CONTAINER_IMAGE: "{{ ceph_docker_registry }}/{{ ceph_docker_image }}:{{ ceph_docker_image_tag }}"
|
||||
TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES: "{{ ceph_tcmalloc_max_total_thread_cache }}"
|
||||
args:
|
||||
- --setuser=ceph
|
||||
- --setgroup=ceph
|
||||
- --default-log-to-file=false
|
||||
- --default-log-to-stderr=true
|
||||
- --default-log-stderr-prefix="debug "
|
||||
volumes:
|
||||
- /var/lib/ceph/crash:/var/lib/ceph/crash:z
|
||||
- /var/run/ceph:/var/run/ceph:z
|
||||
- /var/log/ceph:/var/log/ceph:z
|
||||
- /etc/ceph:/etc/ceph:z
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
|
||||
# this is only here for usage with the rolling_update.yml playbook
|
||||
# do not ever change this here
|
||||
rolling_update: false
|
||||
|
||||
#####################
|
||||
# Docker pull retry #
|
||||
#####################
|
||||
docker_pull_retry: 3
|
||||
docker_pull_timeout: "300s"
|
||||
|
||||
|
||||
#############
|
||||
# DASHBOARD #
|
||||
#############
|
||||
dashboard_enabled: true
|
||||
# Choose http or https
|
||||
# For https, you should set dashboard.crt/key and grafana.crt/key
|
||||
# If you define the dashboard_crt and dashboard_key variables, but leave them as '',
|
||||
# then we will autogenerate a cert and keyfile
|
||||
dashboard_protocol: https
|
||||
dashboard_port: 8443
|
||||
# set this variable to the network you want the dashboard to listen on. (Default to public_network)
|
||||
dashboard_network: "{{ public_network }}"
|
||||
dashboard_admin_user: admin
|
||||
dashboard_admin_user_ro: false
|
||||
# This variable must be set with a strong custom password when dashboard_enabled is True
|
||||
# dashboard_admin_password: p@ssw0rd
|
||||
# We only need this for SSL (https) connections
|
||||
dashboard_crt: ''
|
||||
dashboard_key: ''
|
||||
dashboard_certificate_cn: ceph-dashboard
|
||||
dashboard_tls_external: false
|
||||
dashboard_grafana_api_no_ssl_verify: "{{ true if dashboard_protocol == 'https' and not grafana_crt and not grafana_key else false }}"
|
||||
dashboard_rgw_api_user_id: ceph-dashboard
|
||||
dashboard_rgw_api_admin_resource: ''
|
||||
dashboard_rgw_api_no_ssl_verify: false
|
||||
dashboard_frontend_vip: ''
|
||||
dashboard_disabled_features: []
|
||||
prometheus_frontend_vip: ''
|
||||
alertmanager_frontend_vip: ''
|
||||
node_exporter_container_image: "docker.io/prom/node-exporter:v0.17.0"
|
||||
node_exporter_port: 9100
|
||||
grafana_admin_user: admin
|
||||
# This variable must be set with a strong custom password when dashboard_enabled is True
|
||||
# grafana_admin_password: admin
|
||||
# We only need this for SSL (https) connections
|
||||
grafana_crt: ''
|
||||
grafana_key: ''
|
||||
# When using https, please fill with a hostname for which grafana_crt is valid.
|
||||
grafana_server_fqdn: ''
|
||||
grafana_container_image: "docker.io/grafana/grafana:6.7.4"
|
||||
grafana_container_cpu_period: 100000
|
||||
grafana_container_cpu_cores: 2
|
||||
# container_memory is in GB
|
||||
grafana_container_memory: 4
|
||||
grafana_uid: 472
|
||||
grafana_datasource: Dashboard
|
||||
grafana_dashboards_path: "/etc/grafana/dashboards/ceph-dashboard"
|
||||
grafana_dashboard_version: main
|
||||
grafana_dashboard_files:
|
||||
- ceph-cluster.json
|
||||
- cephfs-overview.json
|
||||
- host-details.json
|
||||
- hosts-overview.json
|
||||
- osd-device-details.json
|
||||
- osds-overview.json
|
||||
- pool-detail.json
|
||||
- pool-overview.json
|
||||
- radosgw-detail.json
|
||||
- radosgw-overview.json
|
||||
- radosgw-sync-overview.json
|
||||
- rbd-details.json
|
||||
- rbd-overview.json
|
||||
grafana_plugins:
|
||||
- vonage-status-panel
|
||||
- grafana-piechart-panel
|
||||
grafana_allow_embedding: true
|
||||
grafana_port: 3000
|
||||
grafana_network: "{{ public_network }}"
|
||||
grafana_conf_overrides: {}
|
||||
prometheus_container_image: "docker.io/prom/prometheus:v2.7.2"
|
||||
prometheus_container_cpu_period: 100000
|
||||
prometheus_container_cpu_cores: 2
|
||||
# container_memory is in GB
|
||||
prometheus_container_memory: 4
|
||||
prometheus_data_dir: /var/lib/prometheus
|
||||
prometheus_conf_dir: /etc/prometheus
|
||||
prometheus_user_id: '65534' # This is the UID used by the prom/prometheus container image
|
||||
prometheus_port: 9092
|
||||
prometheus_conf_overrides: {}
|
||||
# Uncomment out this variable if you need to customize the retention period for prometheus storage.
|
||||
# set it to '30d' if you want to retain 30 days of data.
|
||||
# prometheus_storage_tsdb_retention_time: 15d
|
||||
alertmanager_container_image: "docker.io/prom/alertmanager:v0.16.2"
|
||||
alertmanager_container_cpu_period: 100000
|
||||
alertmanager_container_cpu_cores: 2
|
||||
# container_memory is in GB
|
||||
alertmanager_container_memory: 4
|
||||
alertmanager_data_dir: /var/lib/alertmanager
|
||||
alertmanager_conf_dir: /etc/alertmanager
|
||||
alertmanager_port: 9093
|
||||
alertmanager_cluster_port: 9094
|
||||
alertmanager_conf_overrides: {}
|
||||
alertmanager_dashboard_api_no_ssl_verify: "{{ true if dashboard_protocol == 'https' and not dashboard_crt and not dashboard_key else false }}"
|
||||
|
||||
no_log_on_ceph_key_tasks: true
|
||||
|
||||
###############
|
||||
# DEPRECATION #
|
||||
###############
|
||||
|
||||
|
||||
######################################################
|
||||
# VARIABLES BELOW SHOULD NOT BE MODIFIED BY THE USER #
|
||||
# *DO NOT* MODIFY THEM #
|
||||
######################################################
|
||||
|
||||
container_exec_cmd:
|
||||
docker: false
|
||||
ceph_volume_debug: "{{ enable_ceph_volume_debug | ternary(1, 0) }}"
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
galaxy_info:
|
||||
company: Red Hat
|
||||
author: Sébastien Han
|
||||
description: Handles ceph-ansible default vars for all roles
|
||||
license: Apache
|
||||
min_ansible_version: '2.7'
|
||||
platforms:
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- xenial
|
||||
- name: EL
|
||||
versions:
|
||||
- 'all'
|
||||
galaxy_tags:
|
||||
- system
|
||||
dependencies: []
|
||||
@@ -0,0 +1 @@
|
||||
---
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
ceph_osd_pool_default_crush_rule: -1
|
||||
ceph_osd_pool_default_crush_rule_name: "replicated_rule"
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
###########
|
||||
# GENERAL #
|
||||
###########
|
||||
|
||||
ceph_exporter_addr: "0.0.0.0"
|
||||
ceph_exporter_port: 9926
|
||||
ceph_exporter_stats_period: 5 # seconds
|
||||
ceph_exporter_prio_limit: 5
|
||||
|
||||
##########
|
||||
# DOCKER #
|
||||
##########
|
||||
|
||||
# If you want to add parameters, you should retain the existing ones and include the new ones.
|
||||
ceph_exporter_container_params:
|
||||
args:
|
||||
- -f
|
||||
- -n=client.ceph-exporter
|
||||
- --sock-dir=/var/run/ceph
|
||||
- --addrs={{ ceph_exporter_addr }}
|
||||
- --port={{ ceph_exporter_port }}
|
||||
- --stats-period={{ ceph_exporter_stats_period }}
|
||||
- --prio-limit={{ ceph_exporter_prio_limit }}
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
galaxy_info:
|
||||
company: Red Hat
|
||||
author: Guillaume Abrioux
|
||||
description: Deploy ceph-exporter
|
||||
license: Apache
|
||||
min_ansible_version: '2.7'
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- 'all'
|
||||
galaxy_tags:
|
||||
- system
|
||||
dependencies: []
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
- name: Create and copy client.ceph-exporter keyring
|
||||
when: cephx | bool
|
||||
block:
|
||||
- name: Create client.ceph-exporter keyring
|
||||
ceph_key:
|
||||
name: "client.ceph-exporter"
|
||||
caps:
|
||||
mon: 'allow r'
|
||||
mgr: 'allow r'
|
||||
osd: 'allow r'
|
||||
cluster: "{{ cluster }}"
|
||||
dest: "{{ ceph_conf_key_directory }}"
|
||||
import_key: true
|
||||
mode: "{{ ceph_keyring_permissions }}"
|
||||
owner: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
group: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
delegate_to: "{{ groups.get(mon_group_name, [])[0] }}"
|
||||
run_once: true
|
||||
no_log: "{{ no_log_on_ceph_key_tasks }}"
|
||||
|
||||
- name: Get keys from monitors
|
||||
ceph_key_info:
|
||||
name: client.ceph-exporter
|
||||
cluster: "{{ cluster }}"
|
||||
output_format: plain
|
||||
state: info
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
register: _exporter_keys
|
||||
delegate_to: "{{ groups.get(mon_group_name)[0] }}"
|
||||
run_once: true
|
||||
no_log: "{{ no_log_on_ceph_key_tasks }}"
|
||||
|
||||
- name: Copy ceph key(s) if needed
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ ceph_conf_key_directory }}/{{ cluster }}.client.ceph-exporter.keyring"
|
||||
content: "{{ _exporter_keys.stdout + '\n' }}"
|
||||
owner: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
group: "{{ ceph_uid if containerized_deployment | bool else 'ceph' }}"
|
||||
mode: "{{ ceph_keyring_permissions }}"
|
||||
no_log: "{{ no_log_on_ceph_key_tasks }}"
|
||||
|
||||
- name: Include_tasks systemd.yml
|
||||
ansible.builtin.include_tasks: systemd.yml
|
||||
when: containerized_deployment | bool
|
||||
|
||||
- name: Start the ceph-exporter service
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ 'ceph-exporter@' + ansible_facts['hostname'] if containerized_deployment | bool else 'ceph-exporter.service' }}"
|
||||
state: started
|
||||
enabled: true
|
||||
masked: false
|
||||
daemon_reload: true
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
- name: Generate systemd unit file for ceph-exporter container
|
||||
ansible.builtin.template:
|
||||
src: "{{ role_path }}/templates/ceph-exporter.service.j2"
|
||||
dest: /etc/systemd/system/ceph-exporter@.service
|
||||
owner: "root"
|
||||
group: "root"
|
||||
mode: "0644"
|
||||
notify: Restart ceph exporter
|
||||
@@ -0,0 +1,50 @@
|
||||
[Unit]
|
||||
Description=Ceph exporter
|
||||
{% if container_binary == 'docker' %}
|
||||
After=docker.service network-online.target local-fs.target time-sync.target
|
||||
Requires=docker.service
|
||||
{% else %}
|
||||
After=network-online.target local-fs.target time-sync.target
|
||||
{% endif %}
|
||||
Wants=network-online.target local-fs.target time-sync.target
|
||||
|
||||
[Service]
|
||||
{% if container_binary == 'podman' %}
|
||||
ExecStartPre=-/usr/bin/rm -f /%t/%n-pid /%t/%n-cid
|
||||
ExecStartPre=-/usr/bin/{{ container_binary }} rm --storage ceph-exporter-%i
|
||||
{% endif %}
|
||||
ExecStartPre=-/usr/bin/{{ container_binary }} rm -f ceph-exporter-%i
|
||||
ExecStart=/usr/bin/{{ container_binary }} run --rm --name ceph-exporter-%i \
|
||||
{% if container_binary == 'podman' %}
|
||||
-d --log-driver journald --conmon-pidfile /%t/%n-pid --cidfile /%t/%n-cid \
|
||||
{% endif %}
|
||||
--pids-limit={{ 0 if container_binary == 'podman' else -1 }} \
|
||||
--security-opt label=disable \
|
||||
--net=host \
|
||||
{% for v in ceph_common_container_params['volumes'] + ceph_exporter_container_params['volumes'] | default([]) %}
|
||||
-v {{ v }} \
|
||||
{% endfor %}
|
||||
{% for k, v in (ceph_common_container_params['envs'] | combine(ceph_exporter_container_params['envs'] | default({}))).items() %}
|
||||
-e {{ k }}={{ v }} \
|
||||
{% endfor %}
|
||||
--entrypoint=/usr/bin/ceph-exporter {{ ceph_docker_registry }}/{{ ceph_docker_image }}:{{ ceph_docker_image_tag }} \
|
||||
{{ (ceph_common_container_params['args'] + ceph_exporter_container_params['args'] | default([])) | join(' ') }}
|
||||
{% if container_binary == 'podman' %}
|
||||
ExecStop=-/usr/bin/sh -c "/usr/bin/{{ container_binary }} rm -f `cat /%t/%n-cid`"
|
||||
{% else %}
|
||||
ExecStop=-/usr/bin/{{ container_binary }} stop ceph-exporter-%i
|
||||
{% endif %}
|
||||
StartLimitInterval=10min
|
||||
StartLimitBurst=30
|
||||
{% if container_binary == 'podman' %}
|
||||
Type=forking
|
||||
PIDFile=/%t/%n-pid
|
||||
{% endif %}
|
||||
KillMode=none
|
||||
Restart=always
|
||||
RestartSec=10s
|
||||
TimeoutStartSec=120
|
||||
TimeoutStopSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=ceph.target
|
||||
@@ -0,0 +1,3 @@
|
||||
# Ansible role: ceph-facts
|
||||
|
||||
Documentation is available at http://docs.ceph.com/ceph-ansible/.
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
galaxy_info:
|
||||
company: Red Hat
|
||||
author: Guillaume Abrioux
|
||||
description: Set some facts for ceph to be deployed
|
||||
license: Apache
|
||||
min_ansible_version: '2.7'
|
||||
platforms:
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- xenial
|
||||
- name: EL
|
||||
versions:
|
||||
- 'all'
|
||||
galaxy_tags:
|
||||
- system
|
||||
dependencies: []
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: Check if podman binary is present
|
||||
ansible.builtin.stat:
|
||||
path: /usr/bin/podman
|
||||
register: podman_binary
|
||||
|
||||
- name: Set_fact container_binary
|
||||
ansible.builtin.set_fact:
|
||||
container_binary: "{{ 'podman' if (podman_binary.stat.exists and ansible_facts['distribution'] == 'Fedora') or (ansible_facts['os_family'] == 'RedHat' and ansible_facts['distribution_major_version'] in ['8', '9']) else 'docker' }}"
|
||||
when: not docker2podman | default(false) | bool
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
- name: Resolve devices
|
||||
when:
|
||||
- devices is defined
|
||||
- not osd_auto_discovery | default(False) | bool
|
||||
block:
|
||||
- name: Resolve device link(s)
|
||||
ansible.builtin.command: readlink -f {{ item }}
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
with_items: "{{ devices }}"
|
||||
register: devices_prepare_canonicalize
|
||||
|
||||
- name: Set_fact build devices from resolved symlinks
|
||||
ansible.builtin.set_fact:
|
||||
devices: "{{ devices_prepare_canonicalize.results | map(attribute='stdout') | reject('search', '/dev/disk') | list | unique }}"
|
||||
|
||||
- name: Resolve dedicated_device
|
||||
when:
|
||||
- dedicated_devices is defined
|
||||
- not osd_auto_discovery | default(False) | bool
|
||||
block:
|
||||
- name: Resolve dedicated_device link(s)
|
||||
ansible.builtin.command: readlink -f {{ item }}
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
with_items: "{{ dedicated_devices }}"
|
||||
register: dedicated_devices_prepare_canonicalize
|
||||
|
||||
- name: Set_fact build dedicated_devices from resolved symlinks
|
||||
ansible.builtin.set_fact:
|
||||
dedicated_devices: "{{ dedicated_devices_prepare_canonicalize.results | map(attribute='stdout') | reject('search', '/dev/disk') | list | unique }}"
|
||||
|
||||
- name: Resolve bluestore_wal_device
|
||||
when:
|
||||
- bluestore_wal_devices is defined
|
||||
- not osd_auto_discovery | default(False) | bool
|
||||
block:
|
||||
- name: Resolve bluestore_wal_device link(s)
|
||||
ansible.builtin.command: readlink -f {{ item }}
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
with_items: "{{ bluestore_wal_devices }}"
|
||||
register: bluestore_wal_devices_prepare_canonicalize
|
||||
|
||||
- name: Set_fact build bluestore_wal_devices from resolved symlinks
|
||||
ansible.builtin.set_fact:
|
||||
bluestore_wal_devices: "{{ bluestore_wal_devices_prepare_canonicalize.results | map(attribute='stdout') | reject('search', '/dev/disk') | list | unique }}"
|
||||
|
||||
- name: Collect existed devices
|
||||
vars:
|
||||
device: "{{ item.key | regex_replace('^', '/dev/') }}"
|
||||
ansible.builtin.command: test -b {{ device }}
|
||||
changed_when: false
|
||||
ignore_errors: true
|
||||
loop: "{{ ansible_facts['devices'] | dict2items }}"
|
||||
when:
|
||||
- osd_auto_discovery | default(False) | bool
|
||||
- ansible_facts['devices'] is defined
|
||||
- item.value.removable == "0"
|
||||
- item.value.sectors != "0"
|
||||
- item.value.partitions|count == 0
|
||||
- item.value.holders|count == 0
|
||||
- ansible_facts['mounts'] | selectattr('device', 'equalto', device) | list | length == 0
|
||||
- item.key is not match osd_auto_discovery_exclude
|
||||
- device not in dedicated_devices | default([])
|
||||
- device not in bluestore_wal_devices | default([])
|
||||
- device not in (lvm_volumes | default([]) | map(attribute='data') | list)
|
||||
register: devices_check
|
||||
|
||||
- name: Set_fact devices generate device list when osd_auto_discovery
|
||||
vars:
|
||||
device: "{{ item.item.key | regex_replace('^', '/dev/') }}"
|
||||
ansible.builtin.set_fact:
|
||||
devices: "{{ devices | default([]) | union([device]) }}"
|
||||
loop: "{{ devices_check.results }}"
|
||||
when:
|
||||
- devices_check is defined
|
||||
- devices_check is not skipped
|
||||
- not item.skipped | default(false)
|
||||
- not item.failed | default(false)
|
||||
@@ -0,0 +1,250 @@
|
||||
---
|
||||
- name: Check if it is atomic host
|
||||
ansible.builtin.stat:
|
||||
path: /run/ostree-booted
|
||||
register: stat_ostree
|
||||
|
||||
- name: Set_fact is_atomic
|
||||
ansible.builtin.set_fact:
|
||||
is_atomic: "{{ stat_ostree.stat.exists }}"
|
||||
|
||||
- name: Import_tasks container_binary.yml
|
||||
ansible.builtin.import_tasks: container_binary.yml
|
||||
|
||||
- name: Set_fact ceph_cmd
|
||||
ansible.builtin.set_fact:
|
||||
ceph_cmd: "{{ container_binary + ' run --rm --net=host -v /etc/ceph:/etc/ceph:z -v /var/lib/ceph:/var/lib/ceph:z -v /var/run/ceph:/var/run/ceph:z --entrypoint=ceph ' + ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else 'ceph' }}"
|
||||
|
||||
# In case ansible_python_interpreter is set by the user,
|
||||
# ansible will not discover python and discovered_interpreter_python
|
||||
# will not be set
|
||||
- name: Set_fact discovered_interpreter_python
|
||||
ansible.builtin.set_fact:
|
||||
discovered_interpreter_python: "{{ ansible_python_interpreter }}"
|
||||
when: ansible_python_interpreter is defined
|
||||
|
||||
# If ansible_python_interpreter is not defined, this can result in the
|
||||
# discovered_interpreter_python fact from being set. This fails later in this
|
||||
# playbook and is used elsewhere.
|
||||
- name: Set_fact discovered_interpreter_python if not previously set
|
||||
ansible.builtin.set_fact:
|
||||
discovered_interpreter_python: "{{ ansible_facts['discovered_interpreter_python'] }}"
|
||||
when:
|
||||
- discovered_interpreter_python is not defined
|
||||
- ansible_facts['discovered_interpreter_python'] is defined
|
||||
|
||||
# Set ceph_release to ceph_stable by default
|
||||
- name: Set_fact ceph_release ceph_stable_release
|
||||
ansible.builtin.set_fact:
|
||||
ceph_release: "{{ ceph_stable_release }}"
|
||||
|
||||
- name: Set_fact monitor_name ansible_facts['hostname']
|
||||
ansible.builtin.set_fact:
|
||||
monitor_name: "{{ hostvars[item]['ansible_facts']['hostname'] }}"
|
||||
delegate_to: "{{ item }}"
|
||||
delegate_facts: true
|
||||
with_items: "{{ groups.get(mon_group_name, []) }}"
|
||||
run_once: true
|
||||
when: groups.get(mon_group_name, []) | length > 0
|
||||
|
||||
- name: Find a running monitor
|
||||
when: groups.get(mon_group_name, []) | length > 0
|
||||
block:
|
||||
- name: Set_fact container_exec_cmd
|
||||
ansible.builtin.set_fact:
|
||||
container_exec_cmd: "{{ container_binary }} exec ceph-mon-{{ hostvars[groups[mon_group_name][0]]['ansible_facts']['hostname'] if not rolling_update | bool else hostvars[mon_host | default(groups[mon_group_name][0])]['ansible_facts']['hostname'] }}"
|
||||
when:
|
||||
- containerized_deployment | bool
|
||||
|
||||
- name: Find a running mon container
|
||||
ansible.builtin.command: "{{ container_binary }} ps -q --filter name=ceph-mon-{{ hostvars[item]['ansible_facts']['hostname'] }}"
|
||||
register: find_running_mon_container
|
||||
failed_when: false
|
||||
run_once: true
|
||||
delegate_to: "{{ item }}"
|
||||
with_items: "{{ groups.get(mon_group_name, []) }}"
|
||||
changed_when: false
|
||||
when:
|
||||
- containerized_deployment | bool
|
||||
|
||||
- name: Check for a ceph mon socket
|
||||
ansible.builtin.shell: stat --printf=%n {{ rbd_client_admin_socket_path }}/{{ cluster }}-mon*.asok
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
check_mode: false
|
||||
register: mon_socket_stat
|
||||
run_once: true
|
||||
delegate_to: "{{ item }}"
|
||||
with_items: "{{ groups.get(mon_group_name, []) }}"
|
||||
when:
|
||||
- not containerized_deployment | bool
|
||||
|
||||
- name: Check if the ceph mon socket is in-use
|
||||
ansible.builtin.command: grep -q {{ item.stdout }} /proc/net/unix
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
check_mode: false
|
||||
register: mon_socket
|
||||
run_once: true
|
||||
delegate_to: "{{ hostvars[item.item]['inventory_hostname'] }}"
|
||||
with_items: "{{ mon_socket_stat.results }}"
|
||||
when:
|
||||
- not containerized_deployment | bool
|
||||
- item.rc == 0
|
||||
|
||||
- name: Set_fact running_mon - non_container
|
||||
ansible.builtin.set_fact:
|
||||
running_mon: "{{ hostvars[item.item.item]['inventory_hostname'] }}"
|
||||
with_items: "{{ mon_socket.results }}"
|
||||
run_once: true
|
||||
when:
|
||||
- not containerized_deployment | bool
|
||||
- item.rc is defined
|
||||
- item.rc == 0
|
||||
|
||||
- name: Set_fact running_mon - container
|
||||
ansible.builtin.set_fact:
|
||||
running_mon: "{{ item.item }}"
|
||||
run_once: true
|
||||
with_items: "{{ find_running_mon_container.results }}"
|
||||
when:
|
||||
- containerized_deployment | bool
|
||||
- item.stdout_lines | default([]) | length > 0
|
||||
|
||||
- name: Set_fact _container_exec_cmd
|
||||
ansible.builtin.set_fact:
|
||||
_container_exec_cmd: "{{ container_binary }} exec ceph-mon-{{ hostvars[groups[mon_group_name][0] if running_mon is undefined else running_mon]['ansible_facts']['hostname'] }}"
|
||||
when:
|
||||
- containerized_deployment | bool
|
||||
|
||||
# this task shouldn't run in a rolling_update situation
|
||||
# because it blindly picks a mon, which may be down because
|
||||
# of the rolling update
|
||||
- name: Get current fsid if cluster is already running
|
||||
ansible.builtin.command: "{{ timeout_command }} {{ _container_exec_cmd | default('') }} ceph --cluster {{ cluster }} fsid"
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
check_mode: false
|
||||
register: current_fsid
|
||||
run_once: true
|
||||
delegate_to: "{{ groups[mon_group_name][0] if running_mon is undefined else running_mon }}"
|
||||
when:
|
||||
- not rolling_update | bool
|
||||
|
||||
# set this as a default when performing a rolling_update
|
||||
# so the rest of the tasks here will succeed
|
||||
- name: Set_fact current_fsid rc 1
|
||||
ansible.builtin.set_fact:
|
||||
current_fsid:
|
||||
rc: 1
|
||||
when: rolling_update | bool or groups.get(mon_group_name, []) | length == 0
|
||||
|
||||
- name: Get current fsid
|
||||
ansible.builtin.command: "{{ timeout_command }} {{ container_exec_cmd }} ceph --admin-daemon /var/run/ceph/{{ cluster }}-mon.{{ hostvars[mon_host | default(groups[mon_group_name][0])]['ansible_facts']['hostname'] }}.asok config get fsid"
|
||||
register: rolling_update_fsid
|
||||
delegate_to: "{{ mon_host | default(groups[mon_group_name][0]) }}"
|
||||
until: rolling_update_fsid is succeeded
|
||||
changed_when: false
|
||||
when:
|
||||
- rolling_update | bool
|
||||
- groups.get(mon_group_name, []) | length > 0
|
||||
|
||||
- name: Set_fact fsid
|
||||
ansible.builtin.set_fact:
|
||||
fsid: "{{ (rolling_update_fsid.stdout | from_json).fsid }}"
|
||||
when:
|
||||
- rolling_update | bool
|
||||
- groups.get(mon_group_name, []) | length > 0
|
||||
|
||||
- name: Set_fact fsid from current_fsid
|
||||
ansible.builtin.set_fact:
|
||||
fsid: "{{ current_fsid.stdout }}"
|
||||
run_once: true
|
||||
when: current_fsid.rc == 0
|
||||
|
||||
- name: Fsid related tasks
|
||||
when:
|
||||
- generate_fsid | bool
|
||||
- current_fsid.rc != 0
|
||||
- not rolling_update | bool
|
||||
block:
|
||||
- name: Generate cluster fsid
|
||||
ansible.builtin.command: "{{ hostvars[groups[mon_group_name][0]]['discovered_interpreter_python'] }} -c 'import uuid; print(str(uuid.uuid4()))'"
|
||||
register: cluster_uuid
|
||||
delegate_to: "{{ groups[mon_group_name][0] }}"
|
||||
changed_when: false
|
||||
run_once: true
|
||||
|
||||
- name: Set_fact fsid
|
||||
ansible.builtin.set_fact:
|
||||
fsid: "{{ cluster_uuid.stdout }}"
|
||||
|
||||
- name: Import_tasks devices.yml
|
||||
ansible.builtin.import_tasks: devices.yml
|
||||
when: inventory_hostname in groups.get(osd_group_name, [])
|
||||
|
||||
- name: Check if the ceph conf exists
|
||||
ansible.builtin.stat:
|
||||
path: '/etc/ceph/{{ cluster }}.conf'
|
||||
register: ceph_conf
|
||||
|
||||
- name: Set default osd_pool_default_crush_rule fact
|
||||
ansible.builtin.set_fact:
|
||||
osd_pool_default_crush_rule: "{{ ceph_osd_pool_default_crush_rule }}"
|
||||
|
||||
- name: Get default crush rule value from ceph configuration
|
||||
when: ceph_conf.stat.exists | bool
|
||||
block:
|
||||
- &read-osd-pool-default-crush-rule
|
||||
name: Read osd pool default crush rule
|
||||
ansible.builtin.command: grep 'osd_pool_default_crush_rule' /etc/ceph/{{ cluster }}.conf
|
||||
register: crush_rule_variable
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
failed_when: crush_rule_variable.rc not in (0, 1)
|
||||
- &set-osd-pool-default-crush-rule-fact
|
||||
name: Set osd_pool_default_crush_rule fact
|
||||
ansible.builtin.set_fact:
|
||||
osd_pool_default_crush_rule: "{{ crush_rule_variable.stdout.split(' = ')[1] }}"
|
||||
when: crush_rule_variable.rc == 0
|
||||
|
||||
- name: Get default crush rule value from running monitor ceph configuration
|
||||
when:
|
||||
- running_mon is defined
|
||||
- not ceph_conf.stat.exists | bool
|
||||
block:
|
||||
- <<: *read-osd-pool-default-crush-rule # noqa: name[casing]
|
||||
delegate_to: "{{ running_mon }}"
|
||||
- *set-osd-pool-default-crush-rule-fact
|
||||
|
||||
- name: Import_tasks set_monitor_address.yml
|
||||
ansible.builtin.import_tasks: set_monitor_address.yml
|
||||
when: groups.get(mon_group_name, []) | length > 0
|
||||
|
||||
- name: Import_tasks set_radosgw_address.yml
|
||||
ansible.builtin.include_tasks: set_radosgw_address.yml
|
||||
when:
|
||||
- set_radosgw_address | default(true)
|
||||
- inventory_hostname in groups.get(rgw_group_name, [])
|
||||
|
||||
- name: Set_fact ceph_run_cmd
|
||||
ansible.builtin.set_fact:
|
||||
ceph_run_cmd: "{{ container_binary + ' run --rm --net=host -v /etc/ceph:/etc/ceph:z -v /var/lib/ceph/:/var/lib/ceph/:z -v /var/log/ceph/:/var/log/ceph/:z --entrypoint=ceph ' + ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else 'ceph' }}"
|
||||
delegate_to: "{{ item }}"
|
||||
delegate_facts: true
|
||||
run_once: true
|
||||
with_items:
|
||||
- "{{ groups[mon_group_name] if groups[mon_group_name] | default([]) | length > 0 else [] }}"
|
||||
- "{{ groups[mds_group_name] if groups[mds_group_name] | default([]) | length > 0 else [] }}"
|
||||
- "{{ groups[client_group_name] if groups[client_group_name] | default([]) | length > 0 else [] }}"
|
||||
|
||||
- name: Set_fact ceph_admin_command
|
||||
ansible.builtin.set_fact:
|
||||
ceph_admin_command: "{{ hostvars[item]['ceph_run_cmd'] }} -n client.admin -k /etc/ceph/{{ cluster }}.client.admin.keyring"
|
||||
delegate_to: "{{ item }}"
|
||||
delegate_facts: true
|
||||
run_once: true
|
||||
with_items:
|
||||
- "{{ groups[mon_group_name] if groups[mon_group_name] | default([]) | length > 0 else [] }}"
|
||||
- "{{ groups[mds_group_name] if groups[mds_group_name] | default([]) | length > 0 else [] }}"
|
||||
- "{{ groups[client_group_name] if groups[client_group_name] | default([]) | length > 0 else [] }}"
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
- name: Get current default crush rule details
|
||||
ceph_crush_rule_info:
|
||||
cluster: "{{ cluster }}"
|
||||
environment:
|
||||
CEPH_CONTAINER_IMAGE: "{{ ceph_docker_registry + '/' + ceph_docker_image + ':' + ceph_docker_image_tag if containerized_deployment | bool else None }}"
|
||||
CEPH_CONTAINER_BINARY: "{{ container_binary }}"
|
||||
register: default_crush_rule_details
|
||||
delegate_to: "{{ delegated_node | default(groups[mon_group_name][0]) }}"
|
||||
run_once: true
|
||||
|
||||
- name: Get current default crush rule name
|
||||
ansible.builtin.set_fact:
|
||||
ceph_osd_pool_default_crush_rule_name: "{{ item.rule_name }}"
|
||||
with_items: "{{ default_crush_rule_details.stdout | default('{}', True) | from_json }}"
|
||||
run_once: true
|
||||
when: item.rule_id | int == osd_pool_default_crush_rule | int
|
||||
@@ -0,0 +1,35 @@
|
||||
- name: Set grafana_server_addr fact - ipv4
|
||||
ansible.builtin.set_fact:
|
||||
grafana_server_addr: "{{ hostvars[inventory_hostname]['ansible_facts']['all_ipv4_addresses'] | ips_in_ranges(grafana_network.split(',')) | first }}"
|
||||
when:
|
||||
- groups.get(monitoring_group_name, []) | length > 0
|
||||
- ip_version == 'ipv4'
|
||||
- dashboard_enabled | bool
|
||||
- inventory_hostname in groups[monitoring_group_name]
|
||||
|
||||
- name: Set grafana_server_addr fact - ipv6
|
||||
ansible.builtin.set_fact:
|
||||
grafana_server_addr: "{{ hostvars[inventory_hostname]['ansible_facts']['all_ipv6_addresses'] | ips_in_ranges(grafana_network.split(',')) | last | ansible.utils.ipwrap }}"
|
||||
when:
|
||||
- groups.get(monitoring_group_name, []) | length > 0
|
||||
- ip_version == 'ipv6'
|
||||
- dashboard_enabled | bool
|
||||
- inventory_hostname in groups[monitoring_group_name]
|
||||
|
||||
- name: Set grafana_server_addrs fact - ipv4
|
||||
ansible.builtin.set_fact:
|
||||
grafana_server_addrs: "{{ (grafana_server_addrs | default([]) + [hostvars[item]['ansible_facts']['all_ipv4_addresses'] | ips_in_ranges(grafana_network.split(',')) | first]) | unique }}"
|
||||
with_items: "{{ groups.get(monitoring_group_name, []) }}"
|
||||
when:
|
||||
- groups.get(monitoring_group_name, []) | length > 0
|
||||
- ip_version == 'ipv4'
|
||||
- dashboard_enabled | bool
|
||||
|
||||
- name: Set grafana_server_addrs fact - ipv6
|
||||
ansible.builtin.set_fact:
|
||||
grafana_server_addrs: "{{ (grafana_server_addrs | default([]) + [hostvars[item]['ansible_facts']['all_ipv6_addresses'] | ips_in_ranges(grafana_network.split(',')) | last | ansible.utils.ipwrap]) | unique }}"
|
||||
with_items: "{{ groups.get(monitoring_group_name, []) }}"
|
||||
when:
|
||||
- groups.get(monitoring_group_name, []) | length > 0
|
||||
- ip_version == 'ipv6'
|
||||
- dashboard_enabled | bool
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
- name: Include facts.yml
|
||||
ansible.builtin.include_tasks: facts.yml
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Set_fact _monitor_addresses - ipv4
|
||||
ansible.builtin.set_fact:
|
||||
_monitor_addresses: "{{ _monitor_addresses | default({}) | combine({item: hostvars[item]['ansible_facts']['all_ipv4_addresses'] | ips_in_ranges(hostvars[item]['public_network'].split(',')) | first}) }}"
|
||||
with_items: "{{ groups.get(mon_group_name, []) }}"
|
||||
when:
|
||||
- ip_version == 'ipv4'
|
||||
|
||||
- name: Set_fact _monitor_addresses - ipv6
|
||||
ansible.builtin.set_fact:
|
||||
_monitor_addresses: "{{ _monitor_addresses | default({}) | combine({item: hostvars[item]['ansible_facts']['all_ipv6_addresses'] | ips_in_ranges(hostvars[item]['public_network'].split(',')) | last | ansible.utils.ipwrap}) }}"
|
||||
with_items: "{{ groups.get(mon_group_name, []) }}"
|
||||
when:
|
||||
- ip_version == 'ipv6'
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
- name: Dashboard related tasks
|
||||
when: ceph_dashboard_call_item is defined
|
||||
block:
|
||||
- name: Set current radosgw_address_block, radosgw_address, radosgw_interface from node "{{ ceph_dashboard_call_item }}"
|
||||
ansible.builtin.set_fact:
|
||||
radosgw_address_block: "{{ hostvars[ceph_dashboard_call_item]['radosgw_address_block'] | default(radosgw_address_block) }}"
|
||||
radosgw_address: "{{ hostvars[ceph_dashboard_call_item]['radosgw_address'] | default(radosgw_address) }}"
|
||||
radosgw_interface: "{{ hostvars[ceph_dashboard_call_item]['radosgw_interface'] | default(radosgw_interface) }}"
|
||||
|
||||
- name: Set_fact _radosgw_address to radosgw_address_block ipv4
|
||||
ansible.builtin.set_fact:
|
||||
_radosgw_address: "{{ hostvars[inventory_hostname]['ansible_facts']['all_ipv4_addresses'] | ips_in_ranges(hostvars[inventory_hostname]['radosgw_address_block'].split(',')) | first }}"
|
||||
when:
|
||||
- radosgw_address_block is defined
|
||||
- radosgw_address_block != 'subnet'
|
||||
- ip_version == 'ipv4'
|
||||
|
||||
- name: Set_fact _radosgw_address to radosgw_address_block ipv6
|
||||
ansible.builtin.set_fact:
|
||||
_radosgw_address: "{{ hostvars[inventory_hostname]['ansible_facts']['all_ipv6_addresses'] | ips_in_ranges(hostvars[inventory_hostname]['radosgw_address_block'].split(',')) | last | ansible.utils.ipwrap }}"
|
||||
when:
|
||||
- radosgw_address_block is defined
|
||||
- radosgw_address_block != 'subnet'
|
||||
- ip_version == 'ipv6'
|
||||
|
||||
- name: Set_fact _radosgw_address to radosgw_address
|
||||
ansible.builtin.set_fact:
|
||||
_radosgw_address: "{{ radosgw_address | ansible.utils.ipwrap }}"
|
||||
when:
|
||||
- radosgw_address is defined
|
||||
- radosgw_address != 'x.x.x.x'
|
||||
|
||||
- name: Tasks for radosgw interface
|
||||
when:
|
||||
- radosgw_address_block == 'subnet'
|
||||
- radosgw_address == 'x.x.x.x'
|
||||
- radosgw_interface != 'interface'
|
||||
block:
|
||||
- name: Set_fact _interface
|
||||
ansible.builtin.set_fact:
|
||||
_interface: "{{ (hostvars[item]['radosgw_interface'] | replace('-', '_')) }}"
|
||||
loop: "{{ groups.get(rgw_group_name, []) }}"
|
||||
delegate_to: "{{ item }}"
|
||||
delegate_facts: true
|
||||
run_once: true
|
||||
|
||||
- name: Set_fact _radosgw_address to radosgw_interface - ipv4
|
||||
ansible.builtin.set_fact:
|
||||
_radosgw_address: "{{ hostvars[item]['ansible_facts'][hostvars[item]['_interface']][ip_version]['address'] }}"
|
||||
loop: "{{ groups.get(rgw_group_name, []) }}"
|
||||
delegate_to: "{{ item }}"
|
||||
delegate_facts: true
|
||||
run_once: true
|
||||
when: ip_version == 'ipv4'
|
||||
|
||||
- name: Set_fact _radosgw_address to radosgw_interface - ipv6
|
||||
ansible.builtin.set_fact:
|
||||
_radosgw_address: "{{ hostvars[item]['ansible_facts'][hostvars[item]['_interface']][ip_version][0]['address'] | ansible.utils.ipwrap }}"
|
||||
loop: "{{ groups.get(rgw_group_name, []) }}"
|
||||
delegate_to: "{{ item }}"
|
||||
delegate_facts: true
|
||||
run_once: true
|
||||
when: ip_version == 'ipv6'
|
||||
|
||||
- name: Rgw_instances
|
||||
when:
|
||||
- ceph_dashboard_call_item is defined or
|
||||
inventory_hostname in groups.get(rgw_group_name, [])
|
||||
block:
|
||||
- name: Reset rgw_instances (workaround)
|
||||
ansible.builtin.set_fact:
|
||||
rgw_instances: []
|
||||
|
||||
- name: Set_fact rgw_instances
|
||||
ansible.builtin.set_fact:
|
||||
rgw_instances: "{{ rgw_instances | default([]) | union([{'instance_name': 'rgw' + item | string, 'radosgw_address': hostvars[ceph_dashboard_call_item | default(inventory_hostname)]['_radosgw_address'], 'radosgw_frontend_port': radosgw_frontend_port | int + item | int}]) }}"
|
||||
with_sequence: start=0 end={{ radosgw_num_instances | int - 1 }}
|
||||
delegate_to: "{{ ceph_dashboard_call_item if ceph_dashboard_call_item is defined else inventory_hostname }}"
|
||||
delegate_facts: true
|
||||
@@ -0,0 +1,201 @@
|
||||
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 [2014] [Sébastien Han]
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,3 @@
|
||||
# Ansible role: ceph-fetch
|
||||
|
||||
Documentation is available at http://docs.ceph.com/ceph-ansible/.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
# 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:
|
||||
|
||||
fetch_directory: fetch/
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
galaxy_info:
|
||||
company: Red Hat
|
||||
author: Andrew Schoen
|
||||
description: Fetches ceph keys from monitors.
|
||||
license: Apache
|
||||
min_ansible_version: '2.7'
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- 'all'
|
||||
galaxy_tags:
|
||||
- system
|
||||
dependencies: []
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
- name: Lookup keys in /etc/ceph
|
||||
ansible.builtin.shell: ls -1 /etc/ceph/*.keyring
|
||||
changed_when: false
|
||||
register: ceph_keys
|
||||
|
||||
- name: Create a local fetch directory if it does not exist
|
||||
ansible.builtin.file:
|
||||
path: "{{ fetch_directory }}"
|
||||
state: directory
|
||||
mode: "0755"
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
|
||||
- name: Copy ceph user and bootstrap keys to the ansible server
|
||||
ansible.builtin.fetch:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ fetch_directory }}/{{ fsid }}/{{ item }}"
|
||||
flat: true
|
||||
fail_on_missing: false
|
||||
run_once: true
|
||||
with_items:
|
||||
- "{{ ceph_keys.stdout_lines }}"
|
||||
- "/var/lib/ceph/bootstrap-osd/{{ cluster }}.keyring"
|
||||
- "/var/lib/ceph/bootstrap-rgw/{{ cluster }}.keyring"
|
||||
- "/var/lib/ceph/bootstrap-mds/{{ cluster }}.keyring"
|
||||
- "/var/lib/ceph/bootstrap-rbd/{{ cluster }}.keyring"
|
||||
- "/var/lib/ceph/bootstrap-mgr/{{ cluster }}.keyring"
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
galaxy_info:
|
||||
company: Red Hat
|
||||
author: Boris Ranto
|
||||
description: Configures Grafana for Ceph Dashboard
|
||||
license: Apache
|
||||
min_ansible_version: "2.4"
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- 'all'
|
||||
galaxy_tags:
|
||||
- system
|
||||
dependencies: []
|
||||
@@ -0,0 +1,117 @@
|
||||
---
|
||||
- name: Install ceph-grafana-dashboards package on RedHat or SUSE
|
||||
ansible.builtin.package:
|
||||
name: ceph-grafana-dashboards
|
||||
state: "{{ (upgrade_ceph_packages | bool) | ternary('latest', 'present') }}"
|
||||
register: result
|
||||
until: result is succeeded
|
||||
when:
|
||||
- not containerized_deployment | bool
|
||||
- ansible_facts['os_family'] in ['RedHat', 'Suse']
|
||||
tags: package-install
|
||||
|
||||
- name: Make sure grafana is down
|
||||
ansible.builtin.service:
|
||||
name: grafana-server
|
||||
state: stopped
|
||||
|
||||
- name: Wait for grafana to be stopped
|
||||
ansible.builtin.wait_for:
|
||||
host: '{{ grafana_server_addr if ip_version == "ipv4" else grafana_server_addr[1:-1] }}'
|
||||
port: '{{ grafana_port }}'
|
||||
state: stopped
|
||||
|
||||
- name: Make sure grafana configuration directories exist
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
recurse: true
|
||||
owner: "{{ grafana_uid }}"
|
||||
group: "{{ grafana_uid }}"
|
||||
with_items:
|
||||
- "/etc/grafana/dashboards/ceph-dashboard"
|
||||
- "/etc/grafana/provisioning/datasources"
|
||||
- "/etc/grafana/provisioning/dashboards"
|
||||
- "/etc/grafana/provisioning/notifiers"
|
||||
|
||||
- name: Download ceph grafana dashboards
|
||||
ansible.builtin.get_url:
|
||||
url: "https://raw.githubusercontent.com/ceph/ceph/{{ grafana_dashboard_version }}/monitoring/ceph-mixin/dashboards_out/{{ item }}"
|
||||
dest: "/etc/grafana/dashboards/ceph-dashboard/{{ item }}"
|
||||
mode: "0644"
|
||||
with_items: "{{ grafana_dashboard_files }}"
|
||||
when:
|
||||
- not containerized_deployment | bool
|
||||
- not ansible_facts['os_family'] in ['RedHat', 'Suse']
|
||||
|
||||
- name: Write grafana.ini
|
||||
openstack.config_template.config_template:
|
||||
src: grafana.ini.j2
|
||||
dest: /etc/grafana/grafana.ini
|
||||
owner: "{{ grafana_uid }}"
|
||||
group: "{{ grafana_uid }}"
|
||||
mode: "0640"
|
||||
config_type: ini
|
||||
config_overrides: "{{ grafana_conf_overrides }}"
|
||||
|
||||
- name: Write datasources provisioning config file
|
||||
ansible.builtin.template:
|
||||
src: datasources-ceph-dashboard.yml.j2
|
||||
dest: /etc/grafana/provisioning/datasources/ceph-dashboard.yml
|
||||
owner: "{{ grafana_uid }}"
|
||||
group: "{{ grafana_uid }}"
|
||||
mode: "0640"
|
||||
|
||||
- name: Write dashboards provisioning config file
|
||||
ansible.builtin.template:
|
||||
src: dashboards-ceph-dashboard.yml.j2
|
||||
dest: /etc/grafana/provisioning/dashboards/ceph-dashboard.yml
|
||||
owner: "{{ grafana_uid }}"
|
||||
group: "{{ grafana_uid }}"
|
||||
mode: "0640"
|
||||
when: not containerized_deployment | bool
|
||||
|
||||
- name: Copy grafana SSL certificate file
|
||||
ansible.builtin.copy:
|
||||
src: "{{ grafana_crt }}"
|
||||
dest: "/etc/grafana/ceph-dashboard.crt"
|
||||
owner: "{{ grafana_uid }}"
|
||||
group: "{{ grafana_uid }}"
|
||||
mode: "0640"
|
||||
remote_src: "{{ dashboard_tls_external | bool }}"
|
||||
when:
|
||||
- grafana_crt | length > 0
|
||||
- dashboard_protocol == "https"
|
||||
|
||||
- name: Copy grafana SSL certificate key
|
||||
ansible.builtin.copy:
|
||||
src: "{{ grafana_key }}"
|
||||
dest: "/etc/grafana/ceph-dashboard.key"
|
||||
owner: "{{ grafana_uid }}"
|
||||
group: "{{ grafana_uid }}"
|
||||
mode: "0440"
|
||||
remote_src: "{{ dashboard_tls_external | bool }}"
|
||||
when:
|
||||
- grafana_key | length > 0
|
||||
- dashboard_protocol == "https"
|
||||
|
||||
- name: Generate a Self Signed OpenSSL certificate for dashboard
|
||||
ansible.builtin.shell: |
|
||||
test -f /etc/grafana/ceph-dashboard.key -a -f /etc/grafana/ceph-dashboard.crt || \
|
||||
(openssl req -new -nodes -x509 -subj '/O=IT/CN=ceph-grafana' -days 3650 -keyout /etc/grafana/ceph-dashboard.key -out /etc/grafana/ceph-dashboard.crt -extensions v3_ca && \
|
||||
chown {{ grafana_uid }}:{{ grafana_uid }} /etc/grafana/ceph-dashboard.key /etc/grafana/ceph-dashboard.crt)
|
||||
changed_when: false
|
||||
when:
|
||||
- dashboard_protocol == "https"
|
||||
- grafana_key | length == 0 or grafana_crt | length == 0
|
||||
|
||||
- name: Enable and start grafana
|
||||
ansible.builtin.service:
|
||||
name: grafana-server
|
||||
state: restarted
|
||||
enabled: true
|
||||
|
||||
- name: Wait for grafana to start
|
||||
ansible.builtin.wait_for:
|
||||
host: '{{ grafana_server_addr if ip_version == "ipv4" else grafana_server_addr[1:-1] }}'
|
||||
port: '{{ grafana_port }}'
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user