|
| 1 | +--- |
| 2 | +# Copyright Red Hat, Inc. |
| 3 | +# All Rights Reserved. |
| 4 | +# |
| 5 | +# Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 6 | +# not use this file except in compliance with the License. You may obtain |
| 7 | +# a copy of the License at |
| 8 | +# |
| 9 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +# |
| 11 | +# Unless required by applicable law or agreed to in writing, software |
| 12 | +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 13 | +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 14 | +# License for the specific language governing permissions and limitations |
| 15 | +# under the License. |
| 16 | + |
| 17 | +# This playbook updates the central site after all DCN sites are deployed. |
| 18 | +# 1. Copy Ceph keys and configuration from DCN sites to central controllers |
| 19 | +# 2. Configure Glance with DCN Ceph stores |
| 20 | +# 3. Restart Glance to apply the new configuration |
| 21 | + |
| 22 | +- name: Update central site with DCN Ceph stores |
| 23 | + hosts: "{{ cifmw_target_host | default('localhost') }}" |
| 24 | + gather_facts: false |
| 25 | + vars: |
| 26 | + _dcn_stack_names: "{{ dcn_stack_names | default('dcn1,dcn2') }}" |
| 27 | + _glance_config_file: "/var/lib/config-data/puppet-generated/glance_api/etc/glance/glance-api.conf" |
| 28 | + tasks: |
| 29 | + - name: Build list of DCN sites from scenario |
| 30 | + vars: |
| 31 | + _dcn_name: "{{ item }}" |
| 32 | + _dcn_stack: >- |
| 33 | + {{ cifmw_adoption_osp_deploy_scenario.stacks | |
| 34 | + selectattr('stackname', 'equalto', _dcn_name) | |
| 35 | + first }} |
| 36 | + _dcn_group: "{{ _dcn_stack.stack_nodes | first }}" |
| 37 | + _dcn_node: "{{ _vm_groups[_dcn_group] | first }}" |
| 38 | + ansible.builtin.set_fact: |
| 39 | + _dcn_sites: >- |
| 40 | + {{ _dcn_sites | default([]) + [{'name': _dcn_name, 'ceph_node': _dcn_node}] }} |
| 41 | + loop: "{{ _dcn_stack_names.split(',') }}" |
| 42 | + |
| 43 | + - name: Get list of controller nodes |
| 44 | + vars: |
| 45 | + _central_stack: >- |
| 46 | + {{ cifmw_adoption_osp_deploy_scenario.stacks | |
| 47 | + selectattr('stackname', 'equalto', central_stack_name | default('central')) | |
| 48 | + first }} |
| 49 | + _controller_group: >- |
| 50 | + {{ _central_stack.stack_nodes | |
| 51 | + select('search', 'controller') | |
| 52 | + first | default('osp-controllers') }} |
| 53 | + ansible.builtin.set_fact: |
| 54 | + _controller_nodes: "{{ _vm_groups[_controller_group] | default([]) }}" |
| 55 | + |
| 56 | + - name: Display discovered nodes |
| 57 | + ansible.builtin.debug: |
| 58 | + msg: |
| 59 | + - "DCN sites: {{ _dcn_sites }}" |
| 60 | + - "Controller nodes: {{ _controller_nodes }}" |
| 61 | + |
| 62 | + - name: Build Glance DCN store configuration |
| 63 | + ansible.builtin.set_fact: |
| 64 | + _glance_dcn_config: | |
| 65 | + {% for site in _dcn_sites %} |
| 66 | + [{{ site.name }}] |
| 67 | + rbd_store_ceph_conf=/etc/ceph/{{ site.name }}.conf |
| 68 | + rbd_store_user=openstack |
| 69 | + rbd_store_pool=images |
| 70 | + rbd_thin_provisioning=False |
| 71 | + store_description={{ site.name }} rbd glance store |
| 72 | + {% endfor %} |
| 73 | +
|
| 74 | + - name: Copy Ceph files from DCN sites to controllers |
| 75 | + block: |
| 76 | + - name: Ensure ceph config directory exists on controllers |
| 77 | + delegate_to: "{{ item }}" |
| 78 | + become: true |
| 79 | + ansible.builtin.file: |
| 80 | + path: "/var/lib/tripleo-config/ceph" |
| 81 | + state: directory |
| 82 | + owner: root |
| 83 | + group: root |
| 84 | + mode: "0755" |
| 85 | + loop: "{{ _controller_nodes }}" |
| 86 | + |
| 87 | + - name: Fetch Ceph config from DCN site |
| 88 | + delegate_to: "{{ item.ceph_node }}" |
| 89 | + become: true |
| 90 | + ansible.builtin.fetch: |
| 91 | + src: "/var/lib/tripleo-config/ceph/{{ item.name }}.conf" |
| 92 | + dest: "/tmp/ceph_files/{{ item.name }}.conf" |
| 93 | + flat: true |
| 94 | + loop: "{{ _dcn_sites }}" |
| 95 | + loop_control: |
| 96 | + label: "{{ item.name }}" |
| 97 | + |
| 98 | + - name: Fetch Ceph keyring from DCN site |
| 99 | + delegate_to: "{{ item.ceph_node }}" |
| 100 | + become: true |
| 101 | + ansible.builtin.fetch: |
| 102 | + src: "/var/lib/tripleo-config/ceph/{{ item.name }}.client.openstack.keyring" |
| 103 | + dest: "/tmp/ceph_files/{{ item.name }}.client.openstack.keyring" |
| 104 | + flat: true |
| 105 | + loop: "{{ _dcn_sites }}" |
| 106 | + loop_control: |
| 107 | + label: "{{ item.name }}" |
| 108 | + |
| 109 | + - name: Copy Ceph config to controllers |
| 110 | + delegate_to: "{{ item.1 }}" |
| 111 | + become: true |
| 112 | + ansible.builtin.copy: |
| 113 | + src: "/tmp/ceph_files/{{ item.0.name }}.conf" |
| 114 | + dest: "/var/lib/tripleo-config/ceph/{{ item.0.name }}.conf" |
| 115 | + owner: root |
| 116 | + group: root |
| 117 | + mode: "0644" |
| 118 | + loop: "{{ _dcn_sites | product(_controller_nodes) | list }}" |
| 119 | + loop_control: |
| 120 | + label: "{{ item.0.name }} -> {{ item.1 }}" |
| 121 | + |
| 122 | + - name: Copy Ceph keyring to controllers |
| 123 | + delegate_to: "{{ item.1 }}" |
| 124 | + become: true |
| 125 | + ansible.builtin.copy: |
| 126 | + src: "/tmp/ceph_files/{{ item.0.name }}.client.openstack.keyring" |
| 127 | + dest: "/var/lib/tripleo-config/ceph/{{ item.0.name }}.client.openstack.keyring" |
| 128 | + owner: root |
| 129 | + group: root |
| 130 | + mode: "0644" |
| 131 | + loop: "{{ _dcn_sites | product(_controller_nodes) | list }}" |
| 132 | + loop_control: |
| 133 | + label: "{{ item.0.name }} -> {{ item.1 }}" |
| 134 | + |
| 135 | + - name: Configure Glance with DCN stores |
| 136 | + block: |
| 137 | + - name: Check glance config status on each controller |
| 138 | + delegate_to: "{{ controller }}" |
| 139 | + become: true |
| 140 | + ansible.builtin.stat: |
| 141 | + path: "{{ _glance_config_file }}" |
| 142 | + register: _glance_status |
| 143 | + loop: "{{ _controller_nodes }}" |
| 144 | + loop_control: |
| 145 | + loop_var: controller |
| 146 | + |
| 147 | + - name: Build list of controllers needing Glance update |
| 148 | + ansible.builtin.set_fact: |
| 149 | + _controllers_to_update: >- |
| 150 | + {{ _glance_status.results | |
| 151 | + selectattr('stat.exists') | |
| 152 | + map(attribute='controller') | |
| 153 | + list }} |
| 154 | +
|
| 155 | + - name: Display controllers to update |
| 156 | + ansible.builtin.debug: |
| 157 | + msg: "Controllers needing Glance update: {{ _controllers_to_update }}" |
| 158 | + |
| 159 | + - name: Get current enabled_backends value |
| 160 | + delegate_to: "{{ controller }}" |
| 161 | + become: true |
| 162 | + ansible.builtin.command: |
| 163 | + cmd: awk -F'\s*=\s*' '/^enabled_backends\s*=/{print $2; exit}' "{{ _glance_config_file }}" |
| 164 | + register: _current_backends |
| 165 | + changed_when: false |
| 166 | + loop: "{{ _controllers_to_update }}" |
| 167 | + loop_control: |
| 168 | + loop_var: controller |
| 169 | + |
| 170 | + - name: Build DCN backends string |
| 171 | + ansible.builtin.set_fact: |
| 172 | + _dcn_backends_suffix: >- |
| 173 | + {{ _dcn_sites | map(attribute='name') | map('regex_replace', '^(.*)$', ',\1:rbd') | join('') }} |
| 174 | +
|
| 175 | + - name: Update enabled_backends to include DCN stores |
| 176 | + delegate_to: "{{ item.controller }}" |
| 177 | + become: true |
| 178 | + ansible.builtin.lineinfile: |
| 179 | + path: "{{ _glance_config_file }}" |
| 180 | + regexp: '^enabled_backends\s*=' |
| 181 | + line: "enabled_backends={{ item.stdout }}{{ _dcn_backends_suffix }}" |
| 182 | + backrefs: false |
| 183 | + loop: "{{ _current_backends.results }}" |
| 184 | + loop_control: |
| 185 | + label: "{{ item.controller }}" |
| 186 | + when: >- |
| 187 | + _dcn_sites | map(attribute='name') | |
| 188 | + map('regex_replace', '^(.*)$', '\1:rbd') | |
| 189 | + reject('in', item.stdout) | list | length > 0 |
| 190 | + notify: Restart Glance API service on updated controllers |
| 191 | + |
| 192 | + - name: Enable copy-image import method for multistore |
| 193 | + delegate_to: "{{ controller }}" |
| 194 | + become: true |
| 195 | + ansible.builtin.lineinfile: |
| 196 | + path: "{{ _glance_config_file }}" |
| 197 | + regexp: '^enabled_import_methods\s*=' |
| 198 | + line: 'enabled_import_methods=["web-download","copy-image"]' |
| 199 | + insertafter: '^\[DEFAULT\]' |
| 200 | + loop: "{{ _controllers_to_update }}" |
| 201 | + loop_control: |
| 202 | + loop_var: controller |
| 203 | + notify: Restart Glance API service on updated controllers |
| 204 | + |
| 205 | + - name: Add DCN store configuration to glance-api.conf |
| 206 | + delegate_to: "{{ controller }}" |
| 207 | + become: true |
| 208 | + ansible.builtin.blockinfile: |
| 209 | + path: "{{ _glance_config_file }}" |
| 210 | + block: "{{ _glance_dcn_config }}" |
| 211 | + insertafter: EOF |
| 212 | + loop: "{{ _controllers_to_update }}" |
| 213 | + loop_control: |
| 214 | + loop_var: controller |
| 215 | + notify: Restart Glance API service on updated controllers |
| 216 | + |
| 217 | + - name: Clean up temporary Ceph files |
| 218 | + ansible.builtin.file: |
| 219 | + path: /tmp/ceph_files |
| 220 | + state: absent |
| 221 | + |
| 222 | + handlers: |
| 223 | + - name: Restart Glance API service on updated controllers |
| 224 | + delegate_to: "{{ controller }}" |
| 225 | + become: true |
| 226 | + ansible.builtin.systemd: |
| 227 | + name: tripleo_glance_api.service |
| 228 | + state: restarted |
| 229 | + loop: "{{ _controllers_to_update }}" |
| 230 | + loop_control: |
| 231 | + loop_var: controller |
0 commit comments