Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions hooks/playbooks/adoption_dcn_export.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
# Copyright Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

# This playbook exports a TripleO stack for use by DCN stacks.
# It creates the <stack_name>-export.yaml file that contains
# the parameters DCN stacks need to connect to the central site.

- name: Export TripleO stack for DCN
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: false
vars:
_stack_name: "{{ stack_name | default('central') }}"
_ansible_user_dir: "{{ ansible_user_dir | default('/home/zuul') }}"
tasks:
- name: Gather ansible_user_dir from undercloud
delegate_to: "osp-undercloud-0"
ansible.builtin.setup:
gather_subset:
- user_dir

- name: Export stack for DCN usage
delegate_to: "osp-undercloud-0"
vars:
_export_cmd: >-
source {{ ansible_user_dir }}/stackrc;
openstack overcloud export
--stack {{ _stack_name }}
--force-overwrite
--output-file {{ ansible_user_dir }}/overcloud-deploy/{{ _stack_name }}/{{ _stack_name }}-export.yaml
cifmw.general.ci_script:
chdir: "{{ ansible_user_dir }}"
output_dir: "{{ ansible_user_dir }}/ci-framework-data/artifacts"
script: "{{ _export_cmd }}"

- name: Export Ceph configuration for DCN usage
delegate_to: "osp-undercloud-0"
vars:
_export_ceph_cmd: >-
source {{ ansible_user_dir }}/stackrc;
openstack overcloud export ceph
--stack {{ _stack_name }}
--force-overwrite
--output-file {{ ansible_user_dir }}/{{ _stack_name }}_ceph_external.yaml
cifmw.general.ci_script:
chdir: "{{ ansible_user_dir }}"
output_dir: "{{ ansible_user_dir }}/ci-framework-data/artifacts"
script: "{{ _export_ceph_cmd }}"
229 changes: 229 additions & 0 deletions hooks/playbooks/adoption_dcn_update_central.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
---
# Copyright Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

# This playbook updates the central site after all DCN sites are deployed.
# 1. Copy Ceph keys and configuration from DCN sites to central controllers
# 2. Configure Glance with DCN Ceph stores
# 3. Restart Glance to apply the new configuration

- name: Update central site with DCN Ceph stores
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: false
vars:
_dcn_stack_names: "{{ dcn_stack_names | default('dcn1,dcn2') }}"
_glance_config_file: "/var/lib/config-data/puppet-generated/glance_api/etc/glance/glance-api.conf"
tasks:
- name: Build list of DCN sites from scenario
vars:
_dcn_name: "{{ item }}"
_dcn_stack: >-
{{ cifmw_adoption_osp_deploy_scenario.stacks |
selectattr('stackname', 'equalto', _dcn_name) |
first }}
_dcn_group: "{{ _dcn_stack.stack_nodes | first }}"
_dcn_node: "{{ _vm_groups[_dcn_group] | first }}"
ansible.builtin.set_fact:
_dcn_sites: >-
{{ _dcn_sites | default([]) + [{'name': _dcn_name, 'ceph_node': _dcn_node}] }}
loop: "{{ _dcn_stack_names.split(',') }}"

- name: Get list of controller nodes
vars:
_central_stack: >-
{{ cifmw_adoption_osp_deploy_scenario.stacks |
selectattr('stackname', 'equalto', central_stack_name | default('central')) |
first }}
_controller_group: >-
{{ _central_stack.stack_nodes |
select('search', 'controller') |
first | default('osp-controllers') }}
ansible.builtin.set_fact:
_controller_nodes: "{{ _vm_groups[_controller_group] | default([]) }}"

- name: Display discovered nodes
ansible.builtin.debug:
msg:
- "DCN sites: {{ _dcn_sites }}"
- "Controller nodes: {{ _controller_nodes }}"

- name: Build Glance DCN store configuration
ansible.builtin.set_fact:
_glance_dcn_config: |
{% for site in _dcn_sites %}
[{{ site.name }}]
rbd_store_ceph_conf=/etc/ceph/{{ site.name }}.conf
rbd_store_user=openstack
rbd_store_pool=images
rbd_thin_provisioning=False
store_description={{ site.name }} rbd glance store
{% endfor %}

- name: Copy Ceph files from DCN sites to controllers
block:
- name: Ensure ceph config directory exists on controllers
delegate_to: "{{ item }}"
become: true
ansible.builtin.file:
path: "/var/lib/tripleo-config/ceph"
state: directory
owner: root
group: root
mode: "0755"
loop: "{{ _controller_nodes }}"

