docs(apps): trim otbr, trmnl, zigbee2mqtt — and correct a copy-pasted falsehood
Comments only across otbr, trmnl/renderer, zigbee2mqtt-deployment and the
smartctl ServiceMonitor. All four still parse; monitoring-rules still renders.
Each keeps the instruction and loses the investigation. otbr stays disabled with
the condition for re-enabling it — verified partition merge, one OMR prefix, the
Nest routers visible — instead of the paragraph reconstructing how the split
partition was diagnosed. Its socat bridge keeps both dead ends, because they are
what stops someone simplifying it: forkpty needs a socat the image does not ship,
and a sidecar cannot supply the PTY because devpts is per-container. zigbee2mqtt
keeps "never run alongside ZHA, and never start without the restored coordinator
backup or you form a new network and drop every device", and loses the cutover
diary around it.
The ServiceMonitor correction is the useful part. Four monitors carry the claim
that kube-prometheus-stack's Prometheus "selects ServiceMonitors by this label;
without it the resource exists but is never discovered". The live resource has
serviceMonitorSelector {} and podMonitorSelector {} — empty, so every monitor is
picked up regardless of labels. Only ruleSelector matches on
release=kube-prometheus-stack, which is why the same sentence on the disk-wear
PrometheusRule is correct and this one is not.
Corrected here for the monitor I added yesterday, which is where I introduced it
by copying a neighbour. The other three carry the same wrong sentence and are
left for a pass that can check each rather than sed across them.
This commit is contained in:
@@ -6,12 +6,9 @@ metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: zigbee2mqtt
|
||||
spec:
|
||||
# CUTOVER DONE (2026-07-23): ZHA disabled, the coordinator-backup Secret is
|
||||
# populated in OpenBao, and Z2M is now the live Zigbee stack — so replicas is
|
||||
# 1. It shipped at 0 as a safety interlock (Z2M contends with ZHA for the
|
||||
# coordinator's single TCP session, and starting without the restored backup
|
||||
# would form a NEW network and drop every device); that interlock is spent
|
||||
# once the migration is committed. To roll back, set 0 and re-enable ZHA.
|
||||
# Z2M is the live Zigbee stack. Never run it alongside ZHA: they contend for
|
||||
# the coordinator's single TCP session, and a Z2M start without the restored
|
||||
# coordinator backup forms a NEW network and drops every paired device.
|
||||
replicas: 1
|
||||
# RWO PVC → single writer; never run two pods against the same /app/data.
|
||||
strategy:
|
||||
@@ -39,14 +36,10 @@ spec:
|
||||
# network_key, the latter extracted from the OpenBao coordinator backup
|
||||
# as a natural-byte-order int array.
|
||||
- name: seed-data
|
||||
# alpine + jq, built by .woodpecker/build-ci-images.yml from
|
||||
# ci/images/alpine-jq/. Replaces `apk add --no-cache jq` on every pod
|
||||
# start: tools belong in the image, not installed at runtime.
|
||||
# Referenced by tag rather than digest — these are our own images.
|
||||
# DATED tag, not :latest, matching the ci-ansible:2026-04-29 precedent
|
||||
# in kubernetes/infrastructure/netbird-backup/cronjob.yaml. With
|
||||
# :latest, rebuilding this base for some unrelated consumer would
|
||||
# silently change what this init container runs on its next pod
|
||||
# Our own alpine + jq image, built by build-ci-images.yml. DATED tag,
|
||||
# never :latest — rebuilding this base for an unrelated consumer
|
||||
# would otherwise silently change what this init container runs on
|
||||
# its next pod
|
||||
# restart, with no diff here to review — and this is the container that
|
||||
# renders the Zigbee network key. Bumping the tag is a deliberate,
|
||||
# reviewable act; the cost is remembering to bump it.
|
||||
|
||||
@@ -5,9 +5,8 @@ metadata:
|
||||
namespace: monitoring
|
||||
labels:
|
||||
app.kubernetes.io/name: smartctl-exporter
|
||||
# kube-prometheus-stack's Prometheus resource selects ServiceMonitors
|
||||
# by this label; without it the resource exists but is never
|
||||
# discovered.
|
||||
# Not required for discovery — serviceMonitorSelector is empty — but kept
|
||||
# for consistency with the other monitors.
|
||||
release: kube-prometheus-stack
|
||||
spec:
|
||||
selector:
|
||||
|
||||
@@ -5,25 +5,15 @@ metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: otbr
|
||||
spec:
|
||||
# Disabled 2026-07-11 (replicas: 0) after otbr broke Matter.
|
||||
# DISABLED (replicas: 0). Running otbr broke Matter: its radio is RF-isolated
|
||||
# enough from the Nest mesh that it forms a rival partition of the same
|
||||
# network, and the two bridge only over Ethernet — fast enough for a ping,
|
||||
# too slow for the fragmented CASE handshake, so devices stay discoverable
|
||||
# while every commissioning attempt times out.
|
||||
#
|
||||
# otbr is seeded with the Nest network's dataset so it should join the
|
||||
# existing partition as an additive co-BR. In practice it does not merge
|
||||
# cleanly: its SLZB-06 radio is RF-isolated enough from the Nest mesh that
|
||||
# otbr elects itself leader of a rival partition (or the network re-addresses
|
||||
# under a new OMR prefix, observed fd5f -> fdd5). The two same-network
|
||||
# partitions then bridge only over the Ethernet backbone, which carries a
|
||||
# ping but is too slow for the large fragmented CASE handshake -- every
|
||||
# Matter device stays mDNS-discoverable while CASE times out. Removing otbr
|
||||
# re-merges the mesh onto the Nest hubs and Matter recovers.
|
||||
#
|
||||
# This is NOT a diagnosis of a specific config bug: the DHCP/sbr routing
|
||||
# changes (19a4482, df61407) were investigated and matter-server's IPv6 path
|
||||
# to the mesh works (reaches devices, ping ok); sbr's v6 table 100 is an
|
||||
# inert orphan and otbr's eth0 default is outranked by net1's pref-high RA
|
||||
# default. The instability is at the Thread partition layer. Re-enable only
|
||||
# after the co-BR integration is verified to MERGE (one partition, one OMR,
|
||||
# otbr's router table shows the Nest routers) instead of split.
|
||||
# The instability is at the Thread partition layer, not in the config below.
|
||||
# Re-enable only once co-BR integration is verified to MERGE: one partition,
|
||||
# one OMR prefix, and the Nest routers visible in otbr's router table.
|
||||
replicas: 0
|
||||
strategy:
|
||||
type: Recreate
|
||||
@@ -46,25 +36,17 @@ spec:
|
||||
# (slzb-thread.renner.uno). Dropping the workload-class=pinned
|
||||
# toleration lets the edge taint keep it off the tiny edge box.
|
||||
containers:
|
||||
# The Thread RCP lives on a SLZB-06 over Ethernet at
|
||||
# slzb-thread.renner.uno:6638 (Serial-over-IP). otbr-agent's
|
||||
# spinel transport supports `spinel+hdlc+forkpty://<exec>?<args>`
|
||||
# which forks an exec whose stdio becomes the spinel-HDLC
|
||||
# transport, but the upstream openthread/otbr image does NOT
|
||||
# ship socat (or any TCP-stream tool), so that URL form ends in
|
||||
# silent ENOENT and otbr-agent dies right after logging the
|
||||
# radio URL.
|
||||
# The Thread RCP is a network-attached radio (Serial-over-IP), so the
|
||||
# spinel transport needs a TCP-to-PTY bridge. Two obvious approaches
|
||||
# do not work and should not be retried:
|
||||
#
|
||||
# A sidecar socat won't work either: each container has its own
|
||||
# devpts namespace, so a PTY (e.g. /dev/pts/0) created in a
|
||||
# sibling container is invisible from this container — a shared
|
||||
# emptyDir symlink to /dev/pts/0 is dangling.
|
||||
# - `spinel+hdlc+forkpty://` needs socat, which the upstream image
|
||||
# does not ship; the URL fails with a silent ENOENT and otbr-agent
|
||||
# dies right after logging it.
|
||||
# - A sidecar cannot provide it either: devpts is per-container, so
|
||||
# a PTY created next door is invisible here and the symlink dangles.
|
||||
#
|
||||
# The bridge has to live in the otbr container's own namespace.
|
||||
# Install socat at startup via apt (Ubuntu 18.04 base, no egress
|
||||
# restrictions on this namespace), run it in the background as
|
||||
# the spinel-HDLC TCP↔PTY bridge, then exec the upstream
|
||||
# entrypoint with RADIO_URL pointing at the PTY symlink.
|
||||
# Hence socat is installed at startup and run inside this container.
|
||||
- name: otbr
|
||||
image: openthread/otbr:latest
|
||||
command:
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
# Headless renderer: screenshots the Home Assistant e-ink dashboard,
|
||||
# dithers it to 16 greys and hands it to Terminus.
|
||||
#
|
||||
# Upstream ships this as a Home Assistant add-on. Our HA is a plain
|
||||
# container with no Supervisor, so it runs standalone here instead —
|
||||
# viable because the app prefers HOME_ASSISTANT_URL/ACCESS_TOKEN env
|
||||
# vars over /data/options.json and authenticates with an ordinary
|
||||
# long-lived token. SUPERVISOR_TOKEN is deliberately NOT set: it only
|
||||
# flips an internal isAddOn flag, and setting it would switch the app
|
||||
# to add-on behaviour (fixed port, /data assumptions).
|
||||
# Upstream ships this as a Home Assistant add-on; it runs standalone here
|
||||
# because the app prefers the env vars over /data/options.json. Do NOT set
|
||||
# SUPERVISOR_TOKEN — it flips an internal isAddOn flag and switches the app to
|
||||
# add-on behaviour (fixed port, /data assumptions).
|
||||
#
|
||||
# DIRECTION OF TRAVEL, which is the non-obvious part: with the
|
||||
# byos-hanami webhook in `uri` delivery mode the renderer does NOT
|
||||
# push image bytes. It POSTs a URL pointing at its own /output/<file>
|
||||
# endpoint, and TERMINUS FETCHES THE IMAGE BACK from it. That is why
|
||||
# both live in this namespace — the pull is intra-namespace and is
|
||||
# already permitted by the default-deny-ingress rule.
|
||||
# DIRECTION OF TRAVEL, the non-obvious part: in `uri` delivery mode the
|
||||
# renderer does not push image bytes. It POSTs a URL to its own /output/<file>
|
||||
# and Terminus fetches the image back. Both therefore live in this namespace,
|
||||
# where that pull is already permitted.
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
|
||||
Reference in New Issue
Block a user