From bb2bd3fc0f612cdab6f9d61724568daf9281ce3c Mon Sep 17 00:00:00 2001 From: Bohdan Dobrelia Date: Tue, 17 Mar 2026 13:32:28 +0100 Subject: [PATCH 1/3] [ci_gen_kustomize_values] nova05epsilon: ceph conf The ceph.yml post_stage_run hook (via cifmw_ceph_client role) writes Ceph config files to cifmw_ceph_client_fetch_dir (default /tmp/). This template reads those files and provides them as base64-encoded values under data.ceph_conf (DCN convention). Generated-by: claude-4.6-opus-high Signed-off-by: Bohdan Dobrelia --- .../values.yaml.j2 | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 roles/ci_gen_kustomize_values/templates/nova05epsilon/edpm-nodeset-values-post-ceph/values.yaml.j2 diff --git a/roles/ci_gen_kustomize_values/templates/nova05epsilon/edpm-nodeset-values-post-ceph/values.yaml.j2 b/roles/ci_gen_kustomize_values/templates/nova05epsilon/edpm-nodeset-values-post-ceph/values.yaml.j2 new file mode 100644 index 000000000..cd1bf2ea8 --- /dev/null +++ b/roles/ci_gen_kustomize_values/templates/nova05epsilon/edpm-nodeset-values-post-ceph/values.yaml.j2 @@ -0,0 +1,23 @@ +--- +# source: nova05epsilon/edpm-nodeset-values-post-ceph/values.yaml.j2 +# Auto-populates ceph_conf from files written by ceph.yml hook. +# The ceph.yml post_stage_run hook (via cifmw_ceph_client role) writes +# Ceph config files to cifmw_ceph_client_fetch_dir (default /tmp/). +# This template reads those files and provides them as base64-encoded +# values under data.ceph_conf (DCN convention). +# When running in generate-CRs-only mode (mock validation), the files +# won't exist; emit placeholders so kustomize can still build. +{% set _fetch_dir = cifmw_ceph_client_fetch_dir | default('/tmp') %} +{% set _cluster = cifmw_ceph_client_cluster | default('ceph') %} +{% set _conf_file = (_fetch_dir, _cluster ~ '.conf') | path_join %} +{% set _keyring_file = (_fetch_dir, _cluster ~ '.client.openstack.keyring') | path_join %} +{% set _mock = cifmw_kustomize_deploy_generate_crs_only | default(false) | bool %} +data: + ceph_conf: +{% if not _mock and _keyring_file is file and _conf_file is file %} + {{ _cluster }}.client.openstack.keyring: {{ lookup('file', _keyring_file, rstrip=False) | b64encode }} + {{ _cluster }}.conf: {{ lookup('file', _conf_file, rstrip=False) | b64encode }} +{% else %} + {{ _cluster }}.client.openstack.keyring: CHANGEME_CEPH_KEYRING + {{ _cluster }}.conf: CHANGEME_CEPH_CONF +{% endif %} From 9ffc5dad2448083731de6d4b49b5c563edae1c78 Mon Sep 17 00:00:00 2001 From: Bohdan Dobrelia Date: Thu, 14 May 2026 10:17:37 +0200 Subject: [PATCH 2/3] [ceph] Allow overriding ssh and storage_mgmt To allow BM SNO with ceph using custom ceph CIDR values, make ssh_network_range and storage_mgmt_network_range overridable via cifmw_ceph_ssh_network_range and cifmw_ceph_storage_mgmt_network_range. Both are set in set_fact which clobbers extra vars, so we use the cifmw_ indirection with default() to preserve original defaults. NOTE: storage_network_range also needs this treatment. It use to be commented out in set_fact, and this change needs extra testing with Ceph ci jobs perhaps. Also gather network facts for IP-to-host mapping. Signed-off-by: Bohdan Dobrelia --- hooks/playbooks/ceph.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/hooks/playbooks/ceph.yml b/hooks/playbooks/ceph.yml index 13f5ce610..dd3aa4822 100644 --- a/hooks/playbooks/ceph.yml +++ b/hooks/playbooks/ceph.yml @@ -104,6 +104,10 @@ gather_facts: false become: true tasks: + - name: Gather network facts for IP-to-host mapping + ansible.builtin.setup: + gather_subset: + - network # jq is normally installed by cifmw_block_device role, but when cifmw_ceph_spec_data_devices # is defined (indicating block devices are already present), the block device creation play # is skipped. Install jq explicitly here to ensure it's available for ceph operations. @@ -186,9 +190,12 @@ when: - not cifmw_ceph_ipv6 | default(false) ansible.builtin.set_fact: - ssh_network_range: 192.168.122.0/24 - # storage_network_range: 172.18.0.0/24 - storage_mgmt_network_range: 172.20.0.0/24 + ssh_network_range: >- + {{ cifmw_ceph_ssh_network_range | default('192.168.122.0/24') }} + storage_network_range: >- + {{ cifmw_ceph_storage_network_range | default('172.18.0.0/24') }} + storage_mgmt_network_range: >- + {{ cifmw_ceph_storage_mgmt_network_range | default('172.20.0.0/24') }} all_addresses: ansible_all_ipv4_addresses ms_bind_ipv4: true ms_bind_ipv6: false From 6121110e30eb9d443148efa71c9a0f3ef7a20d14 Mon Sep 17 00:00:00 2001 From: Bohdan Dobrelia Date: Wed, 3 Jun 2026 17:42:24 +0200 Subject: [PATCH 3/3] [cifmw_cephadm] fix Swift by Ceph RGW on SNO setup On SNO with a single EDPM compute (single-host CephHCI), the Ceph ingress service (haproxy/keepalived) is not deployed because the ceph_rgw.yml.j2 spec template only creates it for multi-host clusters. Parameterize RGW port to correct the Keystone Swift endpoint for SNO. Change the VIP detection logic so that if cifmw_cephadm_rgw_vip is pre-set (e.g. to the host's storage IP for SNO cases) - it's preserved. Otherwise it falls back to cifmw_cephadm_vip (the ingress VIP) as before. Users will be able to chose from VIP:8080 vs host_ip:8082 accordingly. Signed-off-by: Bohdan Dobrelia --- docs/dictionary/en-custom.txt | 1 + roles/cifmw_cephadm/README.md | 15 ++++++++++++--- roles/cifmw_cephadm/defaults/main.yml | 1 + roles/cifmw_cephadm/tasks/configure_object.yml | 12 ++++++------ roles/cifmw_cephadm/tasks/post.yml | 2 +- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/docs/dictionary/en-custom.txt b/docs/dictionary/en-custom.txt index b6c483033..c042d8973 100644 --- a/docs/dictionary/en-custom.txt +++ b/docs/dictionary/en-custom.txt @@ -227,6 +227,7 @@ fips firewalld flbxutz fmw +frontend fqdn freefonts frmo diff --git a/roles/cifmw_cephadm/README.md b/roles/cifmw_cephadm/README.md index 45a7ac2bd..c06ef866c 100644 --- a/roles/cifmw_cephadm/README.md +++ b/roles/cifmw_cephadm/README.md @@ -87,9 +87,18 @@ that they do not need to be changed for a typical EDPM deployment. `cifmw_cephadm_bootstrap_conf` file, which represents the initial Ceph configuration file passed at bootstrap time. -* `cifmw_cephadm_rgw_vip`: the ingress daemon deployed along with `radosgw` - requires a `VIP` that will be owned by `keepalived`. This IP address will - be used as entry point to reach the `radosgw backends` through `haproxy`. +* `cifmw_cephadm_rgw_vip`: an entry point to reach the + `radosgw` service. On multi-node deployments with ingress (haproxy + + keepalived) it holds the value for VIP owned by keepalived that + fronts the RGW backends via haproxy on port 8080. On SNO deployments where + ingress is not deployed, set this to the host's storage network IP so + the Swift endpoint points directly at the RGW daemon (port 8082). + If not set, it defaults to `cifmw_cephadm_vip` (the ingress VIP). + +* `cifmw_cephadm_rgw_port`: the port used in Swift/object-store Keystone + endpoints. Defaults to `8080` (the ingress/haproxy frontend port). For + single-node deployments without ingress, set to `8082` (the RGW daemon's + native `rgw_frontend_port`) so clients reach RGW directly. * `cifmw_cephadm_nfs_vip`: the ingress daemon deployed along with the `nfs` cluster requires a `VIP` that will be owned by `keepalived`. This IP diff --git a/roles/cifmw_cephadm/defaults/main.yml b/roles/cifmw_cephadm/defaults/main.yml index 2d516ed06..cd497ed2a 100644 --- a/roles/cifmw_cephadm/defaults/main.yml +++ b/roles/cifmw_cephadm/defaults/main.yml @@ -154,6 +154,7 @@ cifmw_cephadm_wait_install_retries: 8 cifmw_cephadm_wait_install_delay: 15 cifmw_cephadm_rgw_ingress_service_name: "ingress.rgw.default" cifmw_cephadm_rgw_ingress_service_id: "rgw.default" +cifmw_cephadm_rgw_port: 8080 # set ssl_backward compatibily to False if ceph version is equal or greater # than Tentacle cifmw_rgw_ssl_backward_compatibility: true diff --git a/roles/cifmw_cephadm/tasks/configure_object.yml b/roles/cifmw_cephadm/tasks/configure_object.yml index d86c03fb2..680a86f58 100644 --- a/roles/cifmw_cephadm/tasks/configure_object.yml +++ b/roles/cifmw_cephadm/tasks/configure_object.yml @@ -126,16 +126,16 @@ --url {{ cifmw_cephadm_urischeme }}://{{ ( cifmw_external_dns_vip_ext.values() | first if cifmw_external_dns_vip_ext is defined - else cifmw_cephadm_rgw_vip | ansible.utils.ipaddr('address') - ) }}:8080/swift/v1/AUTH_%\(tenant_id\)s \ + else _cephadm_rgw_vip | ansible.utils.ipaddr('address') + ) }}:{{ cifmw_cephadm_rgw_port }}/swift/v1/AUTH_%\(tenant_id\)s \ {{ uuid_swift_public_ep.stdout }} oc -n {{ cifmw_cephadm_ns }} rsh openstackclient \ openstack endpoint set \ --url {{ cifmw_cephadm_urischeme }}://{{ ( cifmw_external_dns_vip_int.values() | first if cifmw_external_dns_vip_int is defined - else cifmw_cephadm_rgw_vip | ansible.utils.ipaddr('address') - ) }}:8080/swift/v1/AUTH_%\(tenant_id\)s \ + else _cephadm_rgw_vip | ansible.utils.ipaddr('address') + ) }}:{{ cifmw_cephadm_rgw_port }}/swift/v1/AUTH_%\(tenant_id\)s \ {{ uuid_swift_internal_ep.stdout }} - name: Configure object store to use rgw @@ -146,8 +146,8 @@ script: |- oc -n {{ cifmw_cephadm_ns }} rsh openstackclient openstack role add --user {{ all_uuids.results.0.stdout }} --project {{ project_service_uuid.stdout }} {{ all_uuids.results.2.stdout }} oc -n {{ cifmw_cephadm_ns }} rsh openstackclient openstack role add --user {{ all_uuids.results.0.stdout }} --project {{ project_service_uuid.stdout }} {{ all_uuids.results.3.stdout }} - oc -n {{ cifmw_cephadm_ns }} rsh openstackclient openstack endpoint create --region regionOne {{ all_uuids.results.1.stdout }} public {{ cifmw_cephadm_urischeme }}://{{ cifmw_external_dns_vip_ext.values() | first if cifmw_external_dns_vip_ext is defined else cifmw_cephadm_rgw_vip | ansible.utils.ipaddr('address') }}:8080/swift/v1/AUTH_%\(tenant_id\)s - oc -n {{ cifmw_cephadm_ns }} rsh openstackclient openstack endpoint create --region regionOne {{ all_uuids.results.1.stdout }} internal {{ cifmw_cephadm_urischeme }}://{{ cifmw_external_dns_vip_int.values() | first if cifmw_external_dns_vip_int is defined else cifmw_cephadm_rgw_vip | ansible.utils.ipaddr('address') }}:8080/swift/v1/AUTH_%\(tenant_id\)s + oc -n {{ cifmw_cephadm_ns }} rsh openstackclient openstack endpoint create --region regionOne {{ all_uuids.results.1.stdout }} public {{ cifmw_cephadm_urischeme }}://{{ cifmw_external_dns_vip_ext.values() | first if cifmw_external_dns_vip_ext is defined else _cephadm_rgw_vip | ansible.utils.ipaddr('address') }}:{{ cifmw_cephadm_rgw_port }}/swift/v1/AUTH_%\(tenant_id\)s + oc -n {{ cifmw_cephadm_ns }} rsh openstackclient openstack endpoint create --region regionOne {{ all_uuids.results.1.stdout }} internal {{ cifmw_cephadm_urischeme }}://{{ cifmw_external_dns_vip_int.values() | first if cifmw_external_dns_vip_int is defined else _cephadm_rgw_vip | ansible.utils.ipaddr('address') }}:{{ cifmw_cephadm_rgw_port }}/swift/v1/AUTH_%\(tenant_id\)s oc -n {{ cifmw_cephadm_ns }} rsh openstackclient openstack role add --project {{ all_uuids.results.4.stdout }} --user {{ all_uuids.results.5.stdout }} {{ all_uuids.results.6.stdout }} delegate_to: localhost when: diff --git a/roles/cifmw_cephadm/tasks/post.yml b/roles/cifmw_cephadm/tasks/post.yml index 3c88320c2..ddfde80fe 100644 --- a/roles/cifmw_cephadm/tasks/post.yml +++ b/roles/cifmw_cephadm/tasks/post.yml @@ -52,7 +52,7 @@ - cifmw_ceph_daemons_layout.rgw_enabled | default(true) | bool ansible.builtin.include_tasks: configure_object.yml vars: - cifmw_cephadm_rgw_vip: "{{ cifmw_cephadm_vip }}" + _cephadm_rgw_vip: "{{ cifmw_cephadm_rgw_vip | default(cifmw_cephadm_vip) }}" - name: Create RGW S3 openstack user when: