Skip to content

Improve custom-build fleet deployment management - #174

Draft
ODevStudio wants to merge 4 commits into
mainfrom
odev/custom-ota-local-noop
Draft

Improve custom-build fleet deployment management#174
ODevStudio wants to merge 4 commits into
mainfrom
odev/custom-ota-local-noop

Conversation

@ODevStudio

@ODevStudio ODevStudio commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #172.

Summary

  • Add a server-side fleet build library of immutable ready-build references without copying or deleting R2 artifacts.
  • Separate desired deployment state from authenticated, device-reported installed state.
  • Add atomic selected/all-scale assignment and deliberate clearing, with ownership and target validation.
  • Replace per-scale browser status requests with one aggregated fleet overview and one state resolution per unique hash.
  • Make the compile-time custom combination hash authoritative on-device and return locally before any redundant OTA retrieval.

API and data model

New authenticated routes:

  • POST /api/v1/device/check-in
  • GET /api/v1/fleet/overview
  • GET|POST /api/v1/fleet/builds
  • PATCH|DELETE /api/v1/fleet/builds/<combination-hash>
  • POST /api/v1/fleet/assignments

Fleet records now retain build references with label, firmware/options summary, and added timestamp. Device records lazily gain desired_updated_at, installed_combination, firmware_version, and last_seen_at. Existing records remain readable with missing fields treated as null. Bulk writes are chunked at the Durable Object 128-entry storage limit while remaining inside one transaction.

Browser

The fleet view now provides saved builds, full-hash copy, installed and desired columns, deployment state, last-seen time, responsive scale selection, select-all, selected/all-scale assignment, deliberate clearing, and confirmations for multi-scale changes. Hashes remain full-length identities; the browser displays a 12-character uppercase prefix.

Firmware

The Custom Build menu performs one compact authenticated check-in. Custom firmware reports normalized HDS_CUSTOM_BUILD_COMBINATION_HASH; official firmware reports null.

After validating the returned full desired hash, firmware compares it with that local compile-time identity. An exact match shows Already installed and the 8-character uppercase prefix, then returns before manifest, signature, firmware, LittleFS, OTA-state, or reboot paths. A differing hash continues through the existing signed-manifest flow. Install confirmation shows target version plus hash prefix.

Scale resources

Controlled esp32s3 size comparison against 45edef5:

  • Static RAM: 56,508 bytes before and after, delta 0 bytes.
  • Flash: 1,669,429 bytes before; 1,668,065 bytes after, delta -1,364 bytes.
  • OTA task stack: unchanged at 24,576 bytes.
  • Heap: no persistent or fleet-proportional allocation. Check-in adds only operation-local strings and bounded request/response JSON; exact peak heap was not instrumented.

Fleet size and saved-build count therefore do not change scale-side storage or steady-state memory.

Verification

  • node --test cloudflare/custom-build-worker/test/fleet.test.mjs - 10 passed
  • node --test cloudflare/custom-build-worker/test/configurator.test.mjs - 6 passed
  • node --test cloudflare/custom-build-worker/test/worker.test.mjs - 2 passed
  • python tools/test_plugin_catalog.py
  • python tools/test_plugin_ci_contract.py
  • python tools/test_custom_build_ota_contract.py
  • python tools/test_custom_build_execution.py
  • python tools/test_custom_ota_public_key_header.py
  • python tools/test_custom_cache_transport.py
  • python tools/test_pull_ota_contract.py
  • python tools/test_ota_runtime_isolation_contract.py
  • python tools/test_ota_rollback_contract.py
  • python tools/test_ota_reboot_routing_contract.py
  • python tools/test_ota_input_isolation_contract.py
  • python tools/test_ota_public_key_header.py - 9 passed
  • python tools/test_ai_docs_contract.py
  • pio run -e esp32s3
  • pio run -e esp32s3-custom
  • Browser checks at desktop and 390 px mobile widths, with zero page overflow
  • git diff --check
  • GitHub Actions: 11 checks passed

The OTA contract regression asserts that equal full hashes return before manifest retrieval or installation and that the current identity originates from the compile-time macro.

Intentionally omitted

  • No background heartbeat or WiFi wake solely for telemetry.
  • No on-scale build list, picker, deployment history, fleet collection, or new NVS field.
  • No post-boot network check-in; the next intentional Custom Build menu check-in reports the running compile-time identity.

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