- name: Fetch Ceph config from DCN site
delegate_to: "{{ item.ceph_node }}"
become: true
ansible.builtin.fetch:
src: "/var/lib/tripleo-config/ceph/{{ item.name }}.conf"
dest: "/tmp/ceph_files/{{ item.name }}.conf"
flat: true
loop: "{{ _dcn_sites }}"
loop_control:
label: "{{ item.name }}"

- name: Fetch Ceph keyring from DCN site
delegate_to: "{{ item.ceph_node }}"
become: true
ansible.builtin.fetch:
src: "/var/lib/tripleo-config/ceph/{{ item.name }}.client.openstack.keyring"
dest: "/tmp/ceph_files/{{ item.name }}.client.openstack.keyring"
flat: true
loop: "{{ _dcn_sites }}"
loop_control:
label: "{{ item.name }}"

- name: Copy Ceph config to controllers
delegate_to: "{{ item.1 }}"
become: true
ansible.builtin.copy:
src: "/tmp/ceph_files/{{ item.0.name }}.conf"
dest: "/var/lib/tripleo-config/ceph/{{ item.0.name }}.conf"
owner: root
group: root
mode: "0644"
loop: "{{ _dcn_sites | product(_controller_nodes) | list }}"
loop_control:
label: "{{ item.0.name }} -> {{ item.1 }}"

- name: Copy Ceph keyring to controllers
delegate_to: "{{ item.1 }}"
become: true
ansible.builtin.copy:
src: "/tmp/ceph_files/{{ item.0.name }}.client.openstack.keyring"
dest: "/var/lib/tripleo-config/ceph/{{ item.0.name }}.client.openstack.keyring"
owner: root
group: root
mode: "0644"
loop: "{{ _dcn_sites | product(_controller_nodes) | list }}"
loop_control:
label: "{{ item.0.name }} -> {{ item.1 }}"

- name: Configure Glance with DCN stores
block:
- name: Check glance config status on each controller
delegate_to: "{{ controller }}"
become: true
ansible.builtin.shell: |
if [ ! -f "{{ _glance_config_file }}" ]; then
echo "NO_FILE"
else
echo "NEEDS_UPDATE"
fi
register: _glance_status
changed_when: false
loop: "{{ _controller_nodes }}"
loop_control:
loop_var: controller

- name: Build list of controllers needing Glance update
ansible.builtin.set_fact:
_controllers_to_update: >-
{{ _glance_status.results |
selectattr('stdout', 'equalto', 'NEEDS_UPDATE') |
map(attribute='controller') |
list }}

- name: Display controllers to update
ansible.builtin.debug:
msg: "Controllers needing Glance update: {{ _controllers_to_update }}"

- name: Get current enabled_backends value
delegate_to: "{{ controller }}"
become: true
ansible.builtin.shell:
cmd: |
set -o pipefail
grep -E '^enabled_backends\s*=' "{{ _glance_config_file }}" | head -1 | sed 's/enabled_backends\s*=\s*//'
register: _current_backends
changed_when: false
loop: "{{ _controllers_to_update }}"
loop_control:
loop_var: controller

- name: Build DCN backends string
ansible.builtin.set_fact:
_dcn_backends_suffix: >-
{{ _dcn_sites | map(attribute='name') | map('regex_replace', '^(.*)$', ',\1:rbd') | join('') }}

- name: Update enabled_backends to include DCN stores
delegate_to: "{{ item.controller }}"
become: true
ansible.builtin.lineinfile:
path: "{{ _glance_config_file }}"
regexp: '^enabled_backends\s*='
line: "enabled_backends={{ item.stdout }}{{ _dcn_backends_suffix }}"
backrefs: false
loop: "{{ _current_backends.results }}"
loop_control:
label: "{{ item.controller }}"
when: _dcn_sites[0].name ~ ':rbd' not in item.stdout

- name: Enable copy-image import method for multistore
delegate_to: "{{ controller }}"
become: true
ansible.builtin.lineinfile:
path: "{{ _glance_config_file }}"
regexp: '^enabled_import_methods\s*='
line: 'enabled_import_methods=["web-download","copy-image"]'
insertafter: '^\[DEFAULT\]'
loop: "{{ _controllers_to_update }}"
loop_control:
loop_var: controller

- name: Add DCN store configuration to glance-api.conf
delegate_to: "{{ controller }}"
become: true
ansible.builtin.blockinfile:
path: "{{ _glance_config_file }}"
block: "{{ _glance_dcn_config }}"
marker: "# {mark} ANSIBLE MANAGED - DCN CEPH STORES"
insertafter: EOF
loop: "{{ _controllers_to_update }}"
loop_control:
loop_var: controller
register: _glance_config_changed

- name: Restart Glance API service on updated controllers
delegate_to: "{{ controller }}"
become: true
ansible.builtin.systemd:
name: tripleo_glance_api.service
state: restarted
loop: "{{ _controllers_to_update }}"
loop_control:
loop_var: controller
when: _controllers_to_update | length > 0
13 changes: 11 additions & 2 deletions hooks/playbooks/adoption_deploy_ceph.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
}}
_cloud_domain: "{{ cifmw_adoption_osp_deploy_scenario.cloud_domain }}"
_source_cmd: "source {{ ansible_user_dir }}/stackrc"
# Use stack-specific filename for non-default stack names to avoid overwrites
# Default 'overcloud' stack uses 'deployed_ceph.yaml' for backward compatibility
_deployed_ceph_suffix: "{{ '' if _overcloud_name == 'overcloud' else '_' ~ _overcloud_name }}"
_deployed_ceph_file: "{{ ansible_user_dir }}/deployed_ceph{{ _deployed_ceph_suffix }}.yaml"
block:
- name: Copy ceph osd file
delegate_to: "osp-undercloud-0"
Expand Down Expand Up @@ -99,6 +103,7 @@
_ceph_spec_cmd: >-
openstack overcloud ceph spec
{{ ansible_user_dir }}/config_download_{{ _overcloud_name }}.yaml
--stack {{ _overcloud_name }}
--tld {{ _cloud_domain }}
--osd-spec {{ _ceph_osd_spec_file_dest }}
--roles-data {{ _roles_file_dest }}
Expand All @@ -111,7 +116,7 @@
- name: Ensure deployed_ceph file does not exist
delegate_to: "osp-undercloud-0"
ansible.builtin.file:
path: "{{ ansible_user_dir }}/deployed_ceph.yaml"
path: "{{ _deployed_ceph_file }}"
state: absent

- name: Gather nodes for stack {{ _overcloud_name }}
Expand Down Expand Up @@ -159,14 +164,18 @@
- name: Deploy ceph
delegate_to: "osp-undercloud-0"
vars:
# Only pass --cluster for non-default stacks to set unique cluster names
# Default 'overcloud' stack uses 'ceph' cluster name for backward compatibility
_ceph_deploy_cmd: >-
openstack overcloud ceph deploy
--stack {{ _overcloud_name }}
{%- if _overcloud_name != 'overcloud' %} --cluster {{ _overcloud_name }}{% endif %}
--tld {{ _cloud_domain }}
--ntp-server {{ cifmw_adoption_osp_deploy_ntp_server }}
--ceph-spec ceph_spec.yaml
--network-data {{ _network_data_file_dest }}
--container-image-prepare {{ ansible_user_dir }}/containers-prepare-parameters.yaml
--output {{ ansible_user_dir }}/deployed_ceph.yaml
--output {{ _deployed_ceph_file }}
cifmw.general.ci_script:
chdir: "{{ ansible_user_dir }}"
output_dir: "{{ _cifmw_basedir_undercloud }}/artifacts"
Expand Down
4 changes: 2 additions & 2 deletions roles/adoption_osp_deploy/tasks/prepare_overcloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,8 @@
delegate_to: "{{ overcloud_vm }}"
vars:
_node_net: "{{ cifmw_networking_env_definition.instances[overcloud_vm] }}"
_ctlplane_node_net: "{{ _node_net.networks.ctlplane | default({}) }}"
_ctlplane_net: "{{ cifmw_networking_env_definition.networks.ctlplane | default({}) }}"
_ctlplane_node_net: "{{ _node_net.networks[_ctlplane] | default({}) }}"
_ctlplane_net: "{{ cifmw_networking_env_definition.networks[_ctlplane] | default({}) }}"
_dns_server: "{{ _ctlplane_net[dns_version|default('dns_v4')] | default(None) }}"
_os_net_config_template: "{{ 'os_net_config_overcloud_bgp.yml.j2' if (cifmw_adoption_osp_deploy_bgp | bool) else 'os_net_config_overcloud.yml.j2' }}"
# Non-BGP specific vars (may not exist in BGP mode, so use default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ allovercloud:
computes:
children:
{% for group in _stack.stack_nodes %}
{% if 'computes' in group %}
{% if 'compute' in group and 'controller' not in group %}
{{ cifmw_adoption_osp_deploy_scenario.roles_groups_map[group] }}: {}
{% endif %}
{% endfor %}
Expand Down
Loading
Loading