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
3 changes: 2 additions & 1 deletion playbooks/validate_cluster.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
- name: Validates that we are logged into a cluster with a default storage class
- name: Validates cluster connectivity, storage class, and OCP version compatibility
hosts: localhost
connection: local
gather_facts: false
roles:
- role: pattern_settings # set general pattern vars
- role: install_settings # set pattern-install specific vars
- role: validate_cluster
- role: validate_ocp_version
3 changes: 3 additions & 0 deletions roles/validate_ocp_version/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
# Minimum OCP version considered supported when not specified in pattern-metadata.yaml
default_minimum_supported_ocp_version: "4.18"
148 changes: 148 additions & 0 deletions roles/validate_ocp_version/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
---
- name: Check for DISABLE_OCP_VERSION_CHECK override
ansible.builtin.set_fact:
_disable_ocp_version_check: "{{ lookup('env', 'DISABLE_OCP_VERSION_CHECK') | default('false', true) | bool }}"

- name: OCP version check disabled
ansible.builtin.debug:
msg: "OCP version compatibility check disabled (DISABLE_OCP_VERSION_CHECK=true)."

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Note: we'll need to add this to pattern.sh's list of env vars to pass through to the utlity container.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

We can add it later to the patternizer repo once this PR merges.

@mhjacks mhjacks Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Update here: more recent pattern.sh passes down 'VP_*' environment variables like so:

    -e VALUES_SECRET \
    -e 'VP_*' \

Can we please change this variable name to VP_DISABLE_OCP_VERSION_CHECK? @p-rog

when: _disable_ocp_version_check

- name: Run OCP version compatibility check
when: not _disable_ocp_version_check
block:
- name: Check pattern-metadata.yaml exists
ansible.builtin.stat:
path: "{{ pattern_dir }}/pattern-metadata.yaml"
register: _metadata_file

- name: Skip version check when pattern-metadata.yaml is missing
ansible.builtin.debug:
msg: "No pattern-metadata.yaml found — skipping OCP version compatibility check."
when: not _metadata_file.stat.exists

- name: Validate OCP version compatibility
when: _metadata_file.stat.exists
block:
- name: Read pattern-metadata.yaml
ansible.builtin.slurp:
src: "{{ pattern_dir }}/pattern-metadata.yaml"
register: _metadata_raw

- name: Parse pattern-metadata.yaml
block:
- name: Decode and parse pattern-metadata.yaml
ansible.builtin.set_fact:
_pattern_metadata: "{{ _metadata_raw.content | b64decode | from_yaml }}"
rescue:
Comment thread
p-rog marked this conversation as resolved.
- name: Fail on malformed pattern-metadata.yaml
ansible.builtin.fail:
msg: "pattern-metadata.yaml exists but contains invalid YAML. Please fix the file before proceeding."

- name: Check if ocp_versions section exists in metadata
ansible.builtin.set_fact:
_has_ocp_versions: "{{ _pattern_metadata.ocp_versions is defined and _pattern_metadata.ocp_versions is mapping }}"

- name: Skip version check when metadata has no ocp_versions section
ansible.builtin.debug:
msg: "No ocp_versions section found in pattern-metadata.yaml — skipping OCP version compatibility check."
when: not _has_ocp_versions

- name: Check OCP version against compatibility matrix
when: _has_ocp_versions
block:
- name: Fetch ClusterVersion from CVO
kubernetes.core.k8s_info:
api_version: config.openshift.io/v1
kind: ClusterVersion
name: version
register: _cluster_version_info

- name: Assert ClusterVersion is available
ansible.builtin.assert:
that:
- _cluster_version_info.resources | default([]) | length > 0
- _cluster_version_info.resources[0].status.desired.version is defined
fail_msg: |
Could not retrieve the ClusterVersion resource from the cluster.
Ensure you are connected to an OpenShift cluster (not vanilla Kubernetes).

- name: Extract OCP version from ClusterVersion
ansible.builtin.set_fact:
_cluster_ocp_version: >-
{{ _cluster_version_info.resources[0].status.desired.version
| regex_search('^(\d+\.\d+)') }}

- name: Resolve minimum supported OCP version
ansible.builtin.set_fact:
_minimum_ocp_version: "{{ _pattern_metadata.ocp_versions.minimum | default(default_minimum_supported_ocp_version) }}"

- name: Collect unsupported versions list
ansible.builtin.set_fact:
_unsupported_versions: "{{ _pattern_metadata.ocp_versions.unsupported | default([]) }}"

- name: Build unsupported version strings for lookup
ansible.builtin.set_fact:
_unsupported_version_strings: "{{ _unsupported_versions | map(attribute='version') | list }}"

- name: Display detected OCP version
ansible.builtin.debug:
msg: "Detected cluster OCP version: {{ _cluster_ocp_version }}"

- name: Check if cluster version is explicitly unsupported
ansible.builtin.set_fact:
_is_unsupported: "{{ _cluster_ocp_version in _unsupported_version_strings }}"

