diff --git a/k8s/automated-nfs-backup.sh b/k8s/automated-nfs-backup.sh index 83ae174..542db5e 100644 --- a/k8s/automated-nfs-backup.sh +++ b/k8s/automated-nfs-backup.sh @@ -53,7 +53,7 @@ restore_warnings=0 total_backup_size_bytes=0 _kubectl() { - "$KUBECTL_BIN" "${KUBECTL_ARGS[@]}" "$@" + "$KUBECTL_BIN" "${KUBECTL_ARGS[@]}" "$@" /dev/null)"; then + if ! output="$(_kubectl -n "$namespace" get "$kind" -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.replicas}{"\t"}{range .metadata.ownerReferences[*]}{.kind},{end}{"\n"}{end}' 2>/dev/null)"; then log_warn "Failed to list kind '${kind}' in namespace '${namespace}' while capturing state" scale_warnings=$((scale_warnings + 1)) continue fi - while IFS=$'\t' read -r name replicas; do + while IFS=$'\t' read -r name replicas owners; do [[ -z "$name" ]] && continue + # Skip resources managed by a higher-level controller (e.g. a + # ReplicaSet owned by a Deployment) — scaling them directly + # conflicts with the owning controller and can leave workloads + # in an inconsistent state after restore. + if [[ -n "$owners" ]]; then + log_debug "Skipping ${kind}/${name} in namespace '${namespace}': owned by ${owners%,}" + continue + fi if [[ -z "$replicas" ]]; then replicas="1" log_warn "Resource ${kind}/${name} had no explicit replicas; defaulting saved value to 1" @@ -155,7 +164,7 @@ scale_resource() { local name="${3:?name is required}" local replicas="${4:?replicas is required}" retry "$SCALE_RETRY_COUNT" "$SCALE_RETRY_DELAY_SECONDS" \ - _kubectl -n "$namespace" scale "${kind}/${name}" --replicas="$replicas" >/dev/null + _kubectl -n "$namespace" scale "${kind}/${name}" --replicas="$replicas" } scale_namespace_to_zero() { @@ -260,6 +269,12 @@ wait_for_scale_state() { status="$(resource_replicas "$namespace" "$kind" "$name" '{.status.replicas}')" ready="$(resource_replicas "$namespace" "$kind" "$name" '{.status.readyReplicas}')" + # If all three values are empty the resource was likely deleted + # between capture and now — nothing to wait for. + if [[ -z "$spec" && -z "$status" && -z "$ready" ]]; then + continue + fi + [[ -z "$spec" ]] && spec="1" [[ -z "$status" ]] && status="0" [[ -z "$ready" ]] && ready="0"