otbr: strip the CR from ot-ctl state before matching it #140

Merged
k.renner merged 1 commits from fix/otbr-state-crlf into master 2026-07-09 12:21:45 +00:00
Owner

Follow-up to #139

#139 worked. The pod now logs otbr: persisted dataset found after 18 attempt(s); activating Thread, and Thread came back after twelve days:

ot-ctl state     -> leader
ot-ctl br state  -> running
ot-ctl partitionid -> 180679217
ot-ctl br omrprefix -> Local/Favored: fd5f:5689:e6dc:1::/64

The dataset appeared ~36 seconds after ot-ctl started answering (18 polls × 2s), so the old single-shot check never had a chance.

The bug this fixes

The attach-confirmation block I added in #139 then printed:

otbr: WARNING Thread not attached after 60s (state=leader)

ot-ctl speaks a serial-console protocol and ends lines with CRLF. So ot-ctl state | head -1 is leader\r — 7 bytes:

$ ot-ctl state | head -1 | od -c
0000000   l   e   a   d   e   r  \r  \n

That matches no shell glob, so the case fell through to the warning branch. And the stray CR is invisible in the log, so the message reads as a flat self-contradiction.

Fix: tr -d '\r' on the captured state.

Verified

  • od -c in the live pod confirms leader\r\n.
  • case "leader\r" in leader) … → no match; tr-stripped → match. Reproduced both ways offline.
  • bash -n clean on the extracted script; kubectl kustomize builds.

The warning was cosmetic — Thread attached correctly regardless — but a health line that states the opposite of the truth is worse than no line at all, and this one would have sent the next person hunting a phantom MLE failure.

Merging restarts the pod again; expect otbr: Thread attached as leader and no warning.

## Follow-up to #139 #139 worked. The pod now logs `otbr: persisted dataset found after 18 attempt(s); activating Thread`, and Thread came back after twelve days: ``` ot-ctl state -> leader ot-ctl br state -> running ot-ctl partitionid -> 180679217 ot-ctl br omrprefix -> Local/Favored: fd5f:5689:e6dc:1::/64 ``` The dataset appeared **~36 seconds** after `ot-ctl` started answering (18 polls × 2s), so the old single-shot check never had a chance. ## The bug this fixes The attach-confirmation block I added in #139 then printed: ``` otbr: WARNING Thread not attached after 60s (state=leader) ``` `ot-ctl` speaks a serial-console protocol and ends lines with **CRLF**. So `ot-ctl state | head -1` is `leader\r` — 7 bytes: ``` $ ot-ctl state | head -1 | od -c 0000000 l e a d e r \r \n ``` That matches no shell glob, so the `case` fell through to the warning branch. And the stray CR is invisible in the log, so the message reads as a flat self-contradiction. Fix: `tr -d '\r'` on the captured state. ## Verified - `od -c` in the live pod confirms `leader\r\n`. - `case "leader\r" in leader) …` → no match; tr-stripped → match. Reproduced both ways offline. - `bash -n` clean on the extracted script; `kubectl kustomize` builds. The warning was cosmetic — Thread attached correctly regardless — but a health line that states the opposite of the truth is worse than no line at all, and this one would have sent the next person hunting a phantom MLE failure. Merging restarts the pod again; expect `otbr: Thread attached as leader` and no warning.
k.renner added 1 commit 2026-07-09 12:19:21 +00:00
#139 landed and did its job: the pod now logs

  otbr: persisted dataset found after 18 attempt(s); activating Thread

and `ot-ctl state` reports `leader`, `ot-ctl br state` reports `running`,
with the OMR prefix fd5f:5689:e6dc:1::/64 published again. The dataset
appeared ~36s after ot-ctl began answering, so the old single-shot check
never stood a chance.

But the attach-confirmation block in that same PR then printed:

  otbr: WARNING Thread not attached after 60s (state=leader)

ot-ctl speaks a serial-console protocol and terminates lines with CRLF, so
`ot-ctl state | head -1` yields `leader\r` -- 7 bytes. That matches no shell
glob, so the `case` fell through to the warning, and the stray CR is
invisible in the log, making the message read as a flat contradiction.

Verified with `od -c` in the live pod (`l e a d e r \r \n`) and by
`case "leader\r" in leader) ...` failing to match while the tr-stripped
value matches. `bash -n` clean, kustomize builds.

The warning was cosmetic -- Thread attached correctly either way -- but a
health line that says the opposite of the truth is worse than no line.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
k.renner merged commit 2a6bf6c3e3 into master 2026-07-09 12:21:45 +00:00
Sign in to join this conversation.