# Dedicated, THROWAWAY MTConnect Agent for the #846/#852 refused-connection live gate. # # Adds two services to the docker-dev rig's own network so a driver deployed on # central-1/central-2 can reach an Agent that the gate is free to stop and start — # never the shared fixture on 10.100.0.35, which other work relies on. It reuses the # integration fixture's agent.cfg / Devices.xml / adapter.py (read-only binds), so # the device model is the familiar `OtFixtureCnc` one (fixture_x_pos, fixture_execution, # the fixture_x_travel / fixture_logic CONDITIONs...). # # WHY THE AGENT SHARES THE ADAPTER'S NETWORK NAMESPACE (the whole point of this file): # the fast path fires ONLY on SocketError.ConnectionRefused. Stopping an ordinary # compose container also drops its name from Docker's embedded DNS, so the driver # would see a DNS failure (HostNotFound) instead — an AMBIGUOUS failure that, by # design, waits for the ~90 s watchdog, and the gate would "fail" for the wrong # reason. Here the name the driver dials (`mtconnect-gate`) belongs to the ADAPTER # container, which keeps running; the Agent joins its namespace # (network_mode: service:...), so stopping the Agent leaves the name resolving to an # IP with nothing on :5000 — the kernel answers RST, i.e. a genuine refusal. # (Stopping BOTH services is the ambiguous control leg: DNS failure, watchdog only.) # # up: docker compose -p otopcua-dev -f docker-dev/docker-compose.yml \ # -f docker-dev/docker-compose.mtconnect-gate.yml up -d mtconnect-gate mtconnect-gate-agent # refuse: docker compose -p otopcua-dev -f docker-dev/docker-compose.yml \ # -f docker-dev/docker-compose.mtconnect-gate.yml stop mtconnect-gate-agent # recover: ... start mtconnect-gate-agent # remove: ... rm -sf mtconnect-gate-agent mtconnect-gate # # Driver AgentUri (from inside the rig) -> http://mtconnect-gate:5000 # From the Mac (curl /probe) -> http://127.0.0.1:5155 (macOS squats :5000 — AirPlay) # # Starting only these two services touches nothing else in the rig (no depends_on # either way). Recipe: docs/drivers/MTConnect.md §"Live gate: refused-connection fast path". services: # Network-namespace owner + SHDR data source. Must be started first and must stay # up for the whole gate; restarting it orphans the Agent's namespace (then restart both). mtconnect-gate: image: python:3.13-alpine restart: "no" labels: project: lmxopcua purpose: mtconnect-refused-connection-gate volumes: - ../tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.IntegrationTests/Docker/adapter.py:/fixtures/adapter.py:ro command: ["python", "-u", "/fixtures/adapter.py", "--host", "0.0.0.0", "--port", "7878"] networks: default: # agent.cfg dials its adapter as `adapter`; inside the shared namespace that resolves here. aliases: [adapter] ports: # Published on the namespace OWNER — the Agent cannot publish ports of its own in this mode. - "5155:5000" mtconnect-gate-agent: image: mtconnect/agent:2.7.0.12 restart: "no" labels: project: lmxopcua purpose: mtconnect-refused-connection-gate network_mode: "service:mtconnect-gate" depends_on: mtconnect-gate: condition: service_started volumes: - ../tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.IntegrationTests/Docker/agent.cfg:/mtconnect/config/agent.cfg:ro - ../tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.IntegrationTests/Docker/Devices.xml:/mtconnect/config/Devices.xml:ro