- name: Find unsupported version details
ansible.builtin.set_fact:
_unsupported_reason: "{{ (_unsupported_versions | selectattr('version', 'equalto', _cluster_ocp_version) | first).reason | default('No reason specified.') }}"
when: _is_unsupported

- name: Fail on explicitly unsupported OCP version
ansible.builtin.fail:
msg: |

╔══════════════════════════════════════════════════════════════════╗

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I would prefer to not have the "text box" output. It seems to depend on using the null STDOUT callback (which is default) but does not look good e.g. with the normal stdout callback. I think from a UX standpoint halting the installation with instructions on how to recover it is sufficient.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Personally I like "text boxes" because it's very clear that this is the core information you have to read. If you don't mind I would prefer to leave text boxes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I also think that are really a sore point in the eye I think and prefer them to be gone tbh (let alone that they are not aligned at all and are missing lines)

Image

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It looks like this in default output format:

TASK [rhvp.cluster_utils.validate_ocp_version : Find unsupported version details] **************************************
ok: [localhost]

TASK [rhvp.cluster_utils.validate_ocp_version : Fail on explicitly unsupported OCP version] ****************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "\n╔══════════════════════════════════════════════════════════════════╗\n║               OCP VERSION NOT SUPPORTED                        ║\n╠══════════════════════════════════════════════════════════════════╣\n║                                                                ║\n║  Pattern:  RamenDR Starter Kit\n║  Cluster:  OCP 4.22\n║                                                                ║\n║  This OCP version is explicitly listed as unsupported.         ║\n║                                                                ║\n║  Reason: Not yet validated — operator catalog and channel...\n║                                                                ║\n║  To override this check (e.g. for testing), re-run with:      ║\n║    DISABLE_OCP_VERSION_CHECK=true ./pattern.sh make install    ║\n║                                                                ║\n╚══════════════════════════════════════════════════════════════════╝\n"}

And it looks like this with the null callback:

Fail on explicitly unsupported OCP version...  
╔══════════════════════════════════════════════════════════════════╗
║               OCP VERSION NOT SUPPORTED                        ║
╠══════════════════════════════════════════════════════════════════╣
║                                                                ║
║  Pattern:  RamenDR Starter Kit
║  Cluster:  OCP 4.22
║                                                                ║
║  This OCP version is explicitly listed as unsupported.         ║
║                                                                ║
║  Reason: Not yet validated — operator catalog and channel...
║                                                                ║
║  To override this check (e.g. for testing), re-run with:      ║
║    DISABLE_OCP_VERSION_CHECK=true ./pattern.sh make install    ║
║                                                                ║
╚══════════════════════════════════════════════════════════════════╝

It's the last thing you see if it fails, which seems emphatic, and the details of spacing the text box get somewhat complicated with varying sized text in the null callback, and completely unworkable with the default

@p-rog p-rog Aug 6, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

OK, you convinced me :)
Give me a moment to change it.

║ OCP VERSION NOT SUPPORTED ║
╠══════════════════════════════════════════════════════════════════╣
║ ║
║ Pattern: {{ (_pattern_metadata.display_name | default(_pattern_metadata.name | default('unknown'))) | truncate(46) }}
║ Cluster: OCP {{ _cluster_ocp_version }}
║ ║
║ This OCP version is explicitly listed as unsupported. ║
║ ║
║ Reason: {{ _unsupported_reason | truncate(52) }}
║ ║
║ To override this check (e.g. for testing), re-run with: ║
║ DISABLE_OCP_VERSION_CHECK=true ./pattern.sh make install ║
║ ║
╚══════════════════════════════════════════════════════════════════╝
when: _is_unsupported

- name: Check if cluster version is below minimum supported
ansible.builtin.set_fact:
_is_below_minimum: "{{ _cluster_ocp_version is version(_minimum_ocp_version, '<') }}"

- name: Warn when OCP version is below minimum supported
ansible.builtin.debug:
msg: |

┌──────────────────────────────────────────────────────────────────┐
│ WARNING │

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same note on text box formatting as above.

├──────────────────────────────────────────────────────────────────┤
│ │
│ Your cluster is running OCP {{ _cluster_ocp_version }}, which is below the │
│ minimum supported version ({{ _minimum_ocp_version }}) for this pattern. │
│ │
│ The installation will proceed, but you may encounter issues │
│ with operator availability or component compatibility. │
│ │
│ For the best experience, please use OCP {{ _minimum_ocp_version }} or later. │
│ │
└──────────────────────────────────────────────────────────────────┘
when: _is_below_minimum

- name: Confirm OCP version is compatible
ansible.builtin.debug:
msg: "OK: OCP {{ _cluster_ocp_version }} is compatible with this pattern (minimum: {{ _minimum_ocp_version }})."
when: not _is_below_minimum and not _is_unsupported