|
| 1 | +--- |
| 2 | +# Single upgrade step: upgrade from current version to target_release |
| 3 | +# This file is included in a loop from main.yml with target_release variable |
| 4 | + |
| 5 | +- name: Check cluster health before upgrading to {{ target_release }} |
| 6 | + ansible.builtin.include_role: |
| 7 | + name: shiftstack.tools.tools_cluster_checks |
| 8 | + vars: |
| 9 | + actions: |
| 10 | + - wait_until_cluster_is_healthy |
| 11 | + - wait_until_nodes_ready |
| 12 | + - wait_until_no_unschedulable_nodes |
| 13 | + wait_retries: 1 |
| 14 | + wait_delay: 0 |
| 15 | + |
| 16 | +- name: Get the ClusterVersion object before upgrade |
| 17 | + ansible.builtin.shell: | |
| 18 | + oc get clusterversion version -o json |
| 19 | + register: cluster_version_json_before |
| 20 | + changed_when: false |
| 21 | + |
| 22 | +- name: Parse ClusterVersion before upgrade |
| 23 | + ansible.builtin.set_fact: |
| 24 | + cluster_version_before_upgrade: "{{ cluster_version_json_before.stdout | from_json }}" |
| 25 | + |
| 26 | +- name: Get current cluster version from history |
| 27 | + ansible.builtin.set_fact: |
| 28 | + current_version: "{{ cluster_version_before_upgrade.status.history[0].version }}" |
| 29 | + |
| 30 | +- name: Check the version to upgrade to is >= the current version |
| 31 | + ansible.builtin.assert: |
| 32 | + that: |
| 33 | + - target_release is version(current_version | regex_replace('^(\\d+\\.\\d+).*', '\\1'), '>=') |
| 34 | + fail_msg: "The version to upgrade to ({{ target_release }}) must be >= the current version ({{ current_version }})" |
| 35 | + |
| 36 | +- name: Get the OCP release build name to upgrade to |
| 37 | + ansible.builtin.include_role: |
| 38 | + name: shiftstack.tools.tools_get_openshift_release |
| 39 | + tasks_from: get_openshift_release_build_name.yml |
| 40 | + vars: |
| 41 | + openshift_release: "{{ target_release }}" |
| 42 | + openshift_build_name: "{{ upgrade_build_name }}" |
| 43 | + |
| 44 | +- name: Print upgrade versions |
| 45 | + ansible.builtin.debug: |
| 46 | + msg: "Upgrading FROM: '{{ current_version }}' TO: '{{ openshift_release_build_name }}'" |
| 47 | + |
| 48 | +- name: Mark the OpenShift version to upgrade to |
| 49 | + ansible.builtin.debug: |
| 50 | + msg: "Build mark: upgrade_to={{ openshift_release_build_name }}" |
| 51 | + |
| 52 | +# Version-specific workarounds for OSP 18 |
| 53 | +- name: Set patch data for consoleplugins (4.16 only) |
| 54 | + ansible.builtin.set_fact: |
| 55 | + console_patch: |
| 56 | + storedVersions: |
| 57 | + - v1 |
| 58 | + when: openshift_release_build_name is regex('^4\\.16\\..*') |
| 59 | + |
| 60 | +- name: Set consoleplugins to v1 for 4.16 upgrade |
| 61 | + ansible.builtin.shell: | |
| 62 | + oc patch crd consoleplugins.console.openshift.io --subresource='status' --type="merge" -p '{{ console_patch | to_json }}' |
| 63 | + when: openshift_release_build_name is regex('^4\\.16\\..*') |
| 64 | + changed_when: true |
| 65 | + |
| 66 | +- name: Set ack data for 4.19 upgrade handholding |
| 67 | + ansible.builtin.set_fact: |
| 68 | + ack419_patch: |
| 69 | + data: |
| 70 | + ack-4.18-kube-1.32-api-removals-in-4.19: "true" |
| 71 | + when: openshift_release_build_name is regex('^4\\.19\\..*') |
| 72 | + |
| 73 | +- name: Manual ack for 4.19 upgrade (k8s 1.32 API removals) |
| 74 | + ansible.builtin.shell: | |
| 75 | + oc -n openshift-config patch cm admin-acks --type="merge" -p '{{ ack419_patch | to_json }}' |
| 76 | + when: openshift_release_build_name is regex('^4\\.19\\..*') |
| 77 | + changed_when: true |
| 78 | + |
| 79 | +# Get the digest ID from the release image |
| 80 | +- name: Create secret.json for OCP release info |
| 81 | + ansible.builtin.copy: |
| 82 | + content: "{{ ocp_pull_secret }}" |
| 83 | + dest: /tmp/secret.json |
| 84 | + mode: '0600' |
| 85 | + |
| 86 | +- name: Get the OCP release digest |
| 87 | + ansible.builtin.shell: | |
| 88 | + set -o pipefail |
| 89 | + oc adm release info registry.ci.openshift.org/ocp/release:{{ openshift_release_build_name }} --registry-config=/tmp/secret.json | grep Digest | awk '{print $2}' |
| 90 | + args: |
| 91 | + executable: /bin/bash |
| 92 | + register: release_digest |
| 93 | + changed_when: false |
| 94 | + |
| 95 | +- name: Display release digest |
| 96 | + ansible.builtin.debug: |
| 97 | + msg: "{{ openshift_release_build_name }} release digest: {{ release_digest.stdout }}" |
| 98 | + |
| 99 | +- name: Run openshift upgrade command |
| 100 | + ansible.builtin.shell: | |
| 101 | + oc adm upgrade --to-image=registry.ci.openshift.org/ocp/release@{{ release_digest.stdout }} --allow-explicit-upgrade --force |
| 102 | + register: upgrade |
| 103 | + changed_when: true |
| 104 | + |
| 105 | +- name: Display upgrade command output |
| 106 | + ansible.builtin.debug: |
| 107 | + var: upgrade |
| 108 | + |
| 109 | +- name: Check the upgrade command returns ok |
| 110 | + ansible.builtin.assert: |
| 111 | + that: |
| 112 | + - upgrade.rc == 0 |
| 113 | + fail_msg: "oc adm upgrade command returned {{ upgrade.rc }} and stderr {{ upgrade.stderr_lines }}" |
| 114 | + |
| 115 | +- name: Set upgrade start datetime |
| 116 | + ansible.builtin.set_fact: |
| 117 | + start_time: "{{ lookup('pipe', 'date +%Y-%m-%dT%H:%M:%S') }}" |
| 118 | + |
| 119 | +- name: Wait until the upgrade starts (Progressing=True) |
| 120 | + ansible.builtin.shell: | |
| 121 | + set -o pipefail |
| 122 | + oc get clusterversion version -o json | jq '.status.conditions[] | select(.type=="Progressing" and .status=="True")' |
| 123 | + args: |
| 124 | + executable: /bin/bash |
| 125 | + register: progressing_check |
| 126 | + until: progressing_check.stdout | length > 0 |
| 127 | + retries: 20 |
| 128 | + delay: 15 |
| 129 | + changed_when: false |
| 130 | + |
| 131 | +# Main upgrade validation block with must-gather rescue |
| 132 | +- name: Block for upgrade checks with must-gather on failure |
| 133 | + block: |
| 134 | + - name: Wait until the upgrade is completed (cluster is healthy) |
| 135 | + ansible.builtin.include_role: |
| 136 | + name: shiftstack.tools.tools_cluster_checks |
| 137 | + vars: |
| 138 | + actions: |
| 139 | + - wait_until_cluster_is_healthy |
| 140 | + wait_retries: 90 |
| 141 | + wait_delay: 120 |
| 142 | + |
| 143 | + - name: Wait until cluster nodes are ready after OCP upgrade |
| 144 | + ansible.builtin.include_role: |
| 145 | + name: shiftstack.tools.tools_cluster_checks |
| 146 | + vars: |
| 147 | + actions: |
| 148 | + - wait_until_nodes_ready |
| 149 | + wait_retries: 80 |
| 150 | + wait_delay: 30 |
| 151 | + |
| 152 | + - name: Wait until there are no unschedulable nodes after OCP upgrade |
| 153 | + ansible.builtin.include_role: |
| 154 | + name: shiftstack.tools.tools_cluster_checks |
| 155 | + vars: |
| 156 | + actions: |
| 157 | + - wait_until_no_unschedulable_nodes |
| 158 | + wait_retries: 80 |
| 159 | + wait_delay: 30 |
| 160 | + |
| 161 | + - name: Set upgrade finish datetime |
| 162 | + ansible.builtin.set_fact: |
| 163 | + finish_time: "{{ lookup('pipe', 'date +%Y-%m-%dT%H:%M:%S') }}" |
| 164 | + |
| 165 | + - name: Set the upgrade execution time in minutes |
| 166 | + ansible.builtin.set_fact: |
| 167 | + upgrade_time: "{{ (((finish_time | to_datetime('%Y-%m-%dT%H:%M:%S')) - (start_time | to_datetime('%Y-%m-%dT%H:%M:%S'))).total_seconds() / 60) | int }}" |
| 168 | + |
| 169 | + - name: Mark the upgrade execution time |
| 170 | + ansible.builtin.debug: |
| 171 | + msg: "Build mark: upgrade_minutes={{ upgrade_time }}" |
| 172 | + |
| 173 | + - name: Check there are no pods in CrashLoopBackOff |
| 174 | + ansible.builtin.include_role: |
| 175 | + name: shiftstack.tools.tools_cluster_checks |
| 176 | + vars: |
| 177 | + actions: |
| 178 | + - check_no_crashloopbackoff |
| 179 | + |
| 180 | + - name: Wait until the running cluster pods are ready after OCP upgrade |
| 181 | + ansible.builtin.include_role: |
| 182 | + name: shiftstack.tools.tools_cluster_checks |
| 183 | + vars: |
| 184 | + actions: |
| 185 | + - wait_until_pods_ready |
| 186 | + wait_retries: 20 |
| 187 | + wait_delay: 30 |
| 188 | + |
| 189 | + - name: Get the ClusterVersion object after upgrade |
| 190 | + ansible.builtin.shell: | |
| 191 | + oc get clusterversion version -o json |
| 192 | + register: cluster_version_json_after |
| 193 | + changed_when: false |
| 194 | + |
| 195 | + - name: Parse ClusterVersion after upgrade |
| 196 | + ansible.builtin.set_fact: |
| 197 | + cluster_version_after: "{{ cluster_version_json_after.stdout | from_json }}" |
| 198 | + |
| 199 | + - name: Check the upgraded cluster version is the desired one |
| 200 | + ansible.builtin.assert: |
| 201 | + that: |
| 202 | + - cluster_version_after.status.history[0].version == openshift_release_build_name |
| 203 | + fail_msg: "Cluster upgraded to '{{ cluster_version_after.status.history[0].version }}' instead of '{{ openshift_release_build_name }}'" |
| 204 | + success_msg: "Cluster successfully upgraded to '{{ cluster_version_after.status.history[0].version }}'" |
| 205 | + |
| 206 | + - name: Check cluster operators are ready after the OCP upgrade |
| 207 | + ansible.builtin.include_role: |
| 208 | + name: shiftstack.tools.tools_cluster_checks |
| 209 | + vars: |
| 210 | + actions: |
| 211 | + - check_cluster_operators |
| 212 | + release_name: "{{ openshift_release_build_name | default('') }}" |
| 213 | + |
| 214 | + rescue: |
| 215 | + - name: Run must-gather for failed upgrade |
| 216 | + ansible.builtin.include_role: |
| 217 | + name: shiftstack.tools.tools_must-gather |
| 218 | + vars: |
| 219 | + must_gather_dir_suffix: "must-gather-upgrade-{{ target_release }}" |
| 220 | + |
| 221 | + - name: Fail inside rescue block |
| 222 | + ansible.builtin.fail: |
| 223 | + msg: "The cluster is not healthy after the upgrade to {{ target_release }}. Check must-gather artifacts." |
| 224 | + |
| 225 | +# Post-upgrade tasks |
| 226 | +- name: Get the installer and oc client binaries for {{ openshift_release_build_name }} release |
| 227 | + ansible.builtin.include_role: |
| 228 | + name: shiftstack.tools.tools_get_openshift_release |
| 229 | + tasks_from: get_openshift_release_binaries.yml |
| 230 | + vars: |
| 231 | + binaries: |
| 232 | + - installer |
| 233 | + - client |
| 234 | + release_name: "{{ openshift_release_build_name | default('') }}" |
0 commit comments