📝 Update README & specifications.
This commit is contained in:
+186
-5
@@ -7,7 +7,7 @@
|
||||
| Project | `wago-modbustcp-simulator-py` |
|
||||
| Version | 1.4 (Draft for review) |
|
||||
| Date | 2026-10-03 |
|
||||
| Status | Framework phase; module addressing implemented (FR-4.3.11 v1.5 per-type numbering); service/container deployment implemented (§12); plain-text request tracing implemented (NFR-6.4); clean CLI error handling implemented (NFR-6.5 CLI part); web UI §10 in implementation (M1–M5a done: auth, overview, manipulation, diagnostics, configuration, channel names, import/export, split overview; M6 scenario view open); long-duration simulation (§8) implemented 2026-10-04 incl. PlantEnv (FR-8.2.14–16), datasets, degradation, invariants, snapshots; bench mode (§9), runtime device configuration (§11 — coupler/module/channel-name subset covered by web UI M5/M5a), multi-vendor device profiles (§13) and additional fieldbus protocols PROFINET/COMLI (§14) requested |
|
||||
| Status | Framework phase; module addressing implemented (FR-4.3.11 v1.5 per-type numbering); service/container deployment implemented (§12); plain-text request tracing implemented (NFR-6.4); clean CLI error handling implemented (NFR-6.5 CLI part); web UI §10 in implementation (M1–M5a done: auth, overview, manipulation, diagnostics, configuration, channel names, import/export, split overview; M6 scenario view open); long-duration simulation (§8) implemented 2026-10-04 incl. PlantEnv (FR-8.2.14–16), datasets, degradation, invariants, snapshots; bench mode (§9), runtime device configuration (§11 — coupler/module/channel-name subset covered by web UI M5/M5a), multi-vendor device profiles (§13) and additional fieldbus protocols PROFINET/COMLI (§14), and host network settings (§15) requested 2026-10-06 |
|
||||
| Target device simulated | WAGO 750-362 / 750-362/0000-0001 FC Modbus TCP (G4) bus coupler |
|
||||
| Reference documents | `docs/m07500362_xxxxxxxx_0en.pdf` (750-362 Modbus TCP manual), Modbus TCP specification (modbus.org) |
|
||||
|
||||
@@ -1018,7 +1018,8 @@ Terminal monitors (§9) suffice for single engineers, but FAT benches are
|
||||
message (alias-ownership rules of §8 FR-8.2.2 apply).
|
||||
- FR-10.2.10: The UI's **configuration** pages (Ethernet/port settings,
|
||||
Modbus watchdog settings, I/O Config with SAVE CONFIG, Modbus Mapping
|
||||
overview, address-selection DIP switch) are specified in §11; §10 covers
|
||||
overview, address-selection DIP switch) are specified in §11; the
|
||||
Docker-gated host network settings page is specified in §15. §10 covers
|
||||
value/state oversight and manipulation.
|
||||
- FR-10.2.11: **Channel names** (requested 2026-10-03): every module
|
||||
channel can carry an application-specific name (e.g. `start_button`,
|
||||
@@ -1594,7 +1595,187 @@ the same process-image core.
|
||||
|
||||
---
|
||||
|
||||
## 15. Roadmap (post-framework)
|
||||
## 15. Feature Request — Host Network Settings (Docker Bench Host)
|
||||
|
||||
> **Status: requested 2026-10-06, not yet planned into a roadmap
|
||||
> phase.** A settings page in the web UI that views and manipulates
|
||||
> the **host OS's IP addresses**, exposed only when an explicit
|
||||
> environment flag is set **and** the simulator runs inside Docker.
|
||||
> This section captures the requirements and the enabling
|
||||
> architecture (a whitelisted host-side agent); it does not commit to
|
||||
> a schedule.
|
||||
|
||||
### 15.1 Motivation
|
||||
|
||||
A containerized simulator (§12) cannot reach beyond its own network
|
||||
namespace. It can rebind its listen address (FR-11.3.3 dedicated-IP
|
||||
mode), but the **host's** network interfaces — what the bench network
|
||||
and the PLC under test actually see — are outside the container. As a
|
||||
result, FAT cases that depend on *network-level* events cannot be
|
||||
staged from inside the simulator today:
|
||||
|
||||
- "Re-addressing" the virtual coupler (DIP switch, FR-11.3.1–11.3.3)
|
||||
changes nothing on the bench network in the default bridge
|
||||
deployment: the PLC keeps talking to the unchanged host address, so
|
||||
the reconnect/re-addressing logic in the PLC program is never
|
||||
exercised.
|
||||
- Cable-pull / node-power-off fault cases require stopping the whole
|
||||
container (coarse — every port drops at once) or shell access to the
|
||||
bench host, breaking the "operate everything from the browser"
|
||||
workflow of the web UI (§10).
|
||||
- Moving the simulated node to a different subnet mid-bench
|
||||
(multi-bench swaps, address conflicts) likewise needs host access.
|
||||
|
||||
The requested feature closes the gap: an opt-in settings page through
|
||||
which an authenticated operator changes the host OS's IP addresses
|
||||
from the bench UI — making the simulated node's network identity
|
||||
**real on the bench network**, and making network-level fault cases
|
||||
first-class FAT scenarios.
|
||||
|
||||
### 15.2 Requirements
|
||||
|
||||
- FR-15.2.1: **Opt-in via environment flag.** The feature is disabled
|
||||
unless `WAGO_SIM_HOSTNET` is set truthy (same semantics as
|
||||
`WAGO_SIM_VERBOSE`: `1`/`true`/`yes`/`on`); the flag lives in the
|
||||
compose file so enabling it is a visible, deliberate deployment
|
||||
change. Default: off. When off, the page is absent and every
|
||||
`/api/hostnet/*` route answers 404 — no dormant surface.
|
||||
- FR-15.2.2: **Docker-only.** Independently, the simulator must detect
|
||||
a container environment — binding: the compose file sets
|
||||
`WAGO_SIM_IN_DOCKER=1` (supplementary signal: `/.dockerenv` exists).
|
||||
Outside docker the routes stay 404 regardless of the flag: a
|
||||
bare-metal operator has direct access to the OS network settings;
|
||||
the page exists precisely because a container does not.
|
||||
- FR-15.2.3: **Settings page.** A page in the web UI's configuration
|
||||
area (alongside the Port/Ethernet page, FR-11.4.1) listing the
|
||||
host's network interfaces — name, link state, current IPv4
|
||||
addresses — read from **live host state**, not a desired-state
|
||||
mirror, so out-of-band changes made on the host appear on refresh.
|
||||
The page also shows the agent's health and the effective whitelist.
|
||||
- FR-15.2.4: **Operations.** Add an address (address + prefix length),
|
||||
remove an address, replace an interface's primary address — each
|
||||
validated client-side and agent-side (address/prefix syntax,
|
||||
interface exists, interface whitelisted). Changes are
|
||||
**runtime-only** (like `ip addr add`: non-persistent across host
|
||||
reboots); v1 deliberately does not write netplan/NetworkManager/
|
||||
systemd-networkd configuration, so a host reboot is a guaranteed
|
||||
escape hatch back to the deployed addressing. Optional v2, behind
|
||||
the same whitelist and an explicit "disruptive" confirmation: set
|
||||
an interface's link up/down (cable-pull simulation).
|
||||
- FR-15.2.5: **Safety rails.** The agent enforces an interface
|
||||
**whitelist** from its own config file (operations on other
|
||||
interfaces are refused and surfaced as errors on the page); it
|
||||
snapshots an interface's address set before every mutation, and the
|
||||
page offers **undo last** / **restore interface**; every mutation
|
||||
and every refusal is appended to a single-line **audit log**
|
||||
(operator session, interface, old → new, timestamp) written to
|
||||
stdout/journald like the simulator's own logging (FR-12.2.6) and
|
||||
viewable (bounded) on the page.
|
||||
- FR-15.2.6: **Trust boundary** (same stance as FR-10.2.16): the page
|
||||
requires an authenticated session (FR-10.2.8); read-only mode
|
||||
(`WAGO_SIM_WEB_READONLY`) hides the page and answers mutations with
|
||||
403. Changing host addresses is a privileged operation by design —
|
||||
the flag must never be set on a network the operator does not
|
||||
control.
|
||||
- FR-15.2.7: **Host-side agent** (binding architecture decision). A
|
||||
container cannot change host addresses, and the simulator container
|
||||
itself shall not run privileged (§12 non-root, least-privilege
|
||||
deployment). Instead a small companion service —
|
||||
`wago-sim-hostnet-agent` — runs **on the host** (systemd unit in
|
||||
`deploy/`, root or `CAP_NET_ADMIN`), listening on a Unix domain
|
||||
socket that the compose file mounts into the container read-write.
|
||||
The agent's protocol is a narrow whitelist of operations (health,
|
||||
list, snapshot, address add/remove/change, restore) over JSON
|
||||
lines; it never executes a shell with operator input — on Linux v1
|
||||
it uses the netlink API (`pyroute2`, with the `ip` tool as a
|
||||
fallback). *Rejected alternative, documented why*: running the
|
||||
simulator container itself privileged with host namespaces — it
|
||||
forfeits the non-root deployment and couples host control to the
|
||||
simulator's own lifecycle and restarts.
|
||||
- FR-15.2.8: **Degraded states never break the UI.** Flag set but the
|
||||
agent socket absent/unreachable: the page shows a clear "host
|
||||
control unavailable" banner and mutation routes answer 503 with a
|
||||
message; the Modbus server and the rest of the web UI are
|
||||
unaffected.
|
||||
- FR-15.2.9: **DIP dedicated-IP integration** (FR-11.3.3). When a DIP
|
||||
address change is applied in dedicated-IP mode and the derived
|
||||
interface is whitelisted, the apply step may route through the same
|
||||
agent — the derived IP is added to the host NIC — so the PLC on the
|
||||
bench network must genuinely re-connect to the new node address,
|
||||
exactly like a physical coupler after a DIP change. Under
|
||||
`network_mode: host` the simulator rebinds directly per FR-11.3.3;
|
||||
either way the agent supplies the address on the host.
|
||||
|
||||
### 15.3 Architecture sketch (planned)
|
||||
|
||||
```
|
||||
bench host (Linux)
|
||||
├── wago-sim hostnet-agent --config /etc/wago-sim/hostnet.yaml
|
||||
│ (systemd unit: deploy/wago-sim-hostnet-agent.service;
|
||||
│ root or CAP_NET_ADMIN — it owns the interface whitelist)
|
||||
│ config: socket: /run/wago-sim/hostnet.sock, whitelist: [...]
|
||||
└── docker compose
|
||||
├── mounts /run/wago-sim:/run/wago-sim (agent socket in)
|
||||
└── wago-sim serve (page + /api/hostnet/* routes,
|
||||
gated by FR-15.2.1 flag + FR-15.2.2 docker detection)
|
||||
```
|
||||
|
||||
Web API, mounted only under the FR-15.2.1/2 gates:
|
||||
|
||||
| Method/Route | Purpose | FR |
|
||||
|---|---|---|
|
||||
| `GET /api/hostnet` | availability (flag, docker, agent health) + interface/address list + whitelist | 15.2.3 |
|
||||
| `POST /api/hostnet/interfaces/{name}/addresses` | add an address (address, prefix length) | 15.2.4 |
|
||||
| `DELETE /api/hostnet/interfaces/{name}/addresses/{addr}` | remove an address | 15.2.4 |
|
||||
| `POST /api/hostnet/interfaces/{name}/restore` | undo last / restore snapshot | 15.2.5 |
|
||||
| `GET /api/hostnet/audit` | bounded recent audit lines | 15.2.5 |
|
||||
|
||||
### 15.4 Scoping questions (answer before planning)
|
||||
|
||||
1. Platform scope v1: Linux bench hosts only (agent via `pyroute2`)?
|
||||
Windows hosts run the container inside Docker Desktop/WSL2 — the
|
||||
container's "host" is the WSL2 VM; reaching the Windows NICs needs
|
||||
a Windows-side agent over a named pipe — defer or include?
|
||||
2. Networking-mode story for the DIP integration (FR-15.2.9): keep
|
||||
the current bridge deployment (host IP + mapped port) as v1, or
|
||||
require `network_mode: host` for full parity (node IP == host IP,
|
||||
port 502)?
|
||||
3. Agent authentication: Unix-socket file permissions only, or a
|
||||
shared token in the agent config to defend against other local
|
||||
users?
|
||||
4. IPv6 in v1 or deferred?
|
||||
5. Does link up/down (cable pull) belong in v1 — it can sever the
|
||||
operator's own web UI session on that NIC — or are address
|
||||
add/remove/change sufficient for the planned FAT cases?
|
||||
|
||||
### 15.5 Acceptance criteria (draft)
|
||||
|
||||
1. Without `WAGO_SIM_HOSTNET`: no page; all `/api/hostnet/*` routes
|
||||
answer 404; the rest of the UI unchanged (regression suite green).
|
||||
2. Flag set but not in docker: same as 1.
|
||||
3. Flag set + docker + agent reachable: the page lists the host's real
|
||||
interfaces; adding `192.168.1.33/24` to the whitelisted interface
|
||||
shows in `ip addr` **on the host**, and the new address is
|
||||
reachable from the bench network (a master connects through it).
|
||||
4. Removing that address severs the master's connection through it —
|
||||
the PLC's reconnect logic is exercised (the FAT case).
|
||||
5. Restore/undo returns the interface to its pre-change snapshot; a
|
||||
host reboot likewise restores the deployed addressing (changes are
|
||||
runtime-only, FR-15.2.4).
|
||||
6. An operation on a non-whitelisted interface is refused by the
|
||||
agent and surfaced as an error on the page; the audit log records
|
||||
every mutation and every refusal.
|
||||
7. Read-only mode: page hidden, mutations 403.
|
||||
8. DIP integration: applying switch position 33 in dedicated-IP mode
|
||||
results in `192.168.1.33` present on the whitelisted NIC (bridge
|
||||
mode) or the server rebind (host mode); the "restart required"
|
||||
semantics of FR-11.3.3 are unchanged.
|
||||
9. Agent socket missing: "host control unavailable" banner,
|
||||
mutations 503, Modbus server and the rest of the web UI unaffected.
|
||||
|
||||
---
|
||||
|
||||
## 16. Roadmap (post-framework)
|
||||
|
||||
| Phase | Feature |
|
||||
|---|---|
|
||||
@@ -1603,11 +1784,11 @@ the same process-image core.
|
||||
| 4 | FAT report generator (HTML/PDF), scenario comparison, template library per project type |
|
||||
| 5 | Multi-node orchestration (several couplers in one FAT bench), UDP variant, WBM simulation; **web UI (§10)**; **runtime device configuration (§11)**: module hot-configuration with image rebuild, DIP-switch emulation, WBM-equivalent pages, device-state persistence |
|
||||
| 6 | CI integration: run scenarios headless, export JUnit XML |
|
||||
| ? | **Multi-vendor device profiles (§13)** and **additional fieldbus protocols PROFINET/COMLI (§14)** — not yet scheduled; phase assignment after §13.3/§14.3 scoping |
|
||||
| ? | **Multi-vendor device profiles (§13)**, **additional fieldbus protocols PROFINET/COMLI (§14)**, and **host network settings (§15)** — not yet scheduled; phase assignment after §13.3/§14.3/§15.4 scoping |
|
||||
|
||||
---
|
||||
|
||||
## 16. References
|
||||
## 17. References
|
||||
|
||||
- WAGO 750-362 manual `m07500362_xxxxxxxx_0en.pdf`, sections 7.2–7.3 (process image), 11.2 (Modbus), 12.2 (module data architecture)
|
||||
- WAGO I/O System 750 system description `m075xxxxx_xxxxxxxx_0en.pdf`
|
||||
|
||||
Reference in New Issue
Block a user