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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions ci/playbooks/edpm_baremetal_update/minor-update-edpm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
# CI playbook for OpenStack minor version updates.
# This playbook performs a minor version update of an OpenStack deployment
# using index images and install_yamls make targets.
# This playbook depends on content provider variables from CI jobs.
# It runs in the same execution context as deploy-edpm.yml,
# so it can use the install_yamls_makes role that was generated during bootstrap.

- name: OpenStack minor version update
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: false
tasks:
- name: Set cifmw_basedir if not defined
ansible.builtin.set_fact:
cifmw_basedir: "{{ cifmw_basedir | default(ansible_user_dir ~ '/ci-framework-data') }}"

- name: Load parameters files
ansible.builtin.include_vars:
dir: "{{ cifmw_basedir }}/artifacts/parameters"

- name: Run make openstack_cleanup
vars:
make_openstack_cleanup_env: "{{ cifmw_minor_update_env }}"
make_openstack_cleanup_dryrun: false
ansible.builtin.include_role:
name: 'install_yamls_makes'
tasks_from: 'make_openstack_cleanup'
ignore_errors: true # Continue even if cleanup fails

- name: Run make openstack_wait (minor update)
vars:
make_openstack_wait_env: "{{ cifmw_minor_update_env }}"
make_openstack_wait_dryrun: false
ansible.builtin.include_role:
name: 'install_yamls_makes'
tasks_from: 'make_openstack_wait'

- name: Run make openstack_init (minor update)
vars:
make_openstack_init_env: "{{ cifmw_minor_update_env }}"
make_openstack_init_dryrun: false
ansible.builtin.include_role:
name: 'install_yamls_makes'
tasks_from: 'make_openstack_init'

- name: Wait for availableVersion to be different from deployedVersion
kubernetes.core.k8s_info:
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
api_key: "{{ cifmw_openshift_token | default(omit) }}"
context: "{{ cifmw_openshift_context | default(omit) }}"
api_version: core.openstack.org/v1beta1
kind: OpenStackVersion
namespace: "{{ cifmw_install_yamls_defaults['NAMESPACE'] | default('openstack') }}"
register: openstackversion_wait_info
retries: 10
delay: 60
until: >
openstackversion_wait_info.resources is defined and
openstackversion_wait_info.resources | length > 0 and
openstackversion_wait_info.resources[0].status.availableVersion is defined and
openstackversion_wait_info.resources[0].status.deployedVersion is defined and
openstackversion_wait_info.resources[0].status.availableVersion != openstackversion_wait_info.resources[0].status.deployedVersion

- name: Get available version from OpenStackVersion CR
ansible.builtin.set_fact:
cifmw_minor_update_target_version: "{{ openstackversion_wait_info.resources[0].status.availableVersion }}"

- name: Patch OpenStackVersion CR availableVersion
vars:
make_openstack_patch_version_env: "{{ cifmw_minor_update_env }}"
make_openstack_patch_version_dryrun: false
ansible.builtin.include_role:
name: 'install_yamls_makes'
tasks_from: 'make_openstack_patch_version'

- name: Set vars related to update_containers content provider
when:
- content_provider_os_registry_url is defined
- content_provider_os_registry_url != 'null'
ansible.builtin.set_fact:
cifmw_update_containers_registry: "{{ content_provider_os_registry_url | split('/') | first }}"
cifmw_update_containers_org: "{{ content_provider_os_registry_url | split('/') | last }}"
cifmw_update_containers_tag: "{{ content_provider_dlrn_md5_hash }}"
cifmw_update_containers_openstack: true

- name: Prepare and patch OpenStackVersion CR for update
vars:
cifmw_update_containers_metadata: "controlplane"
cifmw_update_containers: true
ansible.builtin.include_role:
name: update_containers
when: >-
(cifmw_update_containers_edpm_image_url is defined and
cifmw_update_containers_openstack is defined and
cifmw_update_containers_openstack | bool) or
(cifmw_update_containers_ansibleee_image_url is defined) or
(cifmw_update_containers_openstack is defined and
cifmw_update_containers_openstack | bool) or
(cifmw_update_containers_watcher is defined and
cifmw_update_containers_watcher | bool)

- name: Run make openstack_update_run
vars:
make_openstack_update_run_env: "{{ cifmw_minor_update_env }}"
make_openstack_update_run_params:
OPENSTACK_VERSION: "{{ cifmw_minor_update_target_version }}"
make_openstack_update_run_dryrun: false
ansible.builtin.include_role:
name: 'install_yamls_makes'
tasks_from: 'make_openstack_update_run'

- name: Verify deployed version matches target version
kubernetes.core.k8s_info:
kubeconfig: "{{ cifmw_openshift_kubeconfig }}"
api_key: "{{ cifmw_openshift_token | default(omit) }}"
context: "{{ cifmw_openshift_context | default(omit) }}"
api_version: core.openstack.org/v1beta1
kind: OpenStackVersion
namespace: "{{ cifmw_install_yamls_defaults['NAMESPACE'] | default('openstack') }}"
register: openstackversion_verify_info
until: >
openstackversion_verify_info.resources is defined and
openstackversion_verify_info.resources | length > 0 and
openstackversion_verify_info.resources[0].status.deployedVersion is defined and
openstackversion_verify_info.resources[0].status.deployedVersion == cifmw_minor_update_target_version
retries: 5
delay: 2

- name: Display update verification result
ansible.builtin.debug:
msg: >-
Update verification successful: Target version {{ cifmw_minor_update_target_version }}
matches deployed version {{ openstackversion_verify_info.resources[0].status.deployedVersion }}
174 changes: 174 additions & 0 deletions ci/playbooks/edpm_baremetal_update/run.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
---
- name: "Run ci/playbooks/edpm_baremetal_update/run.yml"
hosts: "{{ cifmw_zuul_target_host | default('all') }}"
gather_facts: true
tasks:
- name: Filter out host if needed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(non-blocking) question: Why do we need this filtering out? Is it because a zuul contraint?
Is this not already done in L3?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's added in other existing playbooks with 49c4916, so I continued using it.

when:
- cifmw_zuul_target_host is defined
- cifmw_zuul_target_host != 'all'
- inventory_hostname != cifmw_zuul_target_host
ansible.builtin.meta: end_host

- name: Check for edpm-ansible.yml file
ansible.builtin.stat:
path: "{{ ansible_user_dir }}/ci-framework-data/artifacts/edpm-ansible.yml"
register: edpm_file

- name: Check if new ssh keypair exists
ansible.builtin.include_role:
name: recognize_ssh_keypair

- name: Add crc node in local inventory
ansible.builtin.add_host:
name: crc
ansible_ssh_private_key_file: "{{ ansible_user_dir }}/.crc/machines/crc/{{ crc_ssh_keypair }}"
ansible_ssh_user: core
ansible_host: api.crc.testing

- name: Ensure we know ssh hosts
ansible.builtin.shell:
cmd: "ssh-keyscan {{ hostvars[item].ansible_host }} >> ~/.ssh/known_hosts"
loop: "{{ hostvars.keys() | reject('equalto', 'localhost') }}"

- name: Inject CRC in zuul_inventory
block:
- name: Load zuul_inventory
register: _inventory
ansible.builtin.slurp:
path: "{{ ansible_user_dir }}/ci-framework-data/artifacts/zuul_inventory.yml"

- name: Inject CRC in zuul_inventory.yml
vars:
_crc:
all:
hosts:
crc: "{{ dict(hostvars.crc) }}"
_updated: >-
{{
_inventory.content | b64decode | from_yaml | combine(_crc, recursive=true)
}}
ansible.builtin.copy:
dest: "{{ ansible_user_dir }}/ci-framework-data/artifacts/zuul_inventory.yml"
content: "{{ _updated | to_nice_yaml }}"
mode: "0644"

- name: Set default pre-update tag if not provided
ansible.builtin.set_fact:
cifmw_minor_update_pre_update_tag: "{{ cifmw_minor_update_pre_update_tag | default('18.0-fr4-latest') }}"

- name: Get pre-update index image digest from tag
ansible.builtin.shell: >-
skopeo inspect
docker://quay.io/openstack-k8s-operators/openstack-operator-index:{{ cifmw_minor_update_pre_update_tag }}
| jq -r '.Digest'
register: fr4_digest_result
changed_when: false
failed_when: fr4_digest_result.rc != 0

