diff --git a/docs/dictionary/en-custom.txt b/docs/dictionary/en-custom.txt index 6d203d5edd..3149b5c2a4 100644 --- a/docs/dictionary/en-custom.txt +++ b/docs/dictionary/en-custom.txt @@ -186,6 +186,7 @@ ezzmy favorit fbqufbqkfbzxrja fci +fdp fedoraproject fil filesystem @@ -414,6 +415,7 @@ openstack openstackclient openstackcontrolplane openstackdataplane +openstackdataplanedeployment openstackdataplanenodeset openstackdataplanenodesets openstackprovisioner diff --git a/post-deployment.yml b/post-deployment.yml index b0e66a41ce..ab7c250e39 100644 --- a/post-deployment.yml +++ b/post-deployment.yml @@ -8,7 +8,6 @@ tasks_from: admin_setup.yml tags: - admin-setup - - name: Run Test ansible.builtin.import_role: name: cifmw_setup @@ -26,6 +25,43 @@ tags: - compliance + # FDP Update - OpenStack package updates across all layers + - name: FDP Update - Validate required variables + when: cifmw_fdp_update_enabled | default(false) | bool + block: + - name: Validate required variables are set + ansible.builtin.assert: + that: + - cifmw_fdp_update_target_package is defined + - cifmw_fdp_update_target_package | length > 0 + - cifmw_fdp_update_repo_baseurl is defined + - cifmw_fdp_update_repo_baseurl | length > 0 + fail_msg: | + Required variables are missing! + + You must set: + - cifmw_fdp_update_target_package: Name of the RPM package to update + - cifmw_fdp_update_repo_baseurl: Repository base URL containing the updated package + success_msg: "Required variables validated successfully" + + - name: Update control plane container images + ansible.builtin.import_role: + name: fdp_update_container_images + vars: + cifmw_fdp_update_container_images_target_package: "{{ cifmw_fdp_update_target_package }}" + cifmw_fdp_update_container_images_repo_baseurl: "{{ cifmw_fdp_update_repo_baseurl }}" + cifmw_fdp_update_container_images_namespace: "{{ cifmw_fdp_update_namespace | default('openstack') }}" + when: cifmw_fdp_update_container_images_enabled | default(true) | bool + + - name: Update EDPM (containers and host packages) + ansible.builtin.import_role: + name: fdp_update_edpm + vars: + cifmw_fdp_update_edpm_repo_baseurl: "{{ cifmw_fdp_update_repo_baseurl }}" + when: cifmw_fdp_update_edpm_enabled | default(true) | bool + tags: + - fdp-update + - name: Run compliance scan for computes hosts: "{{ groups['computes'] | default ([]) }}" gather_facts: true diff --git a/roles/fdp_update_container_images/README.md b/roles/fdp_update_container_images/README.md new file mode 100644 index 0000000000..51b5e5d08f --- /dev/null +++ b/roles/fdp_update_container_images/README.md @@ -0,0 +1,105 @@ +# fdp_update_container_images + +Ansible role to update specific RPM packages in OpenStack container images by rebuilding them with custom repositories. + +This role automates the process of: +1. Fetching container images from OpenStackVersion CR +2. Checking if target package exists in each image +3. Building new images with updated packages from custom repository +4. Pushing updated images to OpenShift internal registry +5. Patching OpenStackVersion CR to use the new images + +## Privilege escalation +None - Runs as the user executing Ansible + +## Parameters + +* `cifmw_fdp_update_container_images_basedir`: (String) Base directory. Defaults to `cifmw_basedir` which defaults to `~/ci-framework-data`. +* `cifmw_fdp_update_container_images_namespace`: (String) OpenShift namespace where OpenStack is deployed. Defaults to `openstack`. +* `cifmw_fdp_update_container_images_openstack_cr_name`: (String) Name of the OpenStackVersion CR. Defaults to `controlplane`. +* `cifmw_fdp_update_container_images_target_package`: (String) Name of the RPM package to update (e.g., `ovn24.03`). **Required**. +* `cifmw_fdp_update_container_images_repo_name`: (String) Repository name. Defaults to `custom-repo`. +* `cifmw_fdp_update_container_images_repo_baseurl`: (String) Repository base URL. **Required**. +* `cifmw_fdp_update_container_images_repo_enabled`: (Integer) Enable repository (0 or 1). Defaults to `1`. +* `cifmw_fdp_update_container_images_repo_gpgcheck`: (Integer) Enable GPG check (0 or 1). Defaults to `0`. +* `cifmw_fdp_update_container_images_repo_priority`: (Integer) Repository priority. Defaults to `0`. +* `cifmw_fdp_update_container_images_repo_sslverify`: (Integer) Enable SSL verification (0 or 1). Defaults to `0`. +* `cifmw_fdp_update_container_images_image_registry`: (String) External OpenShift image registry URL. Auto-detected from cluster if not specified. Leave empty for auto-detection. +* `cifmw_fdp_update_container_images_image_registry_internal`: (String) Internal OpenShift image registry URL. Defaults to `image-registry.openshift-image-registry.svc:5000`. +* `cifmw_fdp_update_container_images_image_name_prefix`: (String) Prefix for new image names. Defaults to `fdp-update`. +* `cifmw_fdp_update_container_images_temp_dir`: (String) Temporary directory for build context. Auto-generated if not specified. +* `cifmw_fdp_update_container_images_update_dnf_args`: (String) Additional arguments for dnf update command. Defaults to `--disablerepo='*' --enablerepo={{ cifmw_fdp_update_container_images_repo_name }}`. + +## Examples + +### Update OVN package in all containers +```yaml +--- +- hosts: localhost + vars: + cifmw_fdp_update_container_images_target_package: "ovn24.03" + cifmw_fdp_update_container_images_repo_name: "custom-repo" + cifmw_fdp_update_container_images_repo_baseurl: "http://example.com/custom-repo/" + cifmw_fdp_update_container_images_namespace: "openstack" + roles: + - role: "fdp_update_container_images" +``` + +### Update with custom registry and image prefix +```yaml +--- +- hosts: localhost + vars: + cifmw_fdp_update_container_images_target_package: "ovn24.03" + cifmw_fdp_update_container_images_repo_baseurl: "http://custom-repo.example.com/repo/" + cifmw_fdp_update_container_images_image_registry: "registry.example.com" + cifmw_fdp_update_container_images_image_name_prefix: "ovn-hotfix" + roles: + - role: "fdp_update_container_images" +``` + +### Update with specific DNF arguments +```yaml +--- +- hosts: localhost + vars: + cifmw_fdp_update_container_images_target_package: "neutron-ovn-metadata-agent" + cifmw_fdp_update_container_images_repo_baseurl: "http://custom-repo.example.com/repo/" + cifmw_fdp_update_container_images_update_dnf_args: "--disablerepo='*' --enablerepo={{ cifmw_fdp_update_container_images_repo_name }} --nobest" + roles: + - role: "fdp_update_container_images" +``` + +## How it works + +1. **Registry Setup**: + - Enables the default route for OpenShift image registry + - Auto-detects the registry hostname or uses the configured value +2. **Authentication**: Obtains a token from OpenShift and authenticates with the internal registry using TLS +3. **Image Discovery**: Queries the OpenStackVersion CR for all container images +4. **Package Check**: For each image, creates a temporary container to check if the target package is installed +5. **Image Build**: If the package exists, builds a new image with the updated package from the custom repository +6. **Registry Push**: Pushes the new image to the OpenShift internal registry +7. **CR Update**: Patches the OpenStackVersion CR's `spec.customContainerImages` field with the new image reference +8. **Summary**: Provides a summary of all updated images + +## Requirements + +* OpenShift CLI (`oc`) must be available +* Podman must be installed and accessible +* User must have permissions to: + - Create tokens in the target namespace + - Get and patch OpenStackVersion CRs + - Push images to the internal registry + - Patch image registry configuration (`configs.imageregistry.operator.openshift.io/cluster`) + +## Notes + +* The role uses podman to build and push images with TLS verification +* Each updated image gets a unique tag with timestamp: `--` +* Only images containing the target package will be updated +* The role cleans up temporary containers automatically +* All build contexts are created in a temporary directory that is cleaned up after execution +* The role automatically configures the OpenShift image registry for external access: + - Enables the default route if not already enabled + - Auto-detects the registry hostname from the route diff --git a/roles/fdp_update_container_images/defaults/main.yml b/roles/fdp_update_container_images/defaults/main.yml new file mode 100644 index 0000000000..371d4beb2a --- /dev/null +++ b/roles/fdp_update_container_images/defaults/main.yml @@ -0,0 +1,73 @@ +--- +# 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. + +# ============================================================================ +# Base Configuration +# ============================================================================ + +# Base directory for artifacts and temporary files +cifmw_fdp_update_container_images_basedir: "{{ cifmw_basedir | default(ansible_user_dir ~ '/ci-framework-data') }}" + +# OpenShift namespace where OpenStack is deployed +cifmw_fdp_update_container_images_namespace: "openstack" + +# Name of the OpenStackVersion custom resource +cifmw_fdp_update_container_images_openstack_cr_name: "controlplane" + +# Target package to update (REQUIRED - must be set by user) +cifmw_fdp_update_container_images_target_package: "" + +# List of images to update with the target package +# Only these images will be updated (no package scanning is performed) +cifmw_fdp_update_container_images_images_to_scan: + - ovnControllerImage + - ovnControllerOvsImage + - ovnNbDbclusterImage + - ovnNorthdImage + - ovnSbDbclusterImage + - ceilometerSgcoreImage + +# Repository configuration +cifmw_fdp_update_container_images_repo_name: "custom-repo" +cifmw_fdp_update_container_images_repo_baseurl: "" # REQUIRED - must be set by user +cifmw_fdp_update_container_images_repo_enabled: 1 +cifmw_fdp_update_container_images_repo_gpgcheck: 0 +cifmw_fdp_update_container_images_repo_priority: 0 +cifmw_fdp_update_container_images_repo_sslverify: 0 + +# Image registry configuration +# External registry URL (for compute nodes/EDPM and pushing images) +# Leave empty to auto-detect external route from OpenShift cluster +cifmw_fdp_update_container_images_image_registry: "" + +# Internal registry URL (for OpenShift pods to pull images) +# This is auto-detected and should not normally need to be changed +cifmw_fdp_update_container_images_image_registry_internal: "image-registry.openshift-image-registry.svc:5000" + +# Image naming +cifmw_fdp_update_container_images_image_name_prefix: "fdp-update" + +# Temporary directory for build context +cifmw_fdp_update_container_images_temp_dir: "" + +# DNF update arguments +cifmw_fdp_update_container_images_update_dnf_args: "--disablerepo='*' --enablerepo={{ cifmw_fdp_update_container_images_repo_name }}" + +# Internal variables (do not override) +_cifmw_fdp_update_container_images_modified_images: [] +_cifmw_fdp_update_container_images_updated_cr_keys: [] +_cifmw_fdp_update_container_images_total_images: 0 +_cifmw_fdp_update_container_images_processed_images: 0 diff --git a/roles/fdp_update_container_images/meta/main.yml b/roles/fdp_update_container_images/meta/main.yml new file mode 100644 index 0000000000..d727c787bd --- /dev/null +++ b/roles/fdp_update_container_images/meta/main.yml @@ -0,0 +1,38 @@ +--- +# 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. + +galaxy_info: + author: Red Hat + description: Update RPM packages in OpenStack container images + company: Red Hat + license: Apache-2.0 + min_ansible_version: "2.15" + platforms: + - name: Fedora + versions: + - all + - name: EL + versions: + - "9" + galaxy_tags: + - openstack + - containers + - kubernetes + - openshift + - podman + - rpm + +dependencies: [] diff --git a/roles/fdp_update_container_images/tasks/authenticate_registry.yml b/roles/fdp_update_container_images/tasks/authenticate_registry.yml new file mode 100644 index 0000000000..f44ad679ee --- /dev/null +++ b/roles/fdp_update_container_images/tasks/authenticate_registry.yml @@ -0,0 +1,27 @@ +--- +# 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. + +- name: Create registry token + ansible.builtin.command: oc create token builder -n {{ cifmw_fdp_update_container_images_namespace }} + register: _cifmw_fdp_update_container_images_token + changed_when: false + +- name: Authenticate podman with TLS verification + containers.podman.podman_login: + username: unused + password: "{{ _cifmw_fdp_update_container_images_token.stdout }}" + registry: "{{ cifmw_fdp_update_container_images_image_registry }}" + no_log: true diff --git a/roles/fdp_update_container_images/tasks/configure_ca_cert.yml b/roles/fdp_update_container_images/tasks/configure_ca_cert.yml new file mode 100644 index 0000000000..ea3fd29bda --- /dev/null +++ b/roles/fdp_update_container_images/tasks/configure_ca_cert.yml @@ -0,0 +1,40 @@ +--- +# 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. + +- name: Get OpenShift ingress CA certificate + kubernetes.core.k8s_info: + api_version: v1 + kind: Secret + name: router-ca + namespace: openshift-ingress-operator + register: _cifmw_fdp_update_container_images_ca_secret + +- name: Extract CA certificate from secret + ansible.builtin.set_fact: + _cifmw_fdp_update_container_images_ca_cert_b64: + stdout: "{{ _cifmw_fdp_update_container_images_ca_secret.resources[0].data['tls.crt'] }}" + +- name: Decode CA certificate + ansible.builtin.copy: + content: "{{ _cifmw_fdp_update_container_images_ca_cert_b64.stdout | b64decode }}" + dest: /etc/pki/ca-trust/source/anchors/openshift-registry-ca.crt + mode: '0644' + become: true + +- name: Update CA trust + ansible.builtin.command: update-ca-trust extract + become: true + changed_when: true diff --git a/roles/fdp_update_container_images/tasks/detect_registry.yml b/roles/fdp_update_container_images/tasks/detect_registry.yml new file mode 100644 index 0000000000..a07f4793fd --- /dev/null +++ b/roles/fdp_update_container_images/tasks/detect_registry.yml @@ -0,0 +1,56 @@ +--- +# 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. + +- name: Enable OpenShift registry route + kubernetes.core.k8s: + api_version: imageregistry.operator.openshift.io/v1 + kind: Config + name: cluster + state: patched + definition: + spec: + defaultRoute: true + register: _cifmw_fdp_update_container_images_enable_route + failed_when: false + +- name: Wait for route + ansible.builtin.pause: + seconds: 10 + when: _cifmw_fdp_update_container_images_enable_route.changed + +- name: Get registry route + kubernetes.core.k8s_info: + api_version: route.openshift.io/v1 + kind: Route + name: default-route + namespace: openshift-image-registry + register: _cifmw_fdp_update_container_images_route_info + failed_when: false + +- name: Extract registry host from route + ansible.builtin.set_fact: + _cifmw_fdp_update_container_images_route: + stdout: "{{ _cifmw_fdp_update_container_images_route_info.resources[0].spec.host if _cifmw_fdp_update_container_images_route_info.resources | length > 0 else '' }}" + +- name: Set registry URL + ansible.builtin.set_fact: + cifmw_fdp_update_container_images_image_registry: "{{ _cifmw_fdp_update_container_images_route.stdout }}" + when: _cifmw_fdp_update_container_images_route.stdout | length > 0 + +- name: Verify registry URL + ansible.builtin.fail: + msg: "Failed to determine registry URL. Set cifmw_fdp_update_container_images_image_registry manually." + when: cifmw_fdp_update_container_images_image_registry is not defined or cifmw_fdp_update_container_images_image_registry | length == 0 diff --git a/roles/fdp_update_container_images/tasks/fetch_images.yml b/roles/fdp_update_container_images/tasks/fetch_images.yml new file mode 100644 index 0000000000..b3362efc83 --- /dev/null +++ b/roles/fdp_update_container_images/tasks/fetch_images.yml @@ -0,0 +1,38 @@ +--- +# 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. + +- name: Get OpenStackVersion CR + kubernetes.core.k8s_info: + api_version: core.openstack.org/v1beta1 + kind: OpenStackVersion + name: "{{ cifmw_fdp_update_container_images_openstack_cr_name }}" + namespace: "{{ cifmw_fdp_update_container_images_namespace }}" + register: _cifmw_fdp_update_container_images_cr_info + +- name: Extract container images + ansible.builtin.set_fact: + _cifmw_fdp_update_container_images_container_images: "{{ _cifmw_fdp_update_container_images_cr_info.resources[0].status.containerImageVersionDefaults.values() | first | default({}) }}" + +- name: Filter images to process + ansible.builtin.set_fact: + _cifmw_fdp_update_container_images_image_entries: "{{ _cifmw_fdp_update_container_images_container_images | dict2items | selectattr('key', 'in', cifmw_fdp_update_container_images_images_to_scan) | list }}" + _cifmw_fdp_update_container_images_modified_images: [] + _cifmw_fdp_update_container_images_updated_cr_keys: [] + _cifmw_fdp_update_container_images_processed_images: 0 + +- name: Display images to process + ansible.builtin.debug: + msg: "Processing {{ _cifmw_fdp_update_container_images_image_entries | length }} images: {{ _cifmw_fdp_update_container_images_image_entries | map(attribute='key') | list | join(', ') }}" diff --git a/roles/fdp_update_container_images/tasks/main.yml b/roles/fdp_update_container_images/tasks/main.yml new file mode 100644 index 0000000000..903378e43a --- /dev/null +++ b/roles/fdp_update_container_images/tasks/main.yml @@ -0,0 +1,78 @@ +--- +# 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. + +# ============================================ +# Validate and Initialize +# ============================================ + +- name: Validate parameters and initialize + ansible.builtin.include_tasks: validate.yml + +# ============================================ +# Detect Registry +# ============================================ + +- name: Detect OpenShift registry URL + ansible.builtin.include_tasks: detect_registry.yml + +# ============================================ +# Configure Registry Authentication +# ============================================ + +- name: Configure registry CA certificate + ansible.builtin.include_tasks: configure_ca_cert.yml + +- name: Authenticate with registry + ansible.builtin.include_tasks: authenticate_registry.yml + +# ============================================ +# Fetch Images +# ============================================ + +- name: Fetch images to process + ansible.builtin.include_tasks: fetch_images.yml + +# ============================================ +# Process Each Image +# ============================================ + +- name: Build and push updated images + ansible.builtin.include_tasks: process_image.yml + loop: "{{ _cifmw_fdp_update_container_images_image_entries }}" + loop_control: + loop_var: image_entry + label: "{{ image_entry.key }}" + when: _cifmw_fdp_update_container_images_image_entries | length > 0 + +# ============================================ +# Summary +# ============================================ + +- name: Display summary + ansible.builtin.debug: + msg: + - "==========================================" + - "✓ Container image update complete" + - "Target package: {{ cifmw_fdp_update_container_images_target_package }}" + - "Images processed: {{ _cifmw_fdp_update_container_images_processed_images }}" + - "Updated: {{ _cifmw_fdp_update_container_images_updated_cr_keys | join(', ') if _cifmw_fdp_update_container_images_updated_cr_keys | length > 0 else 'None' }}" + - "==========================================" + +- name: Cleanup temporary directory + ansible.builtin.file: + path: "{{ _cifmw_fdp_update_container_images_temp_dir }}" + state: absent + when: _cifmw_fdp_update_container_images_temp_dir is defined diff --git a/roles/fdp_update_container_images/tasks/process_image.yml b/roles/fdp_update_container_images/tasks/process_image.yml new file mode 100644 index 0000000000..54b0173ce3 --- /dev/null +++ b/roles/fdp_update_container_images/tasks/process_image.yml @@ -0,0 +1,67 @@ +--- +# 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. + +- name: Create repository file + ansible.builtin.template: + src: repo.j2 + dest: "{{ _cifmw_fdp_update_container_images_temp_dir }}/{{ cifmw_fdp_update_container_images_repo_name }}.repo" + mode: '0644' + +- name: Create Dockerfile + ansible.builtin.template: + src: Dockerfile.j2 + dest: "{{ _cifmw_fdp_update_container_images_temp_dir }}/Dockerfile" + mode: '0644' + vars: + base_image: "{{ image_entry.value }}" + +- name: Generate image paths + ansible.builtin.set_fact: + _cifmw_fdp_update_container_images_new_image_path_external: "{{ cifmw_fdp_update_container_images_image_registry }}/{{ cifmw_fdp_update_container_images_namespace }}/{{ cifmw_fdp_update_container_images_image_name_prefix }}-{{ image_entry.key | lower }}-{{ ansible_date_time.epoch }}" + _cifmw_fdp_update_container_images_new_image_path_internal: "{{ cifmw_fdp_update_container_images_image_registry_internal }}/{{ cifmw_fdp_update_container_images_namespace }}/{{ cifmw_fdp_update_container_images_image_name_prefix }}-{{ image_entry.key | lower }}-{{ ansible_date_time.epoch }}" + +- name: Build and push image + containers.podman.podman_image: + name: "{{ _cifmw_fdp_update_container_images_new_image_path_external }}" + path: "{{ _cifmw_fdp_update_container_images_temp_dir }}" + build: + file: "{{ _cifmw_fdp_update_container_images_temp_dir }}/Dockerfile" + push: true + push_args: + dest: "{{ _cifmw_fdp_update_container_images_new_image_path_external }}" + state: build + +- name: Patch OpenStackVersion CR + kubernetes.core.k8s: + state: patched + api_version: core.openstack.org/v1beta1 + kind: OpenStackVersion + name: "{{ cifmw_fdp_update_container_images_openstack_cr_name }}" + namespace: "{{ cifmw_fdp_update_container_images_namespace }}" + definition: + spec: + customContainerImages: + "{{ image_entry.key }}": "{{ _cifmw_fdp_update_container_images_new_image_path_internal }}" + +- name: Update tracking + ansible.builtin.set_fact: + _cifmw_fdp_update_container_images_modified_images: "{{ _cifmw_fdp_update_container_images_modified_images + [image_entry.key ~ ': ' ~ _cifmw_fdp_update_container_images_new_image_path_internal] }}" + _cifmw_fdp_update_container_images_updated_cr_keys: "{{ _cifmw_fdp_update_container_images_updated_cr_keys + [image_entry.key] }}" + _cifmw_fdp_update_container_images_processed_images: "{{ _cifmw_fdp_update_container_images_processed_images | int + 1 }}" + +- name: Display progress + ansible.builtin.debug: + msg: "✓ Updated {{ image_entry.key }} ({{ _cifmw_fdp_update_container_images_processed_images }}/{{ _cifmw_fdp_update_container_images_image_entries | length }})" diff --git a/roles/fdp_update_container_images/tasks/validate.yml b/roles/fdp_update_container_images/tasks/validate.yml new file mode 100644 index 0000000000..061632c224 --- /dev/null +++ b/roles/fdp_update_container_images/tasks/validate.yml @@ -0,0 +1,38 @@ +--- +# 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. + +- name: Validate required parameters + ansible.builtin.assert: + that: + - cifmw_fdp_update_container_images_target_package is defined + - cifmw_fdp_update_container_images_target_package | length > 0 + - cifmw_fdp_update_container_images_repo_baseurl is defined + - cifmw_fdp_update_container_images_repo_baseurl | length > 0 + fail_msg: "Required: cifmw_fdp_update_container_images_target_package and cifmw_fdp_update_container_images_repo_baseurl" + +- name: Check oc command is available + ansible.builtin.command: oc version --client + changed_when: false + +- name: Create temporary directory + ansible.builtin.tempfile: + state: directory + prefix: "cifmw_fdp_update_build_" + register: _cifmw_fdp_update_container_images_temp_dir_result + +- name: Set temporary directory + ansible.builtin.set_fact: + _cifmw_fdp_update_container_images_temp_dir: "{{ cifmw_fdp_update_container_images_temp_dir if (cifmw_fdp_update_container_images_temp_dir is defined and cifmw_fdp_update_container_images_temp_dir | length > 0) else _cifmw_fdp_update_container_images_temp_dir_result.path }}" diff --git a/roles/fdp_update_container_images/templates/Dockerfile.j2 b/roles/fdp_update_container_images/templates/Dockerfile.j2 new file mode 100644 index 0000000000..f77f60d2c3 --- /dev/null +++ b/roles/fdp_update_container_images/templates/Dockerfile.j2 @@ -0,0 +1,3 @@ +FROM {{ base_image }} +COPY ./{{ cifmw_fdp_update_container_images_repo_name }}.repo /etc/yum.repos.d/ +RUN dnf update -y {{ cifmw_fdp_update_container_images_update_dnf_args }} {{ cifmw_fdp_update_container_images_target_package }}* diff --git a/roles/fdp_update_container_images/templates/repo.j2 b/roles/fdp_update_container_images/templates/repo.j2 new file mode 100644 index 0000000000..cee92cf1b2 --- /dev/null +++ b/roles/fdp_update_container_images/templates/repo.j2 @@ -0,0 +1,7 @@ +[{{ cifmw_fdp_update_container_images_repo_name }}] +name={{ cifmw_fdp_update_container_images_repo_name }} +baseurl={{ cifmw_fdp_update_container_images_repo_baseurl }} +enabled={{ cifmw_fdp_update_container_images_repo_enabled }} +gpgcheck={{ cifmw_fdp_update_container_images_repo_gpgcheck }} +priority={{ cifmw_fdp_update_container_images_repo_priority }} +sslverify={{ cifmw_fdp_update_container_images_repo_sslverify }} diff --git a/roles/fdp_update_edpm/README.md b/roles/fdp_update_edpm/README.md new file mode 100644 index 0000000000..59a11ee666 --- /dev/null +++ b/roles/fdp_update_edpm/README.md @@ -0,0 +1,184 @@ +# fdp_update_edpm + +Role for updating OpenStack EDPM (Edge Data Plane Management) nodes with custom container images and host packages. + +## Description + +This role provides a declarative approach to update EDPM nodes with: + +1. **Updates container images** by patching OpenStackDataPlaneNodeSet CRs with new image references +2. **Updates host packages** by configuring `edpm_bootstrap_packages` and `edpm_bootstrap_repos` in the nodeset +3. **Configures registry authentication** with OpenShift service account tokens +4. **Installs CA certificates** for secure registry access +5. **Optionally creates deployments** to apply the changes to EDPM nodes + +### Key Features + +- **Declarative approach**: Only modifies Kubernetes CRs, doesn't execute commands directly on EDPM nodes +- **Uses native EDPM capabilities**: Leverages `edpm_bootstrap` and `edpm_podman` roles from edpm-ansible +- **Secure by default**: Installs OpenShift CA certificates instead of using insecure registries +- **Flexible**: Supports updating containers, packages, or both +- **Idempotent**: Can be run multiple times safely + +## Requirements + +- OpenShift cluster with OpenStack operators installed +- Access to `oc` command +- OpenStackVersion CR with custom container images +- Custom repository with updated packages (if updating host packages) + +## Role Variables + +### General Configuration + +| Variable | Default | Description | +|----------|---------|-------------| +| `cifmw_fdp_update_edpm_namespace` | `"openstack"` | OpenShift namespace | +| `cifmw_fdp_update_edpm_nodeset_name` | `"all"` | NodeSet to update (`"all"` or specific name) | +| `cifmw_fdp_update_edpm_dry_run` | `false` | Show changes without applying | + +### Container Image Updates + +| Variable | Default | Description | +|----------|---------|-------------| +| `cifmw_fdp_update_edpm_containers_enabled` | `true` | Enable container image updates | +| `cifmw_fdp_update_edpm_image_registry` | `""` | External registry URL (auto-detected if empty) | +| `cifmw_fdp_update_edpm_image_variable_mapping` | See defaults | Mapping of image keys to EDPM variables | + +### Host Package Updates + +| Variable | Default | Description | +|----------|---------|-------------| +| `cifmw_fdp_update_edpm_packages_enabled` | `true` | Enable host package updates | +| `cifmw_fdp_update_edpm_repo_baseurl` | `""` | **REQUIRED** Repository base URL | +| `cifmw_fdp_update_edpm_repo_name` | `"fdp-update"` | Repository name | +| `cifmw_fdp_update_edpm_packages` | See defaults | List of packages to install/update | + +### Hypervisor Firewall Configuration + +| Variable | Default | Description | +|----------|---------|-------------| +| `cifmw_fdp_update_edpm_setup_hypervisor_firewall` | `true` | Enable/disable hypervisor firewall setup for registry access | +| `cifmw_fdp_update_compute_interface` | `"osp_trunk"` | Network interface on hypervisor connected to compute nodes (EDPM) | +| `cifmw_fdp_update_registry_interface` | `"ocpbm"` | Network interface on hypervisor connected to OpenShift/registry | +| `cifmw_fdp_update_compute_network` | `"192.168.122.0/24"` | Compute nodes network CIDR (source for NAT) | +| `cifmw_fdp_update_registry_network` | `"192.168.201.0/24"` | OpenShift/registry network CIDR (destination for NAT) | + +### Registry Configuration + +| Variable | Default | Description | +|----------|---------|-------------| +| `cifmw_fdp_update_edpm_configure_registry_ca` | `true` | Install OpenShift CA certificate via bootstrap command | +| `cifmw_fdp_update_edpm_configure_registry_auth` | `true` | Configure registry authentication | + +### Deployment Configuration + +| Variable | Default | Description | +|----------|---------|-------------| +| `cifmw_fdp_update_edpm_auto_deploy` | `true` | Automatically create deployment | +| `cifmw_fdp_update_edpm_deployment_per_nodeset` | `true` | Create separate deployment per nodeset | +| `cifmw_fdp_update_edpm_wait_for_deployment` | `true` | Wait for deployment to complete | +| `cifmw_fdp_update_edpm_deployment_timeout` | `3600` | Deployment timeout (seconds) | +| `cifmw_fdp_update_edpm_deployment_services` | See defaults | Services to run in deployment | + +## Dependencies + +None (uses native OpenStack Data Plane operators and edpm-ansible roles) + +## Example Playbook + +### Update both containers and packages + +```yaml +- hosts: localhost + roles: + - role: fdp_update_edpm + vars: + cifmw_fdp_update_edpm_namespace: openstack + cifmw_fdp_update_edpm_nodeset_name: openstack-edpm + cifmw_fdp_update_edpm_repo_baseurl: "http://example.com/repos/fdp-updates" + cifmw_fdp_update_edpm_packages: + - openvswitch3.5 + - openvswitch-selinux-extra-policy +``` + +### Update only containers + +```yaml +- hosts: localhost + roles: + - role: fdp_update_edpm + vars: + cifmw_fdp_update_edpm_packages_enabled: false + cifmw_fdp_update_edpm_containers_enabled: true +``` + +### Update only packages + +```yaml +- hosts: localhost + roles: + - role: fdp_update_edpm + vars: + cifmw_fdp_update_edpm_containers_enabled: false + cifmw_fdp_update_edpm_packages_enabled: true + cifmw_fdp_update_edpm_repo_baseurl: "http://example.com/repos/updates" +``` + +### Dry run (show changes without applying) + +```yaml +- hosts: localhost + roles: + - role: fdp_update_edpm + vars: + cifmw_fdp_update_edpm_dry_run: true +``` + +### Custom network configuration + +```yaml +- hosts: localhost + roles: + - role: fdp_update_edpm + vars: + cifmw_fdp_update_compute_interface: "br-ex" + cifmw_fdp_update_registry_interface: "br-ocp" + cifmw_fdp_update_compute_network: "10.0.0.0/24" + cifmw_fdp_update_registry_network: "172.16.0.0/24" +``` + +## How It Works + +1. **Validates parameters**: Ensures required variables are set +2. **Configures hypervisor firewall** (if enabled): Sets up iptables rules to allow EDPM nodes to access the OpenShift registry +3. **Fetches NodeSets**: Gets OpenStackDataPlaneNodeSet CRs from the cluster +4. **Fetches container images** (if enabled): Gets custom images from OpenStackVersion CR +5. **For each NodeSet**: + - Patches container image variables (e.g., `edpm_ovn_controller_agent_image`) + - Patches `edpm_bootstrap_packages` with packages to install + - Patches `edpm_bootstrap_repos` with custom repository configuration + - Configures registry authentication (`edpm_container_registry_logins`) + - Installs CA certificate via `edpm_bootstrap_command` (if enabled) +6. **Creates deployment** (if enabled): Creates OpenStackDataPlaneDeployment CR +7. **Waits for completion** (if enabled): Monitors deployment until Ready + +## Architecture: Declarative vs Imperative + +This role follows the **declarative** approach of Kubernetes/OpenStack: + +- ❌ **Does NOT** SSH to nodes and run `dnf install` directly +- ❌ **Does NOT** SSH to nodes and run `systemctl restart` directly +- ✅ **Does** patch NodeSet CRs with desired state +- ✅ **Does** let OpenStack Data Plane Operator apply the changes +- ✅ **Does** use native `edpm_bootstrap` role for package installation +- ✅ **Does** use native `edpm_podman` role for container management +- ✅ **Does** use `edpm_bootstrap_command` for CA certificate installation + +## License + +Apache 2.0 + +## Author Information + +Red Hat OpenStack CI Framework Team diff --git a/roles/fdp_update_edpm/defaults/main.yml b/roles/fdp_update_edpm/defaults/main.yml new file mode 100644 index 0000000000..cc87b399c6 --- /dev/null +++ b/roles/fdp_update_edpm/defaults/main.yml @@ -0,0 +1,132 @@ +--- +# 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. + +# ============================================ +# General Configuration +# ============================================ + +# OpenShift namespace where EDPM resources are deployed +cifmw_fdp_update_edpm_namespace: "openstack" + +# NodeSet selector - can be a specific name or 'all' for all nodesets +cifmw_fdp_update_edpm_nodeset_name: "all" + +# Dry run - show changes without applying +cifmw_fdp_update_edpm_dry_run: false + +# ============================================ +# Container Image Updates +# ============================================ + +# Enable/disable container image updates +cifmw_fdp_update_edpm_containers_enabled: true + +# Image registry URL (auto-detected from OpenShift if empty) +cifmw_fdp_update_edpm_image_registry: "" + +# Mapping of control plane image keys to EDPM ansible variables +# Only ovnControllerImage is used on EDPM compute nodes +cifmw_fdp_update_edpm_image_variable_mapping: + ovnControllerImage: edpm_ovn_controller_agent_image + +# ============================================ +# Host Package Updates +# ============================================ + +# Enable/disable host package updates +cifmw_fdp_update_edpm_packages_enabled: true + +# Repository configuration for host package updates +cifmw_fdp_update_edpm_repo_name: "fdp-update" +cifmw_fdp_update_edpm_repo_baseurl: "" # REQUIRED if packages_enabled is true +cifmw_fdp_update_edpm_repo_enabled: true +cifmw_fdp_update_edpm_repo_gpgcheck: false +cifmw_fdp_update_edpm_repo_priority: 1 + +# Packages to update on the host +# These will be added to edpm_bootstrap_packages in the nodeset +cifmw_fdp_update_edpm_packages: + - openvswitch3.5 + - openvswitch-selinux-extra-policy + +# ============================================ +# Hypervisor Firewall Configuration +# ============================================ + +# Enable/disable hypervisor firewall setup for registry access +cifmw_fdp_update_edpm_setup_hypervisor_firewall: true + +# Network interface on hypervisor connected to compute nodes (EDPM) +cifmw_fdp_update_compute_interface: "osp_trunk" + +# Network interface on hypervisor connected to OpenShift/registry +cifmw_fdp_update_registry_interface: "ocpbm" + +# Compute nodes network CIDR (source for NAT) +cifmw_fdp_update_compute_network: "192.168.122.0/24" + +# OpenShift/registry network CIDR (destination for NAT) +cifmw_fdp_update_registry_network: "192.168.201.0/24" + +# ============================================ +# Registry Configuration +# ============================================ + +# Configure OpenShift registry CA certificate on EDPM nodes +cifmw_fdp_update_edpm_configure_registry_ca: true + +# Configure registry authentication automatically +# Uses 'oc create token' or 'oc whoami -t' to get a service account token +cifmw_fdp_update_edpm_configure_registry_auth: true + +# ============================================ +# Deployment Configuration +# ============================================ + +# Automatically create OpenStackDataPlaneDeployment after updating NodeSets +# Creates a single deployment for all updated NodeSets +cifmw_fdp_update_edpm_auto_deploy: true + +# Wait for deployment to complete before continuing +cifmw_fdp_update_edpm_wait_for_deployment: true + +# Timeout for deployment completion (in seconds) +# Default: 3600 seconds (60 minutes / 1 hour) +cifmw_fdp_update_edpm_deployment_timeout: 3600 + +# Polling interval when waiting for deployment (in seconds) +cifmw_fdp_update_edpm_deployment_poll_interval: 30 + +# Services to run in the deployment +# For updates, we need to: +# 1. bootstrap - Install host packages and configure repos +# 2. configure-os - Configure registry authentication +# 3. configure-network - Ensure network is configured +# 4. Service-specific services (ovn, nova, etc) - Pull updated images and restart +cifmw_fdp_update_edpm_deployment_services: + - bootstrap # MUST be first to install packages and configure repos + - configure-os # MUST be second to authenticate before pulling images + - configure-network + - ovn + +# ============================================ +# Internal Variables (do not override) +# ============================================ + +_cifmw_fdp_update_edpm_updated_images: {} +_cifmw_fdp_update_edpm_nodesets: [] +_cifmw_fdp_update_edpm_updated_nodesets: [] +_cifmw_fdp_update_edpm_external_registry: "" diff --git a/roles/fdp_update_edpm/meta/main.yml b/roles/fdp_update_edpm/meta/main.yml new file mode 100644 index 0000000000..3bfc3f70f4 --- /dev/null +++ b/roles/fdp_update_edpm/meta/main.yml @@ -0,0 +1,39 @@ +--- +# 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. + +galaxy_info: + author: Red Hat + description: Update OpenStack EDPM container images and host packages with FDP updates + company: Red Hat + license: Apache-2.0 + min_ansible_version: "2.15" + platforms: + - name: Fedora + versions: + - all + - name: EL + versions: + - "9" + galaxy_tags: + - openstack + - edpm + - dataplane + - kubernetes + - openshift + - rpm + - containers + +dependencies: [] diff --git a/roles/fdp_update_edpm/tasks/configure_ca_cert.yml b/roles/fdp_update_edpm/tasks/configure_ca_cert.yml new file mode 100644 index 0000000000..759a96b0fd --- /dev/null +++ b/roles/fdp_update_edpm/tasks/configure_ca_cert.yml @@ -0,0 +1,65 @@ +--- +# 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 file configures OpenShift registry CA certificate on EDPM nodes +# Embeds CA certificate installation in edpm_bootstrap_command + +- name: Get OpenShift ingress CA certificate + kubernetes.core.k8s_info: + api_version: v1 + kind: Secret + name: router-ca + namespace: openshift-ingress-operator + register: _cifmw_fdp_update_edpm_ca_cert_result + +- name: Decode CA certificate + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_ca_cert: "{{ _cifmw_fdp_update_edpm_ca_cert_result.resources[0].data['tls.crt'] | b64decode }}" + +- name: Get current edpm_bootstrap_command from nodeset + kubernetes.core.k8s_info: + api_version: dataplane.openstack.org/v1beta1 + kind: OpenStackDataPlaneNodeSet + name: "{{ _cifmw_fdp_update_edpm_current_nodeset_name }}" + namespace: "{{ cifmw_fdp_update_edpm_namespace }}" + register: _cifmw_fdp_update_edpm_current_bootstrap_result + failed_when: false + +- name: Build bootstrap command with CA certificate installation + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_bootstrap_with_ca: | + # Install OpenShift registry CA certificate + cat > /etc/pki/ca-trust/source/anchors/openshift-registry-ca.crt <<'EOF' + {{ _cifmw_fdp_update_edpm_ca_cert }} + EOF + update-ca-trust extract + + {{ _cifmw_fdp_update_edpm_current_bootstrap_result.resources[0].spec.nodeTemplate.ansible.ansibleVars.edpm_bootstrap_command | default('') if (_cifmw_fdp_update_edpm_current_bootstrap_result.resources | length > 0) else '' }} + +- name: Patch NodeSet with updated bootstrap command + kubernetes.core.k8s: + state: patched + api_version: dataplane.openstack.org/v1beta1 + kind: OpenStackDataPlaneNodeSet + name: "{{ _cifmw_fdp_update_edpm_current_nodeset_name }}" + namespace: "{{ cifmw_fdp_update_edpm_namespace }}" + definition: + spec: + nodeTemplate: + ansible: + ansibleVars: + edpm_bootstrap_command: "{{ _cifmw_fdp_update_edpm_bootstrap_with_ca }}" + when: not cifmw_fdp_update_edpm_dry_run diff --git a/roles/fdp_update_edpm/tasks/create_deployment.yml b/roles/fdp_update_edpm/tasks/create_deployment.yml new file mode 100644 index 0000000000..ed17139a32 --- /dev/null +++ b/roles/fdp_update_edpm/tasks/create_deployment.yml @@ -0,0 +1,61 @@ +--- +# 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. + +- name: Set deployment name + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_deployment_name: "edpm-fdp-update-{{ ansible_date_time.epoch }}" + +- name: Create OpenStackDataPlaneDeployment + kubernetes.core.k8s: + state: present + api_version: dataplane.openstack.org/v1beta1 + kind: OpenStackDataPlaneDeployment + definition: + metadata: + name: "{{ _cifmw_fdp_update_edpm_deployment_name }}" + namespace: "{{ cifmw_fdp_update_edpm_namespace }}" + spec: + nodeSets: "{{ _cifmw_fdp_update_edpm_updated_nodesets }}" + servicesOverride: "{{ cifmw_fdp_update_edpm_deployment_services }}" + +- name: Display deployment information + ansible.builtin.debug: + msg: + - "Created deployment: {{ _cifmw_fdp_update_edpm_deployment_name }}" + - "NodeSets: {{ _cifmw_fdp_update_edpm_updated_nodesets }}" + - "Services: {{ cifmw_fdp_update_edpm_deployment_services }}" + +- name: Wait for deployment to complete + when: cifmw_fdp_update_edpm_wait_for_deployment | bool + block: + - name: Wait for deployment Ready condition + kubernetes.core.k8s_info: + api_version: dataplane.openstack.org/v1beta1 + kind: OpenStackDataPlaneDeployment + name: "{{ _cifmw_fdp_update_edpm_deployment_name }}" + namespace: "{{ cifmw_fdp_update_edpm_namespace }}" + register: _cifmw_fdp_update_edpm_deployment_result + until: >- + _cifmw_fdp_update_edpm_deployment_result.resources | length > 0 and + _cifmw_fdp_update_edpm_deployment_result.resources[0].status.conditions | + selectattr('type', 'equalto', 'Ready') | + map(attribute='status') | first | default('False') == 'True' + retries: "{{ (cifmw_fdp_update_edpm_deployment_timeout / cifmw_fdp_update_edpm_deployment_poll_interval) | int }}" + delay: "{{ cifmw_fdp_update_edpm_deployment_poll_interval }}" + + - name: Display deployment completion + ansible.builtin.debug: + msg: "Deployment {{ _cifmw_fdp_update_edpm_deployment_name }} completed successfully" diff --git a/roles/fdp_update_edpm/tasks/fetch_nodesets.yml b/roles/fdp_update_edpm/tasks/fetch_nodesets.yml new file mode 100644 index 0000000000..7c2f4fb086 --- /dev/null +++ b/roles/fdp_update_edpm/tasks/fetch_nodesets.yml @@ -0,0 +1,32 @@ +--- +# 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. + +- name: Get OpenStackDataPlaneNodeSets + kubernetes.core.k8s_info: + api_version: dataplane.openstack.org/v1beta1 + kind: OpenStackDataPlaneNodeSet + name: "{{ cifmw_fdp_update_edpm_nodeset_name if cifmw_fdp_update_edpm_nodeset_name != 'all' else omit }}" + namespace: "{{ cifmw_fdp_update_edpm_namespace }}" + register: _cifmw_fdp_update_edpm_nodesets_result + +- name: Parse NodeSets + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_nodesets: "{{ _cifmw_fdp_update_edpm_nodesets_result.resources }}" + +- name: Fail if no NodeSets found + ansible.builtin.fail: + msg: "No OpenStackDataPlaneNodeSets found in namespace {{ cifmw_fdp_update_edpm_namespace }}" + when: _cifmw_fdp_update_edpm_nodesets | length == 0 diff --git a/roles/fdp_update_edpm/tasks/main.yml b/roles/fdp_update_edpm/tasks/main.yml new file mode 100644 index 0000000000..9c5f29eb0f --- /dev/null +++ b/roles/fdp_update_edpm/tasks/main.yml @@ -0,0 +1,83 @@ +--- +# 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. + +# ============================================ +# Validate and Initialize +# ============================================ + +- name: Validate parameters and initialize + ansible.builtin.include_tasks: validate.yml + +# ============================================ +# Setup Hypervisor Firewall +# ============================================ + +- name: Setup hypervisor firewall for registry access + ansible.builtin.include_tasks: setup_hypervisor_firewall.yml + when: cifmw_fdp_update_edpm_setup_hypervisor_firewall | default(true) | bool + +# ============================================ +# Fetch NodeSets +# ============================================ + +- name: Fetch EDPM NodeSets + ansible.builtin.include_tasks: fetch_nodesets.yml + +# ============================================ +# Update Container Images (Optional) +# ============================================ + +- name: Update container images + when: cifmw_fdp_update_edpm_containers_enabled | bool + ansible.builtin.include_tasks: update_container_images.yml + +# ============================================ +# Process Each NodeSet +# ============================================ + +- name: Process each NodeSet + ansible.builtin.include_tasks: process_nodeset.yml + loop: "{{ _cifmw_fdp_update_edpm_nodesets }}" + loop_control: + loop_var: nodeset + label: "{{ nodeset.metadata.name }}" + +# ============================================ +# Deploy Updates to EDPM Nodes (Optional) +# ============================================ + +- name: Deploy updates to EDPM nodes + when: + - cifmw_fdp_update_edpm_auto_deploy | bool + - not cifmw_fdp_update_edpm_dry_run | bool + - _cifmw_fdp_update_edpm_updated_nodesets | default([]) | length > 0 + ansible.builtin.include_tasks: create_deployment.yml + +# ============================================ +# Summary +# ============================================ + +- name: Display update summary + ansible.builtin.debug: + msg: + - "==============================================" + - "EDPM Update Summary" + - "==============================================" + - "Updated {{ _cifmw_fdp_update_edpm_updated_nodesets | length }} NodeSet(s): {{ _cifmw_fdp_update_edpm_updated_nodesets }}" + - "Container images updated: {{ cifmw_fdp_update_edpm_containers_enabled }}" + - "Host packages updated: {{ cifmw_fdp_update_edpm_packages_enabled }}" + - "==============================================" + when: not cifmw_fdp_update_edpm_dry_run diff --git a/roles/fdp_update_edpm/tasks/process_nodeset.yml b/roles/fdp_update_edpm/tasks/process_nodeset.yml new file mode 100644 index 0000000000..43d9cadd96 --- /dev/null +++ b/roles/fdp_update_edpm/tasks/process_nodeset.yml @@ -0,0 +1,159 @@ +--- +# 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. + +- name: Set NodeSet name + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_current_nodeset_name: "{{ nodeset.metadata.name }}" + +# ============================================ +# Patch Container Images +# ============================================ + +- name: Patch container images in nodeset + when: + - cifmw_fdp_update_edpm_containers_enabled | bool + - _cifmw_fdp_update_edpm_updated_images is defined + - _cifmw_fdp_update_edpm_updated_images | length > 0 + block: + - name: Build EDPM image variables patch + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_image_vars_patch: {} + + - name: Add each EDPM variable to patch + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_image_vars_patch: >- + {{ + _cifmw_fdp_update_edpm_image_vars_patch | combine({ + cifmw_fdp_update_edpm_image_variable_mapping[item.key]: item.value + }) + }} + loop: "{{ _cifmw_fdp_update_edpm_updated_images | dict2items }}" + loop_control: + label: "{{ item.key }}" + + - name: Apply container images using k8s patch + kubernetes.core.k8s: + state: patched + api_version: dataplane.openstack.org/v1beta1 + kind: OpenStackDataPlaneNodeSet + name: "{{ _cifmw_fdp_update_edpm_current_nodeset_name }}" + namespace: "{{ cifmw_fdp_update_edpm_namespace }}" + definition: + spec: + nodeTemplate: + ansible: + ansibleVars: "{{ _cifmw_fdp_update_edpm_image_vars_patch }}" + when: + - not cifmw_fdp_update_edpm_dry_run + - _cifmw_fdp_update_edpm_image_vars_patch | length > 0 + +# ============================================ +# Patch Host Packages and Repositories +# ============================================ + +- name: Patch host packages and repositories in nodeset + when: cifmw_fdp_update_edpm_packages_enabled | bool + ansible.builtin.include_tasks: update_host_packages.yml + +# ============================================ +# Configure Registry Authentication +# ============================================ + +- name: Configure registry authentication + when: + - not cifmw_fdp_update_edpm_dry_run + - cifmw_fdp_update_edpm_configure_registry_auth | bool + - _cifmw_fdp_update_edpm_external_registry is defined + - _cifmw_fdp_update_edpm_external_registry | length > 0 + block: + - name: Get authentication token for OpenShift registry + ansible.builtin.command: oc whoami -t + register: _cifmw_fdp_update_edpm_oc_token_result + changed_when: false + failed_when: false + + - name: Get existing registry logins + kubernetes.core.k8s_info: + api_version: dataplane.openstack.org/v1beta1 + kind: OpenStackDataPlaneNodeSet + name: "{{ _cifmw_fdp_update_edpm_current_nodeset_name }}" + namespace: "{{ cifmw_fdp_update_edpm_namespace }}" + register: _cifmw_fdp_update_edpm_current_logins_result + failed_when: false + + - name: Parse existing registry logins + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_existing_logins: >- + {{ + _cifmw_fdp_update_edpm_current_logins_result.resources[0].spec.nodeTemplate.ansible.ansibleVars.edpm_container_registry_logins | default({}) + if (_cifmw_fdp_update_edpm_current_logins_result.resources | length > 0) + else {} + }} + + - name: Merge with new registry login + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_merged_logins: >- + {{ + _cifmw_fdp_update_edpm_existing_logins | combine({ + _cifmw_fdp_update_edpm_external_registry: { + 'serviceaccount': _cifmw_fdp_update_edpm_oc_token_result.stdout + } + }) + }} + when: + - _cifmw_fdp_update_edpm_oc_token_result.rc == 0 + - _cifmw_fdp_update_edpm_oc_token_result.stdout | length > 0 + + - name: Build registry authentication patch + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_registry_auth_patch: + spec: + nodeTemplate: + ansible: + ansibleVars: + edpm_container_registry_logins: "{{ _cifmw_fdp_update_edpm_merged_logins }}" + when: + - _cifmw_fdp_update_edpm_oc_token_result.rc == 0 + - _cifmw_fdp_update_edpm_oc_token_result.stdout | length > 0 + + - name: Apply registry authentication configuration + kubernetes.core.k8s: + state: patched + api_version: dataplane.openstack.org/v1beta1 + kind: OpenStackDataPlaneNodeSet + name: "{{ _cifmw_fdp_update_edpm_current_nodeset_name }}" + namespace: "{{ cifmw_fdp_update_edpm_namespace }}" + definition: "{{ _cifmw_fdp_update_edpm_registry_auth_patch }}" + when: + - _cifmw_fdp_update_edpm_oc_token_result.rc == 0 + - _cifmw_fdp_update_edpm_oc_token_result.stdout | length > 0 + +# ============================================ +# Configure Registry CA Certificate +# ============================================ + +- name: Configure registry CA certificate + when: cifmw_fdp_update_edpm_configure_registry_ca | bool + ansible.builtin.include_tasks: configure_ca_cert.yml + +# ============================================ +# Record NodeSet as Processed +# ============================================ + +- name: Record NodeSet as processed + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_updated_nodesets: "{{ _cifmw_fdp_update_edpm_updated_nodesets + [_cifmw_fdp_update_edpm_current_nodeset_name] }}" + when: not cifmw_fdp_update_edpm_dry_run diff --git a/roles/fdp_update_edpm/tasks/setup_hypervisor_firewall.yml b/roles/fdp_update_edpm/tasks/setup_hypervisor_firewall.yml new file mode 100644 index 0000000000..e22b98b7f5 --- /dev/null +++ b/roles/fdp_update_edpm/tasks/setup_hypervisor_firewall.yml @@ -0,0 +1,59 @@ +--- +# 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. + +# ============================================ +# Setup Hypervisor Firewall for Registry Access +# ============================================ +# This task configures iptables rules on the hypervisor to allow +# compute nodes (EDPM) to access the OpenShift registry for pulling +# container images during FDP updates. + +- name: Allow traffic from {{ cifmw_fdp_update_compute_interface }} to {{ cifmw_fdp_update_registry_interface }} (compute -> registry) + become: true + ansible.builtin.iptables: + chain: FORWARD + in_interface: "{{ cifmw_fdp_update_compute_interface }}" + out_interface: "{{ cifmw_fdp_update_registry_interface }}" + jump: ACCEPT + action: insert + rule_num: '1' + +- name: Allow return traffic from {{ cifmw_fdp_update_registry_interface }} to {{ cifmw_fdp_update_compute_interface }} (registry -> compute) + become: true + ansible.builtin.iptables: + chain: FORWARD + in_interface: "{{ cifmw_fdp_update_registry_interface }}" + out_interface: "{{ cifmw_fdp_update_compute_interface }}" + ctstate: RELATED,ESTABLISHED + jump: ACCEPT + action: insert + rule_num: '1' + +- name: Enable NAT for compute nodes to access registry + become: true + ansible.builtin.iptables: + table: nat + chain: POSTROUTING + source: "{{ cifmw_fdp_update_compute_network }}" + destination: "{{ cifmw_fdp_update_registry_network }}" + out_interface: "{{ cifmw_fdp_update_registry_interface }}" + jump: MASQUERADE + +- name: Persist firewall rules + become: true + community.general.iptables_state: + state: saved + path: /etc/sysconfig/iptables diff --git a/roles/fdp_update_edpm/tasks/update_container_images.yml b/roles/fdp_update_edpm/tasks/update_container_images.yml new file mode 100644 index 0000000000..dc58cda5f5 --- /dev/null +++ b/roles/fdp_update_edpm/tasks/update_container_images.yml @@ -0,0 +1,89 @@ +--- +# 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. + +# ============================================ +# Fetch Updated Container Images +# ============================================ + +- name: Get OpenStackVersion CR list + kubernetes.core.k8s_info: + api_version: core.openstack.org/v1beta1 + kind: OpenStackVersion + namespace: "{{ cifmw_fdp_update_edpm_namespace }}" + register: _cifmw_fdp_update_edpm_osv_result + +- name: Fail if no OpenStackVersion CR found + ansible.builtin.fail: + msg: "No OpenStackVersion CR found in namespace {{ cifmw_fdp_update_edpm_namespace }}" + when: _cifmw_fdp_update_edpm_osv_result.resources | length == 0 + +- name: Parse and filter EDPM-relevant custom images + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_updated_images: >- + {{ + (_cifmw_fdp_update_edpm_osv_result.resources[0].spec.customContainerImages | default({})) | dict2items | + selectattr('key', 'in', cifmw_fdp_update_edpm_image_variable_mapping.keys()) | + items2dict + }} + +# ============================================ +# Convert Internal Registry URLs to External +# ============================================ + +- name: Convert internal registry URLs to external for EDPM compute nodes + when: _cifmw_fdp_update_edpm_updated_images | length > 0 + block: + - name: Determine external registry URL + block: + - name: Try to auto-detect registry route if not configured + kubernetes.core.k8s_info: + api_version: route.openshift.io/v1 + kind: Route + name: default-route + namespace: openshift-image-registry + register: _cifmw_fdp_update_edpm_registry_route_result + failed_when: false + when: cifmw_fdp_update_edpm_image_registry is not defined or cifmw_fdp_update_edpm_image_registry | length == 0 + + - name: Set external registry URL + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_external_registry: >- + {%- if cifmw_fdp_update_edpm_image_registry is defined and cifmw_fdp_update_edpm_image_registry | length > 0 -%} + {{ cifmw_fdp_update_edpm_image_registry }} + {%- elif _cifmw_fdp_update_edpm_registry_route_result.resources | default([]) | length > 0 -%} + {{ _cifmw_fdp_update_edpm_registry_route_result.resources[0].spec.host }} + {%- else -%} + UNDEFINED + {%- endif -%} + + - name: Fail if no external registry URL could be determined + ansible.builtin.fail: + msg: | + Cannot determine external registry URL! + EDPM compute nodes require an external registry URL to pull images. + Please set: cifmw_fdp_update_edpm_image_registry + when: _cifmw_fdp_update_edpm_external_registry == 'UNDEFINED' + + - name: Convert URLs (handle all internal registry variations) + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_updated_images: "{{ dict(_cifmw_fdp_update_edpm_updated_images.keys() | zip(_cifmw_fdp_update_edpm_updated_images.values() | map('regex_replace', 'image-registry\\.openshift-image-registry\\.svc\\.cluster\\.local:5000', _cifmw_fdp_update_edpm_external_registry) | map('regex_replace', 'image-registry\\.openshift-image-registry\\.svc:5000', _cifmw_fdp_update_edpm_external_registry) | list)) }}" + +- name: Display container images to update + ansible.builtin.debug: + msg: + - "Container images found in OpenStackVersion CR:" + - "{{ _cifmw_fdp_update_edpm_updated_images }}" + when: _cifmw_fdp_update_edpm_updated_images | length > 0 diff --git a/roles/fdp_update_edpm/tasks/update_host_packages.yml b/roles/fdp_update_edpm/tasks/update_host_packages.yml new file mode 100644 index 0000000000..6e8d62d243 --- /dev/null +++ b/roles/fdp_update_edpm/tasks/update_host_packages.yml @@ -0,0 +1,109 @@ +--- +# 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 file patches the nodeset with edpm_bootstrap_* variables +# The actual package installation happens during deployment via edpm_bootstrap role + +# ============================================ +# Get Current Bootstrap Configuration +# ============================================ + +- name: Get current bootstrap configuration from nodeset + kubernetes.core.k8s_info: + api_version: dataplane.openstack.org/v1beta1 + kind: OpenStackDataPlaneNodeSet + name: "{{ _cifmw_fdp_update_edpm_current_nodeset_name }}" + namespace: "{{ cifmw_fdp_update_edpm_namespace }}" + register: _cifmw_fdp_update_edpm_current_bootstrap_result + failed_when: false + +# ============================================ +# Merge New Packages with Existing +# ============================================ + +- name: Parse current bootstrap packages + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_bootstrap_packages_list: >- + {{ + _cifmw_fdp_update_edpm_current_bootstrap_result.resources[0].spec.nodeTemplate.ansible.ansibleVars.edpm_bootstrap_packages | default([]) + if (_cifmw_fdp_update_edpm_current_bootstrap_result.resources | length > 0) + else [] + }} + +- name: Merge new packages with existing packages + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_merged_packages: "{{ (_cifmw_fdp_update_edpm_bootstrap_packages_list + cifmw_fdp_update_edpm_packages) | unique }}" + +# ============================================ +# Build Repository Configuration +# ============================================ + +- name: Parse current bootstrap repos + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_bootstrap_repos_list: >- + {{ + _cifmw_fdp_update_edpm_current_bootstrap_result.resources[0].spec.nodeTemplate.ansible.ansibleVars.edpm_bootstrap_repos | default([]) + if (_cifmw_fdp_update_edpm_current_bootstrap_result.resources | length > 0) + else [] + }} + +- name: Build new repository configuration + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_new_repo: + name: "{{ cifmw_fdp_update_edpm_repo_name }}" + baseurl: "{{ cifmw_fdp_update_edpm_repo_baseurl }}" + enabled: "{{ cifmw_fdp_update_edpm_repo_enabled | int }}" + gpgcheck: "{{ cifmw_fdp_update_edpm_repo_gpgcheck | int }}" + priority: "{{ cifmw_fdp_update_edpm_repo_priority }}" + +- name: Check if repo already exists in nodeset + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_repo_exists: "{{ _cifmw_fdp_update_edpm_bootstrap_repos_list | selectattr('name', 'equalto', cifmw_fdp_update_edpm_repo_name) | list | length > 0 }}" + +- name: Remove existing repo if it exists + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_bootstrap_repos_list: "{{ _cifmw_fdp_update_edpm_bootstrap_repos_list | rejectattr('name', 'equalto', cifmw_fdp_update_edpm_repo_name) | list }}" + when: _cifmw_fdp_update_edpm_repo_exists | bool + +- name: Add new repo to repos list + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_merged_repos: "{{ _cifmw_fdp_update_edpm_bootstrap_repos_list + [_cifmw_fdp_update_edpm_new_repo] }}" + +# ============================================ +# Patch NodeSet with Bootstrap Configuration +# ============================================ + +- name: Patch nodeset with bootstrap packages and repos + kubernetes.core.k8s: + state: patched + api_version: dataplane.openstack.org/v1beta1 + kind: OpenStackDataPlaneNodeSet + name: "{{ _cifmw_fdp_update_edpm_current_nodeset_name }}" + namespace: "{{ cifmw_fdp_update_edpm_namespace }}" + definition: + spec: + nodeTemplate: + ansible: + ansibleVars: + edpm_bootstrap_packages: "{{ _cifmw_fdp_update_edpm_merged_packages }}" + edpm_bootstrap_repos: "{{ _cifmw_fdp_update_edpm_merged_repos }}" + when: not cifmw_fdp_update_edpm_dry_run + +- name: Display packages and repos configuration + ansible.builtin.debug: + msg: + - "Packages to install on host: {{ _cifmw_fdp_update_edpm_merged_packages }}" + - "Repositories configured: {{ _cifmw_fdp_update_edpm_merged_repos | map(attribute='name') | list }}" diff --git a/roles/fdp_update_edpm/tasks/validate.yml b/roles/fdp_update_edpm/tasks/validate.yml new file mode 100644 index 0000000000..2036e66ab6 --- /dev/null +++ b/roles/fdp_update_edpm/tasks/validate.yml @@ -0,0 +1,33 @@ +--- +# 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. + +- name: Validate package update configuration + ansible.builtin.assert: + that: + - cifmw_fdp_update_edpm_repo_baseurl is defined + - cifmw_fdp_update_edpm_repo_baseurl | length > 0 + - cifmw_fdp_update_edpm_packages is defined + - cifmw_fdp_update_edpm_packages | length > 0 + fail_msg: "Package updates require: cifmw_fdp_update_edpm_repo_baseurl and cifmw_fdp_update_edpm_packages" + when: cifmw_fdp_update_edpm_packages_enabled | bool + +- name: Verify oc command is available + ansible.builtin.command: oc version --client + changed_when: false + +- name: Initialize updated nodesets tracking list + ansible.builtin.set_fact: + _cifmw_fdp_update_edpm_updated_nodesets: [] diff --git a/zuul.d/molecule.yaml b/zuul.d/molecule.yaml index 10decae4bd..2ed0cc6a41 100644 --- a/zuul.d/molecule.yaml +++ b/zuul.d/molecule.yaml @@ -927,6 +927,24 @@ - ^.config/molecule/.* name: cifmw-molecule-cleanup_openstack parent: cifmw-molecule-noop +- job: + files: + - ^common-requirements.txt + - ^test-requirements.txt + - ^roles/fdp_update_container_images/.* + - ^ci/playbooks/molecule.* + - ^.config/molecule/.* + name: cifmw-molecule-fdp_update_container_images + parent: cifmw-molecule-noop +- job: + files: + - ^common-requirements.txt + - ^test-requirements.txt + - ^roles/fdp_update_edpm/.* + - ^ci/playbooks/molecule.* + - ^.config/molecule/.* + name: cifmw-molecule-fdp_update_edpm + parent: cifmw-molecule-noop - job: files: - ^common-requirements.txt diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml index f68e2c3351..b213366beb 100644 --- a/zuul.d/projects.yaml +++ b/zuul.d/projects.yaml @@ -55,6 +55,8 @@ - cifmw-molecule-edpm_kustomize - cifmw-molecule-edpm_prepare - cifmw-molecule-env_op_images + - cifmw-molecule-fdp_update_container_images + - cifmw-molecule-fdp_update_edpm - cifmw-molecule-federation - cifmw-molecule-fix_python_encodings - cifmw-molecule-hci_prepare