Skip to content

Commit c5c5b5e

Browse files
committed
Add fdp_update_container_images role for control plane updates
Implement container image rebuild automation for FDP updates: - Role fdp_update_container_images: Rebuilds container images with updated packages * Includes Molecule tests for validation * Jinja2 templates for Dockerfile and repo configuration - Integration in post-deployment.yml with variable validation - Zuul CI configuration for automated testing This role enables updating Fast Data Path components in OpenStack control plane containers by rebuilding images with updated RPM packages from a specified repository. Part of the broader FDP update workflow, focusing specifically on container image management. Assisted-By: Claude <[email protected]> Signed-off-by: Miguel Angel Nieto Jimenez <[email protected]>
1 parent 84c46b6 commit c5c5b5e

File tree

16 files changed

+619
-0
lines changed

16 files changed

+619
-0
lines changed

docs/dictionary/en-custom.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ ezzmy
186186
favorit
187187
fbqufbqkfbzxrja
188188
fci
189+
fdp
189190
fedoraproject
190191
fil
191192
filesystem

post-deployment.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,34 @@
2626
tags:
2727
- compliance
2828

29+
# FDP Update - OpenStack package updates across all layers
30+
- name: FDP Update - Validate required variables
31+
when: cifmw_fdp_update_enabled | default(false) | bool
32+
tags:
33+
- fdp-update
34+
block:
35+
- name: Validate required variables are set
36+
ansible.builtin.assert:
37+
that:
38+
- cifmw_fdp_update_target_package is defined
39+
- cifmw_fdp_update_target_package | length > 0
40+
- cifmw_fdp_update_repo_baseurl is defined
41+
- cifmw_fdp_update_repo_baseurl | length > 0
42+
fail_msg: |
43+
Required variables are missing!
44+
45+
You must set:
46+
- cifmw_fdp_update_target_package: Name of the RPM package to update
47+
- cifmw_fdp_update_repo_baseurl: Repository base URL containing the updated package
48+
success_msg: "Required variables validated successfully"
49+
50+
- name: Update control plane container images
51+
ansible.builtin.import_role:
52+
name: fdp_update_container_images
53+
vars:
54+
cifmw_fdp_update_container_images_target_package: "{{ cifmw_fdp_update_target_package }}"
55+
cifmw_fdp_update_container_images_repo_baseurl: "{{ cifmw_fdp_update_repo_baseurl }}"
56+
2957
- name: Run compliance scan for computes
3058
hosts: "{{ groups['computes'] | default ([]) }}"
3159
gather_facts: true
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# fdp_update_container_images
2+
3+
Ansible role to update specific RPM packages in OpenStack container images by rebuilding them with custom repositories.
4+
5+
This role automates the process of:
6+
1. Fetching container images from OpenStackVersion CR
7+
2. Checking if target package exists in each image
8+
3. Building new images with updated packages from custom repository
9+
4. Pushing updated images to OpenShift internal registry
10+
5. Patching OpenStackVersion CR to use the new images
11+
12+
## Privilege escalation
13+
None - Runs as the user executing Ansible
14+
15+
## Parameters
16+
17+
* `cifmw_fdp_update_container_images_basedir`: (String) Base directory. Defaults to `cifmw_basedir` which defaults to `~/ci-framework-data`.
18+
* `cifmw_fdp_update_container_images_namespace`: (String) OpenShift namespace where OpenStack is deployed. Defaults to `openstack`.
19+
* `cifmw_fdp_update_container_images_openstack_cr_name`: (String) Name of the OpenStackVersion CR. Defaults to `controlplane`.
20+
* `cifmw_fdp_update_container_images_target_package`: (String) Name of the RPM package to update (e.g., `ovn24.03`). **Required**.
21+
* `cifmw_fdp_update_container_images_repo_name`: (String) Repository name. Defaults to `custom-repo`.
22+
* `cifmw_fdp_update_container_images_repo_baseurl`: (String) Repository base URL. **Required**.
23+
* `cifmw_fdp_update_container_images_repo_enabled`: (Integer) Enable repository (0 or 1). Defaults to `1`.
24+
* `cifmw_fdp_update_container_images_repo_gpgcheck`: (Integer) Enable GPG check (0 or 1). Defaults to `0`.
25+
* `cifmw_fdp_update_container_images_repo_priority`: (Integer) Repository priority. Defaults to `0`.
26+
* `cifmw_fdp_update_container_images_repo_sslverify`: (Integer) Enable SSL verification (0 or 1). Defaults to `0`.
27+
* `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.
28+
* `cifmw_fdp_update_container_images_image_registry_internal`: (String) Internal OpenShift image registry URL. Defaults to `image-registry.openshift-image-registry.svc:5000`.
29+
* `cifmw_fdp_update_container_images_image_name_prefix`: (String) Prefix for new image names. Defaults to `fdp-update`.
30+
* `cifmw_fdp_update_container_images_temp_dir`: (String) Temporary directory for build context. Auto-generated if not specified.
31+
* `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 }}`.
32+
33+
## Examples
34+
35+
### Update OVN package in all containers
36+
```yaml
37+
---
38+
- hosts: localhost
39+
vars:
40+
cifmw_fdp_update_container_images_target_package: "ovn24.03"
41+
cifmw_fdp_update_container_images_repo_name: "custom-repo"
42+
cifmw_fdp_update_container_images_repo_baseurl: "http://example.com/custom-repo/"
43+
cifmw_fdp_update_container_images_namespace: "openstack"
44+
roles:
45+
- role: "fdp_update_container_images"
46+
```
47+
48+
### Update with custom registry and image prefix
49+
```yaml
50+
---
51+
- hosts: localhost
52+
vars:
53+
cifmw_fdp_update_container_images_target_package: "ovn24.03"
54+
cifmw_fdp_update_container_images_repo_baseurl: "http://custom-repo.example.com/repo/"
55+
cifmw_fdp_update_container_images_image_registry: "registry.example.com"
56+
cifmw_fdp_update_container_images_image_name_prefix: "ovn-hotfix"
57+
roles:
58+
- role: "fdp_update_container_images"
59+
```
60+
61+
### Update with specific DNF arguments
62+
```yaml
63+
---
64+
- hosts: localhost
65+
vars:
66+
cifmw_fdp_update_container_images_target_package: "neutron-ovn-metadata-agent"
67+
cifmw_fdp_update_container_images_repo_baseurl: "http://custom-repo.example.com/repo/"
68+
cifmw_fdp_update_container_images_update_dnf_args: "--disablerepo='*' --enablerepo={{ cifmw_fdp_update_container_images_repo_name }} --nobest"
69+
roles:
70+
- role: "fdp_update_container_images"
71+
```
72+
73+
## How it works
74+
75+
1. **Registry Setup**:
76+
- Enables the default route for OpenShift image registry
77+
- Auto-detects the registry hostname or uses the configured value
78+
2. **Authentication**: Obtains a token from OpenShift and authenticates with the internal registry using TLS
79+
3. **Image Discovery**: Queries the OpenStackVersion CR for all container images
80+
4. **Package Check**: For each image, creates a temporary container to check if the target package is installed
81+
5. **Image Build**: If the package exists, builds a new image with the updated package from the custom repository
82+
6. **Registry Push**: Pushes the new image to the OpenShift internal registry
83+
7. **CR Update**: Patches the OpenStackVersion CR's `spec.customContainerImages` field with the new image reference
84+
8. **Summary**: Provides a summary of all updated images
85+
86+
## Requirements
87+
88+
* OpenShift CLI (`oc`) must be available
89+
* Podman must be installed and accessible
90+
* User must have permissions to:
91+
- Create tokens in the target namespace
92+
- Get and patch OpenStackVersion CRs
93+
- Push images to the internal registry
94+
- Patch image registry configuration (`configs.imageregistry.operator.openshift.io/cluster`)
95+
96+
## Notes
97+
98+
* The role uses podman to build and push images with TLS verification
99+
* Each updated image gets a unique tag with timestamp: `<prefix>-<image-key>-<timestamp>`
100+
* Only images containing the target package will be updated
101+
* The role cleans up temporary containers automatically
102+
* All build contexts are created in a temporary directory that is cleaned up after execution
103+
* The role automatically configures the OpenShift image registry for external access:
104+
- Enables the default route if not already enabled
105+
- Auto-detects the registry hostname from the route
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
# ============================================================================
18+
# Base Configuration
19+
# ============================================================================
20+
21+
# Base directory for artifacts and temporary files
22+
cifmw_fdp_update_container_images_basedir: "{{ cifmw_basedir | default(ansible_user_dir ~ '/ci-framework-data') }}"
23+
24+
# OpenShift namespace where OpenStack is deployed
25+
cifmw_fdp_update_container_images_namespace: "openstack"
26+
27+
# Name of the OpenStackVersion custom resource
28+
cifmw_fdp_update_container_images_openstack_cr_name: "controlplane"
29+
30+
# Target package to update (REQUIRED - must be set by user)
31+
cifmw_fdp_update_container_images_target_package: ""
32+
33+
# List of images to update with the target package
34+
# Only these images will be updated (no package scanning is performed)
35+
cifmw_fdp_update_container_images_images_to_scan:
36+
- ovnControllerImage
37+
- ovnControllerOvsImage
38+
- ovnNbDbclusterImage
39+
- ovnNorthdImage
40+
- ovnSbDbclusterImage
41+
- ceilometerSgcoreImage
42+
43+
# Repository configuration
44+
cifmw_fdp_update_container_images_repo_name: "custom-repo"
45+
cifmw_fdp_update_container_images_repo_baseurl: "" # REQUIRED - must be set by user
46+
cifmw_fdp_update_container_images_repo_enabled: 1
47+
cifmw_fdp_update_container_images_repo_gpgcheck: 0
48+
cifmw_fdp_update_container_images_repo_priority: 0
49+
cifmw_fdp_update_container_images_repo_sslverify: 0
50+
51+
# Image registry configuration
52+
# External registry URL (for compute nodes/EDPM and pushing images)
53+
# Leave empty to auto-detect external route from OpenShift cluster
54+
cifmw_fdp_update_container_images_image_registry: ""
55+
56+
# Internal registry URL (for OpenShift pods to pull images)
57+
# This is auto-detected and should not normally need to be changed
58+
cifmw_fdp_update_container_images_image_registry_internal: "image-registry.openshift-image-registry.svc:5000"
59+
60+
# Image naming
61+
cifmw_fdp_update_container_images_image_name_prefix: "fdp-update"
62+
63+
# Temporary directory for build context
64+
cifmw_fdp_update_container_images_temp_dir: ""
65+
66+
# DNF update arguments
67+
cifmw_fdp_update_container_images_update_dnf_args: "--disablerepo='*' --enablerepo={{ cifmw_fdp_update_container_images_repo_name }}"
68+
69+
# Internal variables (do not override)
70+
_cifmw_fdp_update_container_images_modified_images: []
71+
_cifmw_fdp_update_container_images_updated_cr_keys: []
72+
_cifmw_fdp_update_container_images_total_images: 0
73+
_cifmw_fdp_update_container_images_processed_images: 0
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
galaxy_info:
18+
author: Red Hat
19+
description: Update RPM packages in OpenStack container images
20+
company: Red Hat
21+
license: Apache-2.0
22+
min_ansible_version: "2.15"
23+
platforms:
24+
- name: Fedora
25+
versions:
26+
- all
27+
- name: EL
28+
versions:
29+
- "9"
30+
galaxy_tags:
31+
- openstack
32+
- containers
33+
- kubernetes
34+
- openshift
35+
- podman
36+
- rpm
37+
38+
dependencies: []
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
- name: Create registry token
18+
ansible.builtin.command: oc create token builder -n {{ cifmw_fdp_update_container_images_namespace }}
19+
register: _cifmw_fdp_update_container_images_token
20+
changed_when: false
21+
22+
- name: Authenticate podman with TLS verification
23+
containers.podman.podman_login:
24+
username: unused
25+
password: "{{ _cifmw_fdp_update_container_images_token.stdout }}"
26+
registry: "{{ cifmw_fdp_update_container_images_image_registry }}"
27+
no_log: true
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
- name: Get OpenShift ingress CA certificate
18+
kubernetes.core.k8s_info:
19+
api_version: v1
20+
kind: Secret
21+
name: router-ca
22+
namespace: openshift-ingress-operator
23+
register: _cifmw_fdp_update_container_images_ca_secret
24+
25+
- name: Extract CA certificate from secret
26+
ansible.builtin.set_fact:
27+
_cifmw_fdp_update_container_images_ca_cert_b64:
28+
stdout: "{{ _cifmw_fdp_update_container_images_ca_secret.resources[0].data['tls.crt'] }}"
29+
30+
- name: Decode CA certificate
31+
ansible.builtin.copy:
32+
content: "{{ _cifmw_fdp_update_container_images_ca_cert_b64.stdout | b64decode }}"
33+
dest: /etc/pki/ca-trust/source/anchors/openshift-registry-ca.crt
34+
mode: '0644'
35+
become: true
36+
37+
- name: Update CA trust
38+
ansible.builtin.command: update-ca-trust extract
39+
become: true
40+
changed_when: true
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
- name: Enable OpenShift registry route
18+
kubernetes.core.k8s:
19+
api_version: imageregistry.operator.openshift.io/v1
20+
kind: Config
21+
name: cluster
22+
state: patched
23+
definition:
24+
spec:
25+
defaultRoute: true
26+
register: _cifmw_fdp_update_container_images_enable_route
27+
failed_when: false
28+
29+
- name: Wait for route
30+
ansible.builtin.pause:
31+
seconds: 10
32+
when: _cifmw_fdp_update_container_images_enable_route.changed
33+
changed_when: false
34+
35+
- name: Get registry route
36+
kubernetes.core.k8s_info:
37+
api_version: route.openshift.io/v1
38+
kind: Route
39+
name: default-route
40+
namespace: openshift-image-registry
41+
register: _cifmw_fdp_update_container_images_route_info
42+
failed_when: false
43+
44+
- name: Extract registry host from route
45+
ansible.builtin.set_fact:
46+
_cifmw_fdp_update_container_images_route:
47+
stdout: "{{ _cifmw_fdp_update_container_images_route_info.resources[0].spec.host if _cifmw_fdp_update_container_images_route_info.resources | length > 0 else '' }}"
48+
49+
- name: Set registry URL
50+
ansible.builtin.set_fact:
51+
cifmw_fdp_update_container_images_image_registry: "{{ _cifmw_fdp_update_container_images_route.stdout }}"
52+
when: _cifmw_fdp_update_container_images_route.stdout | length > 0
53+
54+
- name: Verify registry URL
55+
ansible.builtin.fail:
56+
msg: "Failed to determine registry URL. Set cifmw_fdp_update_container_images_image_registry manually."
57+
when: cifmw_fdp_update_container_images_image_registry is not defined or cifmw_fdp_update_container_images_image_registry | length == 0

0 commit comments

Comments
 (0)