deep_scrub_choked

This commit is contained in:
a.pivkin
2026-04-06 07:08:17 +03:00
commit 9149dc1d7f
840 changed files with 52471 additions and 0 deletions
+201
View File
@@ -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.
+3
View File
@@ -0,0 +1,3 @@
# Ansible role: ceph-client
Documentation is available at http://docs.ceph.com/ceph-ansible/.
+41
View File
@@ -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 }}" }
+14
View File
@@ -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 }}"
+10
View File
@@ -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
+28
View File
@@ -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 }}"
+201
View File
@@ -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.
+3
View File
@@ -0,0 +1,3 @@
# Ansible role: ceph-common
Documentation is available at http://docs.ceph.com/ceph-ansible/.
+1
View File
@@ -0,0 +1 @@
---
+29
View File
@@ -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-----
+14
View File
@@ -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
+63
View File
@@ -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, [])
+22
View File
@@ -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'
+32
View File
@@ -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') }}"
+201
View File
@@ -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.
+3
View File
@@ -0,0 +1,3 @@
# Ansible role: ceph-config
Documentation is available at http://docs.ceph.com/ceph-ansible/.
+14
View File
@@ -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
+194
View File
@@ -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
+31
View File
@@ -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 %}
+3
View File
@@ -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
+14
View File
@@ -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', '==')
+3
View File
@@ -0,0 +1,3 @@
# Ansible role: ceph-container-engine
Documentation is available at http://docs.ceph.com/ceph-ansible/.
+17
View File
@@ -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 }}"
+1
View File
@@ -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
+14
View File
@@ -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: []
+67
View File
@@ -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
+9
View File
@@ -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
+14
View File
@@ -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
+8
View File
@@ -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
+3
View File
@@ -0,0 +1,3 @@
# Ansible role: ceph-defaults
Documentation is available at http://docs.ceph.com/ceph-ansible/.
+658
View File
@@ -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) }}"
+17
View File
@@ -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: []
+1
View File
@@ -0,0 +1 @@
---
+3
View File
@@ -0,0 +1,3 @@
---
ceph_osd_pool_default_crush_rule: -1
ceph_osd_pool_default_crush_rule_name: "replicated_rule"
+24
View File
@@ -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 }}
+14
View File
@@ -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: []
+58
View File
@@ -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
+9
View File
@@ -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
+3
View File
@@ -0,0 +1,3 @@
# Ansible role: ceph-facts
Documentation is available at http://docs.ceph.com/ceph-ansible/.
+17
View File
@@ -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
+81
View File
@@ -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)
+250
View File
@@ -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
+35
View File
@@ -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
+3
View File
@@ -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
+201
View File
@@ -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.
+3
View File
@@ -0,0 +1,3 @@
# Ansible role: ceph-fetch
Documentation is available at http://docs.ceph.com/ceph-ansible/.
+10
View File
@@ -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/
+14
View File
@@ -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: []
+28
View File
@@ -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"
+14
View File
@@ -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