diff --git a/kubernetes/apps/home-assistant/zigbee2mqtt-deployment.yaml b/kubernetes/apps/home-assistant/zigbee2mqtt-deployment.yaml index 27d8bfba..b5e06ee4 100644 --- a/kubernetes/apps/home-assistant/zigbee2mqtt-deployment.yaml +++ b/kubernetes/apps/home-assistant/zigbee2mqtt-deployment.yaml @@ -77,22 +77,29 @@ spec: # key, because "devices" sorts before "network_key". An unanchored # extraction yields a device link key, and herdsman then forms a # NEW network and drops every device. - # `?` on BOTH selectors, so every malformed shape reaches the checks - # below with a readable message instead of aborting on jq's raw - # error under `set -e`. Verified against jq 1.7.1 in this image: - # {"devices":[]} / {"network_key":{}} / {"network_key":null} - # -> "null", rc=0 (missing path is lenient) - # {"network_key":"abc"} / {"network_key":123} - # -> rc=5 without `?` on .key - # [] / "a string" -> rc=5 without `?` on .network_key too, - # since the top level is not an object - # `.network_key?.key?` returns empty for all of them at rc=0. + # `?` on BOTH selectors, plus the `// ""` fallback, so every + # malformed shape reaches the checks below with a readable message + # instead of aborting on jq's raw error under `set -e`. + # + # Measured against jq 1.7.1 in this image. The expression AS WRITTEN + # returns an EMPTY string at rc=0 for every one of: + # {} {"devices":[]} {"network_key":{}} {"network_key":null} + # {"network_key":"abc"} {"network_key":123} (parent not an object) + # [] "a string" (top level not an object) + # and the key itself for a well-formed backup. + # + # The guards are what make that true. Bare `.network_key.key` exits + # 5 with `Cannot index ... with string "key"` on the last four + # shapes, and `set -e` would abort right here, surfacing jq's error + # instead of the FATAL lines below. KEY=$(jq -r '(.network_key?.key? // "")' /backup/coordinator_backup.json) # Fail LOUDLY rather than render a wrong key, for the same reason. - # "null" is what jq prints when the path resolves to null, empty is - # what `?` yields for a malformed shape — treat both as absent, - # rather than letting them be reported as merely "non-hex", which - # sends you looking at the key instead of at the field. + # `-z` is the arm that actually fires today: `// ""` maps a null + # result to empty, so KEY is never the literal text "null" with the + # expression above. The "null" arm is belt-and-braces for a future + # edit that drops the fallback, where jq WOULD print `null`. Both + # mean "absent" — reporting them as merely "non-hex" would send you + # looking at the key instead of at the missing field. if [ "$KEY" = "null" ] || [ -z "$KEY" ]; then echo "FATAL: .network_key.key absent from coordinator_backup.json" >&2 exit 1