Skip to content

Commit e1bf815

Browse files
fix: address CodeRabbit review findings for sno-to-3node role
- handlers/main.yml: emit explicit WARNING debug if oc project fails after all retries, keeping failed_when: false to avoid play abortion - tasks/config.yml: add SNO_IPV4 to the AGENT_E2E_TEST_SCENARIO guidance message so all three supported scenarios are listed - boot-nodes.yml: add --nvram to virsh undefine so UEFI varstore is fully removed before virt-install recreates the domain - clean.yml: remove NetworkManager dnsmasq override file and reload NM after libvirt dnsmasq reload to clear stale local DNS entries - create-vms.yml: remove failed_when: false from virsh net-update dns-host add so DNS update failures surface instead of being silently swallowed - ignition.yml: add --request-timeout=30s to oc get configmap and --max-time 10 to curl so probes fail quickly on API/DNS stalls - mco-rollout.yml: tighten drain auto-fix gate to only fire on nodes with a stale MCO desiredDrain annotation (drain-* prefix, != lastAppliedDrain); change sno_auto_fix_drain default to false (opt-in); restart MCC only once per cycle rather than unconditionally - preflight.yml: indent Python snippet inside shell: | block to column 4+ so all lines remain within the block scalar per YAML spec - update-dns.yml: tighten API DNS check to require a known node IP via intersect filter; replace failed_when: false on apps check with a real assertion against sno_all_node_ips[0]; add retries to both checks - verify.yml: add Assert all nodes Ready assertion before the success message so NotReady nodes cause a hard failure instead of passing silently Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: ehila <ehila@redhat.com>
1 parent 134e627 commit e1bf815

10 files changed

Lines changed: 85 additions & 25 deletions

File tree

deploy/openshift-clusters/roles/dev-scripts/install-dev/handlers/main.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@
1919
failed_when: false
2020
listen: Set OCP project
2121

22+
- name: Warn if oc project failed after all retries
23+
debug:
24+
msg: >-
25+
WARNING: 'oc project openshift-machine-api' still failing after all retries
26+
(rc={{ oc_project_result.rc | default('n/a') }}).
27+
stderr: {{ oc_project_result.stderr | default('') | trim }}
28+
when:
29+
- kubeconfig_path is defined
30+
- kubeconfig_stat.stat.exists | default(false)
31+
- oc_project_result.rc | default(0) != 0
32+
listen: Set OCP project
33+
2234
- name: Warn about missing kubeconfig
2335
debug:
2436
msg: >-

deploy/openshift-clusters/roles/dev-scripts/install-dev/tasks/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
msg: >-
2929
Config file {{ config_file[method] }} does not set AGENT_E2E_TEST_SCENARIO,
3030
which is required for the agent installation method. Add
31-
AGENT_E2E_TEST_SCENARIO="TNF_IPV4" (fencing) or "TNA_IPV4" (arbiter) to
32-
the config file.
31+
AGENT_E2E_TEST_SCENARIO="TNF_IPV4" (fencing), "TNA_IPV4" (arbiter), or
32+
"SNO_IPV4" (sno) to the config file.
3333
when:
3434
- method == "agent"
3535
- config_scenario | length == 0

deploy/openshift-clusters/roles/mutable-topology/sno-to-3node/tasks/boot-nodes.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
MAC="{{ sno_node_macs[item.hostname] }}"
5656
5757
sudo virsh destroy "$VM_NAME" 2>/dev/null || true
58-
sudo virsh undefine "$VM_NAME" 2>/dev/null || true
58+
sudo virsh undefine "$VM_NAME" --nvram 2>/dev/null || true
5959
6060
sudo virt-install \
6161
--name "$VM_NAME" \

deploy/openshift-clusters/roles/mutable-topology/sno-to-3node/tasks/clean.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,20 @@
117117
changed_when: true
118118
failed_when: false
119119

120+
- name: "[clean] Remove NetworkManager dnsmasq override"
121+
file:
122+
path: "{{ sno_nm_dnsmasq_conf }}"
123+
state: absent
124+
become: true
125+
failed_when: false
126+
127+
- name: "[clean] Reload NetworkManager to clear stale DNS overrides"
128+
systemd:
129+
name: NetworkManager
130+
state: reloaded
131+
become: true
132+
failed_when: false
133+
120134
- name: "[clean] Cleanup complete"
121135
debug:
122136
msg: >-

deploy/openshift-clusters/roles/mutable-topology/sno-to-3node/tasks/create-vms.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@
133133
"<host ip='{{ item.ip }}'><hostname>{{ item.hostname }}.{{ sno_cluster_domain }}</hostname></host>" \
134134
--live --config
135135
loop: "{{ sno_new_nodes }}"
136-
failed_when: false
137136

138137
- name: "[create-vms] Add entries to addnhosts"
139138
lineinfile:

deploy/openshift-clusters/roles/mutable-topology/sno-to-3node/tasks/ignition.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
---
22
- name: "[ignition] Extract MCS CA certificate"
33
shell: |
4-
oc get configmap -n openshift-machine-config-operator machine-config-server-ca -o jsonpath='{.data.ca-bundle\.crt}'
4+
oc get configmap -n openshift-machine-config-operator machine-config-server-ca \
5+
-o jsonpath='{.data.ca-bundle\.crt}' --request-timeout=30s
56
environment: "{{ sno_oc_env }}"
67
register: mcs_ca_raw
78
changed_when: false
@@ -18,7 +19,7 @@
1819

1920
- name: "[ignition] Verify MCS reachability"
2021
shell: |
21-
curl -sk https://api-int.{{ sno_cluster_domain }}:22623/healthz
22+
curl -sk --max-time 10 https://api-int.{{ sno_cluster_domain }}:22623/healthz
2223
register: mcs_health
2324
changed_when: false
2425
failed_when: false

deploy/openshift-clusters/roles/mutable-topology/sno-to-3node/tasks/mco-rollout.yml

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,31 @@
3939
exit 0
4040
fi
4141
42-
# Auto-fix drain deadlock for any cordoned node.
43-
# On SNO→3node, MCD cordons a node before draining. If MCC cannot reach
44-
# the node (api-int flap, RBAC timing) the drain annotation never advances
45-
# and the node stays cordoned forever. Fix: uncordon, set lastAppliedDrain
46-
# to the drain-<desired> value MCC is waiting for, restart MCC.
47-
if [ -n "$CORDONED_NODES" ] && [ "{{ sno_auto_fix_drain | default(true) | bool }}" = "True" ]; then
42+
# Auto-fix MCO drain deadlock for nodes with a stale drain annotation.
43+
# Only fires when ALL of:
44+
# 1. sno_auto_fix_drain is enabled
45+
# 2. The node is cordoned (SchedulingDisabled)
46+
# 3. MCO owns the cordon: desiredDrain starts with "drain-"
47+
# 4. The drain is actually stuck: desiredDrain != lastAppliedDrain
48+
# This avoids touching nodes cordoned manually or mid-drain legitimately.
49+
if [ -n "$CORDONED_NODES" ] && [ "{{ sno_auto_fix_drain | default(false) | bool }}" = "True" ]; then
4850
DESIRED=$(oc get mcp master -o jsonpath='{.spec.configuration.name}' 2>/dev/null || echo "")
51+
MCC_RESTARTED=0
4952
for NODE_NAME in $CORDONED_NODES; do
50-
echo "DRAIN_FIX: Fixing drain deadlock on $NODE_NAME (desired=${DESIRED})..."
53+
DESIRED_DRAIN=$(oc get node "$NODE_NAME" \
54+
-o jsonpath='{.metadata.annotations.machineconfiguration\.openshift\.io/desiredDrain}' \
55+
2>/dev/null || true)
56+
LAST_DRAIN=$(oc get node "$NODE_NAME" \
57+
-o jsonpath='{.metadata.annotations.machineconfiguration\.openshift\.io/lastAppliedDrain}' \
58+
2>/dev/null || true)
59+
60+
# Skip if this is not an MCO-managed drain or drain is already advancing
61+
if ! echo "$DESIRED_DRAIN" | grep -q "^drain-" || [ "$DESIRED_DRAIN" = "$LAST_DRAIN" ]; then
62+
echo "DRAIN_FIX: $NODE_NAME cordoned but not a stale MCO drain (desired=${DESIRED_DRAIN}, last=${LAST_DRAIN}), skipping"
63+
continue
64+
fi
65+
66+
echo "DRAIN_FIX: Stale MCO drain on $NODE_NAME (desired=${DESIRED_DRAIN}, last=${LAST_DRAIN})"
5167
5268
oc adm uncordon "$NODE_NAME" 2>&1 || true
5369
@@ -57,11 +73,14 @@
5773
--overwrite 2>&1 || true
5874
echo "DRAIN_FIX: Set lastAppliedDrain=drain-${DESIRED} on $NODE_NAME"
5975
fi
76+
MCC_RESTARTED=1
6077
done
6178
62-
oc delete pod -n openshift-machine-config-operator \
63-
-l k8s-app=machine-config-controller 2>&1 || true
64-
echo "DRAIN_FIX: Restarted MCC pod"
79+
if [ "$MCC_RESTARTED" = "1" ]; then
80+
oc delete pod -n openshift-machine-config-operator \
81+
-l k8s-app=machine-config-controller 2>&1 || true
82+
echo "DRAIN_FIX: Restarted MCC pod"
83+
fi
6584
fi
6685
6786
echo "RESULT=pending"

