Created
August 31, 2026 14:59
-
-
Save venkataanil/6fdc710ccd7b9b375dfe8d72cb65ad52 to your computer and use it in GitHub Desktop.
fix-kubevirt-checksum-crd.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # ============================================================================= | |
| # fix-kubevirt-checksum-crd.sh | |
| # | |
| # Workaround for KubeVirt Issue #17858: | |
| # VMI stuck in "Scheduled" on Kubernetes 1.36 because the CRD declares | |
| # containerDiskVolume.checksum as int32, but the actual CRC32 value can | |
| # exceed the int32 max (2,147,483,647). | |
| # | |
| # What this script does: | |
| # 1. Scales down hco-operator and virt-operator to 0 | |
| # (prevents them from reverting the CRD fix) | |
| # 2. Patches the VMI CRD: changes 6 checksum fields from | |
| # format: int32 → format: int64 + min: 0 + max: 4294967295 | |
| # 3. Verifies the patch is in place | |
| # | |
| # Permanent fix: Upgrade CNV to a version shipping KubeVirt >= v1.8.4 | |
| # Reference: https://github.com/kubevirt/kubevirt/issues/17858 | |
| # ============================================================================= | |
| set -euo pipefail | |
| KUBECONFIG="${KUBECONFIG:-/root/mno/kubeconfig}" | |
| NAMESPACE="openshift-cnv" | |
| CRD="virtualmachineinstances.kubevirt.io" | |
| BACKUP="/tmp/vmi-crd-backup-$(date +%Y%m%d-%H%M%S).json" | |
| PATCHED="/tmp/vmi-crd-patched.json" | |
| export KUBECONFIG | |
| echo "======================================================" | |
| echo " KubeVirt CRD Checksum Fix (Issue #17858 workaround)" | |
| echo "======================================================" | |
| echo "" | |
| # ── Step 1: Scale down operators ────────────────────────────────────────────── | |
| echo "[1/4] Scaling down hco-operator and virt-operator..." | |
| oc scale deployment hco-operator -n "${NAMESPACE}" --replicas=0 | |
| oc scale deployment virt-operator -n "${NAMESPACE}" --replicas=0 | |
| echo " Waiting for operator pods to terminate..." | |
| oc wait --for=delete pod -l name=hyperconverged-cluster-operator \ | |
| -n "${NAMESPACE}" --timeout=60s 2>/dev/null || true | |
| oc wait --for=delete pod -l kubevirt.io=virt-operator \ | |
| -n "${NAMESPACE}" --timeout=60s 2>/dev/null || true | |
| echo " Operators scaled down." | |
| echo "" | |
| # ── Step 2: Backup and patch the CRD ───────────────────────────────────────── | |
| echo "[2/4] Backing up CRD to ${BACKUP}..." | |
| oc get crd "${CRD}" -o json > "${BACKUP}" | |
| echo " Backup saved." | |
| echo "" | |
| echo "[3/4] Patching CRD (int32 -> int64 with uint32 bounds)..." | |
| python3 - "${BACKUP}" "${PATCHED}" << 'PYEOF' | |
| import json, sys | |
| input_file, output_file = sys.argv[1], sys.argv[2] | |
| with open(input_file) as f: | |
| crd = json.load(f) | |
| patched = 0 | |
| def patch(obj, path=''): | |
| global patched | |
| if isinstance(obj, dict): | |
| if (obj.get('type') == 'integer' and | |
| obj.get('format') == 'int32' and | |
| path.endswith('/checksum')): | |
| obj['format'] = 'int64' | |
| obj['minimum'] = 0 | |
| obj['maximum'] = 4294967295 | |
| patched += 1 | |
| print(f" Patched: {path.split('/schema/')[1] if '/schema/' in path else path}") | |
| for k, v in obj.items(): | |
| patch(v, f'{path}/{k}') | |
| elif isinstance(obj, list): | |
| for i, v in enumerate(obj): | |
| patch(v, f'{path}[{i}]') | |
| patch(crd) | |
| # Remove server-managed fields before replace | |
| for field in ['resourceVersion', 'uid', 'generation', | |
| 'creationTimestamp', 'managedFields', 'annotations']: | |
| crd['metadata'].pop(field, None) | |
| with open(output_file, 'w') as f: | |
| json.dump(crd, f) | |
| print(f" Total fields patched: {patched}") | |
| PYEOF | |
| oc replace -f "${PATCHED}" | |
| echo "" | |
| # ── Step 3: Verify ──────────────────────────────────────────────────────────── | |
| echo "[4/4] Verifying patch..." | |
| FORMAT=$(oc get crd "${CRD}" \ | |
| -o jsonpath='{.spec.versions[0].schema.openAPIV3Schema.properties.status.properties.volumeStatus.items.properties.containerDiskVolume.properties.checksum.format}') | |
| if [[ "${FORMAT}" == "int64" ]]; then | |
| echo " checksum format = int64 ✓ Patch confirmed." | |
| else | |
| echo " ERROR: checksum format = ${FORMAT} — patch may have failed!" | |
| exit 1 | |
| fi | |
| echo "" | |
| echo "======================================================" | |
| echo " Done. Current state:" | |
| echo "======================================================" | |
| echo "" | |
| oc get deployment hco-operator virt-operator -n "${NAMESPACE}" \ | |
| -o custom-columns='NAME:.metadata.name,REPLICAS:.spec.replicas' | |
| echo "" | |
| echo " virt-api, virt-controller, virt-handler: still running" | |
| oc get deployment virt-api virt-controller -n "${NAMESPACE}" \ | |
| -o custom-columns='NAME:.metadata.name,READY:.status.readyReplicas' | |
| echo "" | |
| echo " CRD backup saved to: ${BACKUP}" | |
| echo "" | |
| echo " NOTE: This is a WORKAROUND. For a permanent fix, upgrade" | |
| echo " CNV to a version shipping KubeVirt >= v1.8.4." | |
| echo " Issue: https://github.com/kubevirt/kubevirt/issues/17858" | |
| echo "======================================================" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment