Per operator: under the SiteLink IP plan there should never be GUID/MAC/IP conflicts. Reframed the merge checks accordingly - they are tripwires for plan drift (un-renumbered site) or stale inventory (same pod recorded in two site files), not expected events. The merge now exits 3 when any warning fired (master still written) so event-day scripts can gate on a clean merge; 0 = clean, 1 = usage, 2 = hard error. Verified: same-file-twice merge exits 3, clean merge exits 0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
91 lines
3.6 KiB
Markdown
91 lines
3.6 KiB
Markdown
# SiteConfigMerge
|
||
|
||
Decodes TeslaConsole `.siteconfig` files and merges multiple sites' configs into a
|
||
single `master.siteconfig` for the central console that commands the fleet during a
|
||
SiteLink event.
|
||
|
||
The `.siteconfig` files themselves are **not** stored in this repo — they change over
|
||
time; sites hand them over as `<siteName>.siteconfig` when an event is being set up.
|
||
|
||
## Usage
|
||
|
||
```
|
||
SiteConfigMerge dump <file.siteconfig> [...]
|
||
```
|
||
Decode and print each file: squads, pods, IPs, MACs, host types, key presence, and
|
||
the TeslaConsole assembly identity that serialized it.
|
||
|
||
```
|
||
SiteConfigMerge merge -o master.siteconfig FSA.siteconfig Pharaoh.siteconfig [...]
|
||
```
|
||
Merge sites into one config:
|
||
|
||
- The **site name is taken from each input's file name** (`FSA.siteconfig` → `FSA`).
|
||
- Every squad is renamed **`<siteName>-<original squad name>`** (`FSA-bay1`);
|
||
unnamed squads become `<siteName>-squadN`.
|
||
- **Pod records are copied byte-for-byte** from the inputs — GUIDs, IPs, MACs, keys,
|
||
art paths all pass through untouched. Only the squad records (which carry the
|
||
name) are re-serialized.
|
||
- The output declares the TeslaConsole assembly identity captured from the first
|
||
input, so the console accepts it as its own.
|
||
|
||
### Consistency checks
|
||
|
||
**Under the SiteLink IP plan, none of these should ever fire.** They are tripwires
|
||
for plan drift, checked for free at the natural checkpoint (merge time, right before
|
||
an event):
|
||
|
||
- **same IP at two sites** — a site hasn't renumbered into its `10.0.<site>.0/24`
|
||
yet (e.g. still on legacy `200.0.0.x` or flat `10.0.0.x`);
|
||
- **duplicate pod GUID or MAC** — orthogonal to the IP plan: GUIDs are minted at
|
||
provisioning and MACs are burned into NICs, so a hit means *stale inventory* —
|
||
the same physical pod recorded in two site files (pod changed hands without
|
||
re-provisioning, or a siteconfig was copied as a template).
|
||
|
||
The master is still written, but the exit code reflects the result so event
|
||
scripts can gate on a clean merge:
|
||
|
||
| Exit code | Meaning |
|
||
|-----------|---------|
|
||
| 0 | clean merge |
|
||
| 1 | usage error |
|
||
| 2 | hard error (unreadable file, duplicate post-rename squad name — same site file given twice) |
|
||
| 3 | merged, but with warnings — resolve before the event |
|
||
|
||
## Build
|
||
|
||
```
|
||
dotnet build -c Release
|
||
```
|
||
Targets .NET Framework 4.8 (same toolchain as TeslaSuite); output at
|
||
`bin\Release\net48\SiteConfigMerge.exe`, runs on any Windows 10/11 box.
|
||
|
||
## File format (from `TeslaSuite\Console\TeslaConsole\Site.cs`)
|
||
|
||
```
|
||
int32 squadCount
|
||
per squad:
|
||
BinaryFormatter(TeslaConsole.Squad) mGuid, mName, mOnline
|
||
int32 podCount
|
||
podCount × BinaryFormatter(TeslaConsole.Pod)
|
||
mId, mIPAddress, mGateway, mDns, mSubnet, mHostName,
|
||
mKey, mMacAddress, mName, mPodArtPath, mHostType, mOnline
|
||
```
|
||
|
||
The tool uses stand-in types with a `SerializationBinder` mapping `TeslaConsole.*`
|
||
both directions, so it has no build dependency on the TeslaSuite repo.
|
||
|
||
## Verification status (2026-07-10)
|
||
|
||
- Decoded a real `local.siteconfig` (squad `bay1`, TeslaConsole 4.11.4.1 identity).
|
||
- Merged two simulated sites; duplicate-GUID and IP-overlap warnings fired correctly.
|
||
- **The real `TeslaConsole.exe` (4.11.4.1) loaded the merged output through its own
|
||
`Site.LoadFromFile`** — squads renamed, pods intact (reflection harness).
|
||
|
||
## Deploying to the central console
|
||
|
||
TeslaConsole loads `local.siteconfig` from its common-appdata directory at startup
|
||
(`Site.Load()`). To arm the central console for an event: back up its existing
|
||
`local.siteconfig`, drop `master.siteconfig` in its place under that name, restart
|
||
the console. Restore the backup after the event.
|