deploy/openshift-clusters/roles/mutable-topology/sno-to-3node/tasks/preflight.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,13 @@
134134
# previous partial run) doesn't cause the subsequent add to fail.
135135
shell: |
136136
CURRENT_IP=$(sudo virsh net-dumpxml {{ sno_libvirt_network }} | python3 -c "
137-
import xml.etree.ElementTree as ET, sys
138-
root = ET.parse(sys.stdin).getroot()
139-
for h in root.findall('.//dns/host'):
140-
for hn in h.findall('hostname'):
141-
if hn.text == 'api-int.{{ sno_cluster_domain }}':
142-
print(h.get('ip', ''))
143-
" 2>/dev/null || true)
137+
import xml.etree.ElementTree as ET, sys
138+
root = ET.parse(sys.stdin).getroot()
139+
for h in root.findall('.//dns/host'):
140+
for hn in h.findall('hostname'):
141+
if hn.text == 'api-int.{{ sno_cluster_domain }}':
142+
print(h.get('ip', ''))
143+
" 2>/dev/null || true)
144144
145145
if [ -n "$CURRENT_IP" ]; then
146146
sudo virsh net-update {{ sno_libvirt_network }} delete dns-host \

deploy/openshift-clusters/roles/mutable-topology/sno-to-3node/tasks/update-dns.yml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,24 @@
5959
dig +short api.{{ sno_cluster_domain }}
6060
register: dns_api_verify
6161
changed_when: false
62-
failed_when: dns_api_verify.stdout | trim == ""
62+
failed_when: >-
63+
dns_api_verify.stdout | trim == "" or
64+
sno_all_node_ips | intersect(dns_api_verify.stdout_lines) | length == 0
65+
retries: 6
66+
delay: 5
67+
until: >-
68+
dns_api_verify.stdout | trim != "" and
69+
sno_all_node_ips | intersect(dns_api_verify.stdout_lines) | length > 0
6370
6471
- name: "[dns] Verify apps DNS resolution"
6572
shell: |
6673
dig +short test.apps.{{ sno_cluster_domain }}
6774
register: dns_apps_verify
6875
changed_when: false
69-
failed_when: false
76+
failed_when: sno_all_node_ips[0] not in dns_apps_verify.stdout_lines
77+
retries: 6
78+
delay: 5
79+
until: sno_all_node_ips[0] in dns_apps_verify.stdout_lines
7080

7181
- name: "[dns] DNS update complete"
7282
debug:

deploy/openshift-clusters/roles/mutable-topology/sno-to-3node/tasks/verify.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@
9393
that: (verify_nodes.stdout_lines | length) >= 3
9494
fail_msg: "Expected 3+ nodes, found {{ verify_nodes.stdout_lines | length }}"
9595

96+
- name: "[verify] Assert all nodes Ready"
97+
assert:
98+
that: "'NotReady' not in verify_nodes.stdout"
99+
fail_msg: "One or more nodes are NotReady:\n{{ verify_nodes.stdout }}"
100+
96101
- name: "[verify] Assert HA topology"
97102
assert:
98103
that: verify_topo.stdout == "HighlyAvailable"

0 commit comments

Comments
 (0)