# PON Fleet Upgrader An Electron desktop app for bulk ONU firmware upgrades against a **Ciena MicroClimate Management System (MCMS) 6.2** PON Manager. Filters a fleet of ONUs, previews the planned writes, and stages new firmware to each device's **inactive bank** so the forced reboot is deferred until the next natural restart window. Two execution modes: - **Bulk task (Procedure 8, recommended)** — creates a single `AUTO-TASK-CFG` via `PUT /v3/tasks/configs//`. MCMS owns the rollout (retries, pacing, scheduled start). - **Per-ONU PUT (Procedure 7)** — iterates the selected ONUs, fetches each `ONU-CFG`, mutates `FW Bank {Ptr,Files,Versions}`, and `PUT`s the full document back. Slower, but you see errors live per device. ## Prerequisites - Node.js 18+ and npm - Network reachability to your MCMS host - An MCMS user with ONU write + Files write permissions - A compatible ONU firmware `.bin` file (already uploaded via this tool or the vendor UI into `/files/onu-firmware/`) ## Install & run ```bash cd pon-fleet-upgrader npm install npm start ``` This launches an Electron window. Use `npm run check` to syntax-check all source files without launching the app. ## Bank strategy MCMS stores firmware in two slots per ONU (`FW Bank Files[0/1]`, `FW Bank Versions[0/1]`) with `FW Bank Ptr` pointing at the active one. | Current `FW Bank Ptr` | Tool writes to slot | Why | |-----------------------|---------------------|-----| | `0` | `1` | Don't overwrite active image | | `1` | `0` | Don't overwrite active image | | `65535` (unset) | `1` | Matches Procedure 7 example; slot 0 stays as factory fallback | The tool computes this per ONU and buckets the selection by target slot when submitting a bulk task (MCMS's `AUTO-TASK-CFG.Task Details.ONU.FW Bank Ptr` accepts a single slot number, so each bucket becomes one task). ## Safety notes - **Always validate on one ONU first.** Select a single device, run in per-ONU mode, confirm the ONU recovers on slot N before using bulk task on the rest of the fleet. - **Don't blank the active slot.** The planner preserves both slots' existing `Files`/`Versions` and only writes the target slot. - **Scheduled start is UTC.** The datetime-local picker converts from your local timezone to UTC before submitting the `AUTO-TASK-CFG`. - **Leave the session short.** Log out when done — MCMS sessions don't auto-expire and a stale cookie on a shared workstation is an unnecessary exposure. ## Filters The left panel supports: - **Name / address contains** — substring match over `ONU.Name`, `ONU.Address`, and `_id` - **PON mode** — server-side Mongo filter on `ONU.PON Mode` - **Active version matches** — substring match on the version string in whichever slot `FW Bank Ptr` points to - **Model / version family** — substring match across *both* slots' version strings, useful for fleet cuts like `EV051` (all Everest 5.1x) The server-side projection is narrow (serial, name/address, PON mode, bank state). The full ONU-CFG is only re-fetched at plan time. ## Files ``` pon-fleet-upgrader/ ├── package.json ├── main.js # Electron main process, IPC handlers ├── preload.js # contextBridge exposing window.api.* ├── src/ │ ├── mcms-api.js # HTTPS client with tough-cookie jar + CSRF │ └── bank-strategy.js # inactive-bank selection + plan computation └── renderer/ ├── index.html # Login / fleet / campaign views ├── app.css └── app.js # UI logic ``` ## Known limitations - The `/v1/onus//upgrade/status/` path used by the original question isn't part of the dev-guide-documented surface; if your MCMS returns 404 for it, fall back to polling `GET /v1/onus/configs//` and watching `FW Bank Versions` + `FW Bank Ptr` change. - Progress of a bulk task is reported back by MCMS in its own task status collection — the tool currently submits and then leaves monitoring to the PON Manager UI. Follow-up work: poll `/v3/tasks/states//`. - No offline mode / cached fleet snapshot. Each `Load fleet` hits the API. - PATCH endpoints aren't used — MCMS requires full-document PUTs for `ONU-CFG` updates (the dev guide is explicit about this). ## License Internal use only.