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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion reproducer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@
- not cifmw_deploy_reproducer_env | default(true) | bool
ansible.builtin.include_role:
name: reproducer
tasks_from: premetal.yml
tasks_from: >-
{{ (cifmw_reproducer_native_control | default(false) | bool) |
ternary('premetal_native.yml', 'premetal.yml') }}

- name: Run deployment if instructed to
when:
Expand Down
28 changes: 28 additions & 0 deletions roles/reproducer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,34 @@ bare metal SNO deployments to the `bm_sno` role.
* `cifmw_reproducer_computes_rhos_release_args`: (String) Arguments to use when installing rhos-release repos on compute nodes. Not defined by default, and `cifmw_repo_setup_rhos_release_args` is used instead.
* `cifmw_bm_sno`: (Bool) Enable agent-based bare metal OCP SNO deployment instead of libvirt/dev-scripts. Defaults to `false`.

### Native control for an existing PreMetal environment

`cifmw_reproducer_native_control: true` selects the native preparation path in
`reproducer.yml` when `cifmw_deploy_reproducer_env: false`. The caller registers
the existing hypervisor and `controller-0` in the running Ansible inventory and
supplies these required transport parameters:

* `cifmw_reproducer_native_source_host`: Inventory name of the build node containing the current job's `configs`, `secrets` and `src` directories.
* `cifmw_reproducer_native_source_home`: Absolute home directory containing those directories on the build node.
* `cifmw_reproducer_native_source_ssh_config`: Absolute SSH configuration path on that build node, with routes and keys for the hypervisor and `controller-0`.

The source node needs rsync; it pushes current job data to both targets using
its supplied SSH configuration. The hypervisor needs Python 3 and PyYAML for
the existing `merge_yaml_override.py` utility. The caller must validate that
the deployed architecture matches the scenario being requested.

The native path preserves the existing parameter-refresh merge: mappings are
merged recursively, lists/scalars are replaced, current `zuul_vars.yaml` is
applied before `extra_variable_files`, and excluded parameter keys are removed
first. File transfers use native modules and private remote temporary files;
they do not assume that executor paths also exist on managed nodes. Pull-secret
refresh and deployment argument construction reuse the existing task files.

This flattens reproducer preparation into the caller's Ansible session. The
deployment and post-deployment wrapper commands remain in `reproducer.yml` and
are explicit residual subprocess boundaries. The default remains `false`, so
the local reproducer and legacy PreMetal path retain their existing behavior.

### Advanced parameters
Those parameters shouldn't be used, unless the user is able to understand potential issues in their environment.

Expand Down
1 change: 1 addition & 0 deletions roles/reproducer/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ cifmw_reproducer_compute_repos: []
cifmw_reproducer_compute_set_repositories: true
cifmw_reproducer_repositories_path: "src"
cifmw_reproducer_play_extravars: []
cifmw_reproducer_native_control: false
cifmw_reproducer_provision_net: ocppr
cifmw_reproducer_supported_hypervisor_os:
CentOS:
Expand Down
18 changes: 18 additions & 0 deletions roles/reproducer/tasks/native_merge_file.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
- name: Merge an override with the existing framework utility
ansible.builtin.command:
argv:
- python3
- "{{ cifmw_reproducer_native_vars_dir.path }}/merge_yaml_override.py"
- "{{ cifmw_reproducer_native_vars_dir.path }}/merged.yml"
- "{{ cifmw_reproducer_native_override_file }}"
register: cifmw_reproducer_native_merge_result
changed_when: false
no_log: true

- name: Store the merged parameters without evaluating their Jinja expressions
ansible.builtin.copy:
content: "{{ cifmw_reproducer_native_merge_result.stdout }}"
dest: "{{ cifmw_reproducer_native_vars_dir.path }}/merged.yml"
mode: "0600"
no_log: true
68 changes: 68 additions & 0 deletions roles/reproducer/tasks/native_overwrite_vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
- name: Create a private merge workspace on the hypervisor
ansible.builtin.tempfile:
state: directory
prefix: cifmw-native-vars-
register: cifmw_reproducer_native_vars_dir

- name: Refresh controller parameters without controller-local file assumptions
block:
- name: Read existing reproducer variables from controller-0
delegate_to: controller-0
ansible.builtin.slurp:
src: "{{ cifmw_reproducer_controller_basedir }}/parameters/reproducer-variables.yml"
register: cifmw_reproducer_native_saved_vars
no_log: true

- name: Stage existing reproducer variables on the hypervisor
ansible.builtin.copy:
content: "{{ cifmw_reproducer_native_saved_vars.content | b64decode }}"
dest: "{{ cifmw_reproducer_native_vars_dir.path }}/merged.yml"
mode: "0600"
no_log: true

- name: Remove parameters excluded by the current job
when: exclude_discovered_files | default([]) | length > 0
cifmw.general.strip_dict_keys:
src: "{{ cifmw_reproducer_native_vars_dir.path }}/merged.yml"
keys_from: >-
{{ exclude_discovered_files |
map('regex_replace', '^(.*)$', ansible_user_dir ~ '/configs/\1') | list }}
no_log: true

- name: Stage the existing framework YAML merge utility
ansible.builtin.copy:
src: merge_yaml_override.py
dest: "{{ cifmw_reproducer_native_vars_dir.path }}/merge_yaml_override.py"
mode: "0600"

- name: Apply current job and extra variable overrides in their existing order
ansible.builtin.include_tasks: native_merge_file.yml
loop: "{{ [ansible_user_dir ~ '/configs/zuul_vars.yaml'] + (extra_variable_files | default([])) }}"
loop_control:
loop_var: cifmw_reproducer_native_override_file
label: "{{ cifmw_reproducer_native_override_file | basename }}"

- name: Read merged reproducer variables
ansible.builtin.slurp:
src: "{{ cifmw_reproducer_native_vars_dir.path }}/merged.yml"
register: cifmw_reproducer_native_merged_vars
no_log: true

- name: Write current parameters back to controller-0
delegate_to: controller-0
ansible.builtin.copy:
content: "{{ cifmw_reproducer_native_merged_vars.content | b64decode }}"
dest: "{{ cifmw_reproducer_controller_basedir }}/{{ item }}"
mode: "0664"
backup: true
loop:
- parameters/reproducer-variables.yml
- artifacts/parameters/custom-params.yml
no_log: true
always:
- name: Remove the private hypervisor merge workspace
ansible.builtin.file:
path: "{{ cifmw_reproducer_native_vars_dir.path }}"
state: absent
no_log: true
50 changes: 50 additions & 0 deletions roles/reproducer/tasks/premetal_native.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
# The source build node, hypervisor and controller-0 are distinct from the
# Ansible control process. The caller supplies working SSH routes for all three.
- name: Validate native reproducer transport inputs
ansible.builtin.assert:
that:
- cifmw_reproducer_native_source_host is defined
- cifmw_reproducer_native_source_home is defined
- cifmw_reproducer_native_source_ssh_config is defined
- inventory_hostname != 'controller-0'
- "'controller-0' in hostvars"
quiet: true

- name: Synchronize current job data from the build node
delegate_to: "{{ cifmw_reproducer_native_source_host }}"
become: false
ansible.posix.synchronize:
src: "{{ cifmw_reproducer_native_source_home }}/{{ item.1 }}/"
dest: "{{ cifmw_reproducer_controller_user }}@{{ item.0 }}:{{ ansible_user_dir }}/{{ item.1 }}/"
archive: true
recursive: true
set_remote_user: false
rsync_opts:
- "--rsh=ssh -F {{ cifmw_reproducer_native_source_ssh_config | quote }}"
loop: "{{ [inventory_hostname, 'controller-0'] | product(['configs', 'secrets', 'src']) | list }}"
loop_control:
label: "{{ item.0 }}/{{ item.1 }}"
no_log: true

- name: Refresh reproducer parameters using remote-safe native tasks
ansible.builtin.include_tasks: native_overwrite_vars.yml

- name: Refresh the cluster pull secret
ansible.builtin.include_tasks: overwrite_pull_secret.yml

- name: Compute additional deployment arguments with secrets
ansible.builtin.include_tasks: compute_additional_args.yml
loop: >-
{{ cifmw_deploy_architecture_secret_files |
default([ansible_user_dir ~ '/secrets/registry_token_creds.yaml']) }}
loop_control:
loop_var: secret_file

- name: Pass extra variable files to the remaining deployment wrappers
ansible.builtin.set_fact:
cifmw_deploy_architecture_args: >-
{{ cifmw_deploy_architecture_args | default('') }} -e @{{ extra_variable_file }}
loop: "{{ extra_variable_files | default([]) }}"
loop_control:
loop_var: extra_variable_file
Loading