Skip to content

fix(boot): OTA-enable app layer + sensorgnome ordering + app-service retry-forever - #52

Merged
bobfogg merged 1 commit into
lts_26_07.isofrom
fix/boot-sequence-hardening
Jul 30, 2026
Merged

fix(boot): OTA-enable app layer + sensorgnome ordering + app-service retry-forever#52
bobfogg merged 1 commit into
lts_26_07.isofrom
fix/boot-sequence-hardening

Conversation

@bobfogg

@bobfogg bobfogg commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Boot-sequence hardening from the boot-sequence KB review. Three findings, all verified against ground truth (not the doc's word).

Findings A + B + #11

A — app layer wasn't OTA-enabled. install-systemd.sh's MUST_BE_ENABLED covered only the 10 native/OS units; the 7 Node/SensorGnome units were deployed as files but enabled only by Ansible/manufacturing. A lost symlink or an Ansible-free image → full native layer, no app layer. Now they're in the list, so OTA self-heals enablement.

B — sensorgnome ordered on a stale premise (the doc's own fix was incomplete). The doc caught that After=station-boot was stale (station-boot no longer writes station-id) and suggested After=ctt-board-detect. But machine.js reads two files synchronously at load: /etc/ctt/station-id (ctt-board-detect) and /etc/bootcount (bootcount.service). sensorgnome and bootcount were both After=station-boot, neither after the other → a real race. Corrected to After=ctt-board-detect.service bootcount.service; dropped the malformed WantedBy=…station-boot.service.

#11 — app services couldn't retry forever. station-* had Restart=on-failure but no start-limit override → a transient boot crash-loop hits systemd's default 5-in-10s give-up and lands failed on a headless station. Added StartLimitIntervalSec=0 + RestartSec=5 (matches the radio driver).

Validation

  • systemd-analyze verify clean on all four app units on a real station (correct [Unit]/[Service] placement, no cycle).
  • The premise behind A/B — NM treats an absent autoconnect line as default yes — confirmed on real NM 1.30.6.
  • systemd ordering is deterministic from the directives; a reboot would only re-confirm what verify already guarantees (offered as belt-and-suspenders).

Also adds the missing CHANGELOG entry for the deploy-dir OTA-clobber fix (PR #50).

🤖 Generated with Claude Code

…e retry-forever

Boot-sequence hardening from the boot-sequence KB review (ground-truth verified):

- install-systemd.sh MUST_BE_ENABLED now covers the 7 app-layer units
  (station-hardware-server/radio/web/lcd-interface, station-boot, bootcount,
  sensorgnome) — previously enabled only by Ansible, so a lost symlink / Ansible-free
  image came up with no app layer. OTA now self-heals it.
- sensorgnome.service: After=ctt-board-detect.service bootcount.service (the units that
  produce its synchronous inputs /etc/ctt/station-id + /etc/bootcount). The old
  After=station-boot was a stale premise and raced bootcount; dropped the malformed
  WantedBy=...station-boot.service.
- station-{hardware-server,radio,web,lcd}-interface: StartLimitIntervalSec=0 + RestartSec=5
  so a transient boot crash-loop retries forever instead of hitting systemd's default
  5-in-10s give-up and leaving a headless station dark (matches the radio driver).

Validated: systemd-analyze verify clean on all four app units on a real station; NM
absent-line default confirmed = yes on NM 1.30.6.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bobfogg
bobfogg merged commit 6523569 into lts_26_07.iso Jul 30, 2026
@bobfogg
bobfogg deleted the fix/boot-sequence-hardening branch July 30, 2026 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant