Skip to content

Commit

Permalink
Introduce two new playbooks for adoption infra
Browse files Browse the repository at this point in the history
create-infra.yml allows to create all the VMs related to adoption
scenarios.
deploy-ocp.yml allows to get the OCP cluster in, independently to the
rest of the Framework. You usually want to run that playbook after the
"create-infra.yml", but it's not mandatory.

The infrastructure and networks changes needed for adoption are to be
pushed in a scenario file, either under scenarios/adoption/SCENARIO.yml,
or in a 3rd party repository (mostly for Downstream).

All of the VMs are shut off after the create-infra.yml is finished, and
only the OCP cluster members are running after the deploy-ocp.yml run.
  • Loading branch information
cjeanner authored and openshift-merge-bot[bot] committed Sep 13, 2024
1 parent f019921 commit c3457d1
Show file tree
Hide file tree
Showing 8 changed files with 405 additions and 52 deletions.
77 changes: 77 additions & 0 deletions create-infra.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
# Purpose of this playbook:
# - Create a virtual infrastructure consisting in
# virtual machines, related storage, and virtual networks.
#
# - Create a dnsmasq instance with the appropriate records to provide
# fixed IPs, proper DNS resolution
#
# - Expose at least one inventory file showing the various resources
#
# This playbook is meant to run for architecture driven deployment only.

- name: Parent scenario if needed
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: true
tasks:
- name: Inherit from parent scenarios if needed
ansible.builtin.include_tasks:
file: "ci/playbooks/tasks/inherit_parent_scenario.yml"

- name: Manage/generate unique ID
ansible.builtin.import_playbook: playbooks/unique-id.yml

- name: Run consistency checks
ansible.builtin.import_playbook: "playbooks/adoption/pre.yml"

- name: Prepare infrastructure datasets
ansible.builtin.import_playbook: "playbooks/adoption/infra.yml"

- name: Amend infrastructure datasets
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: true
tasks:
# Inject "start: false" in the layout to not start any VM yet.
# Starting the VM will be done later, either by the tool deploying
# OSP, or the one deploy RHOSO.
# VM initial configuration, when managed, is done using cloud-init.
- name: Ensure no VM is started when we create them during this run
vars:
_no_start: >-
{% set _vms = {} -%}
{% for _type in _cifmw_libvirt_manager_layout.vms.keys() -%}
{% set _ = _vms.update({_type: {'start': false}}) -%}
{% endfor -%}
{{ _vms }}
ansible.builtin.set_fact:
_cifmw_libvirt_manager_layout: >-
{{
_cifmw_libvirt_manager_layout |
combine({'vms': _no_start}, recursive=true)
}}
- name: Set amount for OCP cluster members to 0
vars:
_0_ocp:
vms:
ocp:
amount: 0
ocp_worker:
amount: 0
ansible.builtin.set_fact:
_cifmw_libvirt_manager_layout: >-
{{
_cifmw_libvirt_manager_layout | combine(_0_ocp, recursive=true)
}}
- name: Prepare networking
ansible.builtin.import_playbook: "playbooks/adoption/network.yml"

- name: Deploy infrastructure
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: true
tasks:
# Create all the VMs
- name: Deploy layout
ansible.builtin.import_role:
name: "libvirt_manager"
tasks_from: "deploy_layout.yml"
69 changes: 69 additions & 0 deletions deploy-ocp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
# This playbook deploy OCP, both master and workers.
# The main goal of this playbook is to be called as
# a standalone piece of a bigger job, mostly in the
# adoption context.
#
# You would typically run this playbook after the
# "create-infra.yml" one, passing the exact same parameters.
#
# Make sure you passed the needed secrets to deploy OCP!

- name: Parent scenario if needed
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: true
tasks:
- name: Inherit from parent scenarios if needed
ansible.builtin.include_tasks:
file: "ci/playbooks/tasks/inherit_parent_scenario.yml"

- name: Manage/generate unique ID
ansible.builtin.import_playbook: playbooks/unique-id.yml

- name: Run consistency checks
ansible.builtin.import_playbook: "playbooks/adoption/pre.yml"

- name: Prepare infrastructure datasets
ansible.builtin.import_playbook: "playbooks/adoption/infra.yml"

- name: Amend infrastructure datasets
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: true
tasks:
# Inject "start: false" in the layout to not start any VM yet.
# Starting the VM will be done later, either by the tool deploying
# OSP, or the one deploy RHOSO.
# VM initial configuration, when managed, is done using cloud-init.
- name: Ensure no VM is started when we create them during this run
vars:
_no_start: >-
{% set _vms = {} -%}
{% for _type in _cifmw_libvirt_manager_layout.vms.keys() -%}
{% if _type is not match('^ocp.*') -%}
{% set _ = _vms.update({_type: {'start': false}}) -%}
{% endif -%}
{% endfor -%}
{{ _vms }}
ansible.builtin.set_fact:
_cifmw_libvirt_manager_layout: >-
{{
_cifmw_libvirt_manager_layout |
combine({'vms': _no_start}, recursive=true)
}}
- name: Prepare networking
ansible.builtin.import_playbook: "playbooks/adoption/network.yml"

- name: OCP cluster
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: true
tasks:
- name: Deploy OCP cluster
ansible.builtin.import_role:
name: "reproducer"
tasks_from: "ocp_layout.yml"

- name: Start OCP cluster based on its overlays
ansible.builtin.import_role:
name: "libvirt_manager"
tasks_from: "deploy_layout.yml"
27 changes: 27 additions & 0 deletions playbooks/adoption/infra.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
# Purpose: create infra dataset to be consumed by
# adoption related playbooks

- name: Create CI virtual infrastructure
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: true
roles:
- role: ci_setup
- role: discover_latest_image

tasks:
- name: Generate libvirt layout
ansible.builtin.include_role:
name: "libvirt_manager"
tasks_from: "generate_layout.yml"

- name: Apply layout patches if it exists
when:
- _adoption_scenario.libvirt_manager_patch_layout is defined
ansible.builtin.set_fact:
_cifmw_libvirt_manager_layout: >-
{{
_cifmw_libvirt_manager_layout |
combine(_adoption_scenario.libvirt_manager_patch_layout,
recursive=true)
}}
23 changes: 23 additions & 0 deletions playbooks/adoption/network.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
# Purpose: create infra dataset to be consumed by
# adoption related playbooks

- name: Build networking_mapper related content
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: true
tasks:
- name: Apply networking_definition patch if it exists
when:
- _adoption_scenario.networking_mapper_definition_patch is defined
ansible.builtin.set_fact:
cifmw_networking_mapper_definition_patch_01_adoption_infra: >-
{{ _adoption_scenario.networking_mapper_definition_patch }}
- name: Prepare networking
vars:
cifmw_reproducer_validate_network: false
_use_crc: false
_use_ocp: true
ansible.builtin.import_role:
name: "reproducer"
tasks_from: "prepare_networking.yml"
66 changes: 66 additions & 0 deletions playbooks/adoption/pre.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
# Purpose: Add consistency checks and build the needed
# datasets for an adoption usecase.
# This playbook should be imported in:
# - create-infra.yml
# - deploy-ocp.yml
# (anything coming later in the adoption process to get OSP)

- name: Prepare dataset
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: true
vars:
_default_scenario_dir: >-
{{
(playbook_dir, '../..',
'scenarios') |path_join
}}
_adoption_scenario_basedir: >-
{{
cifmw_adoption_scenario_path |
default((_default_scenario_dir, 'adoption') | path_join)
}}
tasks:
- name: Assert we have the needed parameters
ansible.builtin.assert:
that:
# Ensure we have a scenario name
- cifmw_architecture_scenario is defined
- cifmw_architecture_scenario | length > 0
msg: >-
Error: provide cifmw_architecture_scenario parameters.
# We allow to point to external resources if needed.
- name: Ensure the automation file exists
vars:
_scenario: >-
{{
[_adoption_scenario_basedir,
cifmw_architecture_scenario ~ '.yml'] | path_join
}}
ansible.builtin.assert:
that:
- _scenario is exists
msg: >-
Error: the automation file {{ _scenario }} does
not exist.
- name: Include common architecture parameter file if needed
ansible.builtin.include_vars:
file: "{{ _default_scenario_dir }}/reproducers/va-common.yml"

- name: Include the scenario automation file
vars:
_scenario: >-
{{
[_adoption_scenario_basedir,
cifmw_architecture_scenario ~ '.yml'] | path_join
}}
ansible.builtin.include_vars:
file: "{{ _scenario }}"
name: _adoption_scenario

- name: Run reproducer validations
ansible.builtin.import_role:
name: "reproducer"
tasks_from: "validations.yml"
56 changes: 56 additions & 0 deletions playbooks/unique-id.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
# Purpose: manage the unique ID used in the
# VM hostname construction.

- name: Manage/generate unique ID
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: true
vars:
_unique_id_file: >-
{{ ansible_user_dir }}/ci-framework-data/artifacts/run-id
tasks:
- name: Ensure needed directory tree is present on local node
ansible.builtin.file:
mode: "0755"
path: "{{ _unique_id_file | dirname }}"
state: directory

- name: Check if we have a unique ID already
register: _unique_id_stat
ansible.builtin.stat:
path: "{{ _unique_id_file }}"

# Here, we want to allow the user to provide their own run ID,
# or to fallback on a generated one.
# In any cases, we want to get the file in place with the correct value.
# The jinja[invalid] is triggered because ansible-lint doesn't seem to find
# the community.general.random_string lookup, and doesn't mock it...
- name: Generate current job unique ID if needed # noqa: jinja[invalid]
when:
- (not _unique_id_stat.stat.exists and cifmw_run_id is undefined)
or cifmw_run_id is defined
vars:
_unique_id: >-
{{
lookup('community.general.random_string',
special=false, upper=false)
}}
ansible.builtin.copy:
dest: "{{ _unique_id_file }}"
content: "{{ cifmw_run_id | default(_unique_id) | lower }}"

# Since the user might pass their own run ID, we can just consume it.
# If, for a subsequent run, the user doesn't pass the run ID, we will
# just get it from the file and consume it.
- name: Load existing run ID
when:
- cifmw_run_id is undefined
block:
- name: Slurp unique id file if needed
register: _unique_id_content
ansible.builtin.slurp:
path: "{{ _unique_id_file }}"

- name: Expose cifmw_run_id if needed
ansible.builtin.set_fact:
cifmw_run_id: "{{ _unique_id_content.content | b64decode }}"
54 changes: 2 additions & 52 deletions reproducer.yml
Original file line number Diff line number Diff line change
@@ -1,56 +1,6 @@
---
- name: Manage/generate unique ID
hosts: "{{ cifmw_target_host | default('localhost') }}"
gather_facts: true
vars:
_unique_id_file: >-
{{ ansible_user_dir }}/ci-framework-data/artifacts/run-id
tasks:
- name: Ensure needed directory tree is present on local node
ansible.builtin.file:
mode: "0755"
path: "{{ _unique_id_file | dirname }}"
state: directory

- name: Check if we have a unique ID already
register: _unique_id_stat
ansible.builtin.stat:
path: "{{ _unique_id_file }}"

# Here, we want to allow the user to provide their own run ID,
# or to fallback on a generated one.
# In any cases, we want to get the file in place with the correct value.
# The jinja[invalid] is triggered because ansible-lint doesn't seem to find
# the community.general.random_string lookup, and doesn't mock it...
- name: Generate current job unique ID if needed # noqa: jinja[invalid]
when:
- (not _unique_id_stat.stat.exists and cifmw_run_id is undefined)
or cifmw_run_id is defined
vars:
_unique_id: >-
{{
lookup('community.general.random_string',
special=false, upper=false)
}}
ansible.builtin.copy:
dest: "{{ _unique_id_file }}"
content: "{{ cifmw_run_id | default(_unique_id) | lower }}"

# Since the user might pass their own run ID, we can just consume it.
# If, for a subsequent run, the user doesn't pass the run ID, we will
# just get it from the file and consume it.
- name: Load existing run ID
when:
- cifmw_run_id is undefined
block:
- name: Slurp unique id file if needed
register: _unique_id_content
ansible.builtin.slurp:
path: "{{ _unique_id_file }}"

- name: Expose cifmw_run_id if needed
ansible.builtin.set_fact:
cifmw_run_id: "{{ _unique_id_content.content | b64decode }}"
- name: Manage unique ID
ansible.builtin.import_playbook: playbooks/unique-id.yml

- name: Reproducer prepare play
hosts: "{{ cifmw_target_host | default('localhost') }}"
Expand Down
Loading

0 comments on commit c3457d1

Please sign in to comment.