-- Argo CD 3.5.2 compatibility: worker Pods have a finite lifetime, but should be -- Healthy while Ready. Apply as resource.customizations.health.Pod in argocd-cm. -- Also set resource.customizations.useOpenLibs.Pod: "true" for string.match. -- This override applies to all Pods, so the fallback preserves the upstream -- 3.5.2 rules in gitops-engine/pkg/health/health_pod.go. Recheck on Argo upgrades. local metadata = obj.metadata or {} local labels = metadata.labels or {} local annotations = metadata.annotations or {} local spec = obj.spec or {} local status = obj.status or {} local worker = labels["app.kubernetes.io/managed-by"] == "bridge-orchestrator" and (labels["bridge.role"] == "session" or labels["bridge.role"] == "proxy") and labels["bridge.worker_id"] ~= nil -- Hook Pods must finish even if someone copies worker labels onto them. local hook = annotations["argocd.argoproj.io/hook"] ~= nil or annotations["helm.sh/hook"] ~= nil local service = spec.restartPolicy == "Always" or (worker and not hook) local containers = status.containerStatuses or {} local init = status.initContainerStatuses or {} local message = status.message or "" local function result(state, detail) return {status = state, message = detail or message} end local function waitingError(list) for _, ctr in ipairs(list) do local waiting = (ctr.state or {}).waiting if waiting ~= nil then local reason = waiting.reason or "" if string.match(reason, "^Err") or string.match(reason, "Error$") or string.match(reason, "BackOff$") then return waiting.message or reason end end end return nil end if service then local errorMessage = waitingError(containers) -- Include broken init containers for workers, without changing ordinary Pods. if errorMessage == nil and worker and not hook then errorMessage = waitingError(init) end if errorMessage ~= nil then return result("Degraded", errorMessage) end end if status.phase == "Pending" then return result("Progressing") end if status.phase == "Succeeded" then return result("Healthy") end if status.phase == "Failed" then if message ~= "" then return result("Degraded") end for _, list in ipairs({init, containers}) do for _, ctr in ipairs(list) do local terminated = (ctr.state or {}).terminated if terminated ~= nil then if terminated.message ~= nil and terminated.message ~= "" then return result("Degraded", terminated.message) end if terminated.reason == "OOMKilled" then return result("Degraded", "OOMKilled") end if terminated.exitCode ~= nil and terminated.exitCode ~= 0 then return result("Degraded", 'container "' .. ctr.name .. '" failed with exit code ' .. terminated.exitCode) end end end end return result("Degraded") end if status.phase == "Running" then if service then for _, condition in ipairs(status.conditions or {}) do if condition.type == "Ready" and condition.status == "True" then return result("Healthy") end end for _, ctr in ipairs(containers) do if (ctr.lastState or {}).terminated ~= nil then return result("Degraded") end end return result("Progressing") end if spec.restartPolicy == "Never" or spec.restartPolicy == "OnFailure" then return result("Progressing") end end return result("Unknown")