- name: Set FR4 index image using digest from tag
ansible.builtin.set_fact:
cifmw_minor_update_fr4_index_image: >-
quay.io/openstack-k8s-operators/openstack-operator-index@{{ fr4_digest_result.stdout | trim }}

- name: Get minor update index image from content provider or use default
ansible.builtin.set_fact:
cifmw_minor_update_index_image: >-
{{
cifmw_operator_build_output.operators['openstack-operator'].image_catalog
if (cifmw_operator_build_output is defined and
cifmw_operator_build_output.operators is defined and
'openstack-operator' in cifmw_operator_build_output.operators)
else cifmw_minor_update_fr4_index_image
}}

- name: Override operator build output with FR4 index image for Phase 1
ansible.builtin.set_fact:
cifmw_operator_build_output_fr4: >-
{{
{
'cifmw_operator_build_output': {
'operators': {
'openstack-operator': {
'image_catalog': cifmw_minor_update_fr4_index_image
}
}
}
}
}}

- name: Phase 1 - Deploy with FR4 index image using deploy-edpm.yml
block:
- name: Write FR4 operator build output to temporary file
ansible.builtin.copy:
dest: "{{ ansible_user_dir }}/ci-framework-data/artifacts/operator_build_output_fr4.yml"
content: "{{ cifmw_operator_build_output_fr4 | to_nice_yaml }}"
mode: "0644"

- name: Perform Podified and EDPM deployment on compute nodes with virtual baremetal (FR4)
ansible.builtin.command:
chdir: "{{ ansible_user_dir }}/src/github.com/openstack-k8s-operators/ci-framework"
cmd: >-
ansible-playbook deploy-edpm.yml
Copy link
Contributor

@evallesp evallesp Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@danpawlik are we OK by executing here ansible-playbook commands?
I was thinking of spliting the zuul job in three:
run:
- ci/playbooks/edpm_baremetal_update/prepare.yml
- deploy-edpm.yml
- ci/playbooks/edpm_baremetal_update/update.yml

so basically, moving the run to a prepare playbook, until the execution of deploy-edpm and then going by running the update.
WDYT @danpawlik ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we can't use deploy_edpm.yml as is, as we don't want to update container images from content provider in openstackversion during deploy. It has to be done after the deploy and midway through update.

-i "{{ ansible_user_dir }}/ci-framework-data/artifacts/zuul_inventory.yml"
-e @group_vars/all.yml
-e @scenarios/centos-9/base.yml
-e @scenarios/centos-9/edpm_baremetal_deployment_ci.yml
{%- if edpm_file.stat.exists %}
-e @{{ ansible_user_dir }}/ci-framework-data/artifacts/edpm-ansible.yml
{%- endif %}
{%- if cifmw_extras is defined %}
{%- for extra_var in cifmw_extras %}
-e "{{ extra_var }}"
{%- endfor %}
{%- endif %}
-e "@{{ ansible_user_dir }}/ci-framework-data/artifacts/parameters/zuul-params.yml"
-e "@{{ ansible_user_dir }}/ci-framework-data/artifacts/operator_build_output_fr4.yml"
-e "cifmw_prepare_openstackversion=false"

# Load install_yamls environment from parameters file created by deploy-edpm.yml bootstrap
# deploy-edpm.yml runs on target host, so files are on target host
# Use slurp to read from target host, then parse with from_yaml
- name: Read install-yamls-params.yml file from target host
ansible.builtin.slurp:
src: "{{ ansible_user_dir }}/ci-framework-data/artifacts/parameters/install-yamls-params.yml"
register: install_yamls_params_content
when: cifmw_install_yamls_environment is not defined

- name: Load install_yamls environment from parameters file
ansible.builtin.set_fact:
cifmw_install_yamls_environment: "{{ (install_yamls_params_content.content | b64decode | from_yaml)['cifmw_install_yamls_environment'] | default({}) }}"
cifmw_install_yamls_defaults: "{{ (install_yamls_params_content.content | b64decode | from_yaml)['cifmw_install_yamls_defaults'] | default({}) }}"
when:
- cifmw_install_yamls_environment is not defined
- install_yamls_params_content.content is defined

- name: Set install_yamls environment for minor update phase
ansible.builtin.set_fact:
cifmw_minor_update_env: >-
{{
(cifmw_install_yamls_environment | default({})) |
combine({'PATH': cifmw_path | default(ansible_user_dir ~ '/.crc/bin:' ~ ansible_user_dir ~ '/.crc/bin/oc:' ~ ansible_user_dir ~ '/bin:' ~ ansible_env.PATH)}) |
combine({'OPENSTACK_IMG': cifmw_minor_update_index_image}) |
combine({'BMO_CLEANUP': false})
}}

# Phase 2: Run update playbook in same execution context as deploy-edpm.yml
# This allows it to use install_yamls_makes role that was generated during Phase 1 bootstrap
- name: Phase 2 - Update with index image for minor update
block:
- name: Write minor update environment to temporary file
ansible.builtin.copy:
dest: "{{ ansible_user_dir }}/ci-framework-data/artifacts/parameters/minor_update_env.yml"
content: "{{ {'cifmw_minor_update_env': cifmw_minor_update_env} | to_nice_yaml }}"
mode: "0644"

- name: Run Phase 2 update playbook for minor update
ansible.builtin.command:
chdir: "{{ ansible_user_dir }}/src/github.com/openstack-k8s-operators/ci-framework"
cmd: >-
ansible-playbook ci/playbooks/edpm_baremetal_update/minor-update-edpm.yml
-i "{{ ansible_user_dir }}/ci-framework-data/artifacts/zuul_inventory.yml"
-e @group_vars/all.yml
-e "@{{ ansible_user_dir }}/ci-framework-data/artifacts/parameters/zuul-params.yml"
-e "@{{ ansible_user_dir }}/ci-framework-data/artifacts/parameters/minor_update_env.yml"
7 changes: 4 additions & 3 deletions roles/edpm_prepare/tasks/kustomize_and_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,19 @@
cifmw_update_containers_registry: "{{ content_provider_os_registry_url | split('/') | first }}"
cifmw_update_containers_org: "{{ content_provider_os_registry_url | split('/') | last }}"
cifmw_update_containers_tag: "{{ content_provider_dlrn_md5_hash }}"
cifmw_update_containers_openstack: true
cifmw_update_containers_openstack: "{{ cifmw_edpm_prepare_update_containers | default(true) }}"

- name: Prepare OpenStackVersion CR
when: >-
(cifmw_update_containers_edpm_image_url is defined and
(cifmw_prepare_openstackversion | default(true) | bool) and
((cifmw_update_containers_edpm_image_url is defined and
cifmw_update_containers_openstack is defined and
cifmw_update_containers_openstack | bool) or
(cifmw_update_containers_ansibleee_image_url is defined) or
(cifmw_update_containers_openstack is defined and
cifmw_update_containers_openstack | bool) or
(cifmw_update_containers_watcher is defined and
cifmw_update_containers_watcher | bool)
cifmw_update_containers_watcher | bool))
vars:
cifmw_update_containers_metadata: "{{ _ctlplane_name }}"
ansible.builtin.include_role:
Expand Down
15 changes: 15 additions & 0 deletions zuul.d/edpm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@
cifmw_edpm_deploy_baremetal_bootc: true
cifmw_update_containers: true

# Virtual Baremetal job with CRC for minor update testing.
# First deploys with FR4 index image, then updates with PR index image.
- job:
name: cifmw-crc-podified-edpm-baremetal-minor-update
nodeset: centos-9-crc-2-48-0-6xlarge
parent: cifmw-base-crc-openstack
run: ci/playbooks/edpm_baremetal_update/run.yml
dependencies:
- openstack-k8s-operators-content-provider
vars:
crc_parameters: "--memory 32000 --disk-size 240 --cpus 12"
cifmw_manage_secrets_pullsecret_content: '{}'
cifmw_rhol_crc_binary_folder: "/usr/local/bin"
cifmw_minor_update_pre_update_tag: "18.0-fr3-latest"

# Podified galera job
- job:
name: cifmw-crc-podified-galera-deployment
Expand Down
1 change: 1 addition & 0 deletions zuul.d/project-templates.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
- cifmw-molecule
- podified-multinode-edpm-deployment-crc: *content_provider
- cifmw-crc-podified-edpm-baremetal: *content_provider
- cifmw-crc-podified-edpm-baremetal-minor-update: *content_provider
- podified-multinode-hci-deployment-crc: *content_provider
- cifmw-multinode-tempest: *content_provider
- cifmw-pod-zuul-files
Expand Down