🚧 Implement service stub
This commit is contained in:
@@ -11,9 +11,10 @@ and flapping quality — as structured events (JSONL logs, Windows Event Log, op
|
||||
HTTP webhook).
|
||||
|
||||
> **Status:** in active development — discovery, browsing (`list-items`), one-shot
|
||||
> reads (`read`/`probe`) and the exe build are **live and field-verified** against a
|
||||
> real server; the continuous monitoring loop, reporters and Windows service host are
|
||||
> next. See the [TODO](TODO.md) for current status and the
|
||||
> reads (`read`/`probe`), the continuous monitoring loop (`run`), all reporters,
|
||||
> the exe build and the Windows service host are **live and field-verified**
|
||||
> (service: in-process debug host verified; the elevated SCM pass is the remaining
|
||||
> live check). See the [TODO](TODO.md) for current status and the
|
||||
> [implementation plan](docs/IMPLEMENTATION_PLAN.md) for the phases; read the
|
||||
> [specification](docs/SPECIFICATION.md) for detection rules and behavior.
|
||||
|
||||
@@ -32,9 +33,9 @@ answers the triage question *where is the problem?* with evidence:
|
||||
|
||||
See the full interpretation matrix in the [specification](docs/SPECIFICATION.md).
|
||||
|
||||
## Planned features
|
||||
## Features
|
||||
|
||||
- Windows service (auto-start, SCM crash recovery) with a foreground `run` mode for testing
|
||||
- Windows service (auto-start, SCM crash recovery) with a foreground `run` mode for testing — live
|
||||
- Local or remote (DCOM) connections to any OPC DA server
|
||||
- Server browsing: `list-servers` (discovery) and `list-items`
|
||||
(address-space browse: full tree / branches / tags) — live now
|
||||
@@ -83,8 +84,16 @@ opcda-diagnozer probe
|
||||
# foreground run (console) — continuous monitoring; Ctrl+C stops
|
||||
opcda-diagnozer run
|
||||
|
||||
# install as Windows service (dedicated account required for DCOM auth)
|
||||
opcda-diagnozer install --account DOMAIN\svc-opcdiag
|
||||
# install as a Windows service (auto-start + SCM crash recovery; admin shell)
|
||||
# LocalSystem default; a dedicated account is required for remote DCOM auth
|
||||
opcda-diagnozer install
|
||||
opcda-diagnozer install --account DOMAIN\svc-opcdiag --password ****
|
||||
|
||||
# service lifecycle + state
|
||||
opcda-diagnozer start
|
||||
opcda-diagnozer stop
|
||||
opcda-diagnozer status
|
||||
opcda-diagnozer uninstall
|
||||
```
|
||||
`list-servers` uses two discovery mechanisms (`--source`): the OPC DA Automation
|
||||
Wrapper's `GetOPCServers` over COM (works remotely via DCOM; needs Launch+Activation
|
||||
@@ -117,6 +126,48 @@ exist (and `probe`/`read` read the config's tag list unless tags are passed).
|
||||
a non-GOOD or failing tag makes the exit code non-zero, so it doubles as a
|
||||
scriptable health check. `--source cache` reads the server cache instead of
|
||||
forcing a device round-trip.
|
||||
|
||||
## Windows service
|
||||
|
||||
The monitor runs unattended as a **Windows service** (auto-start, SCM crash
|
||||
recovery) — `opcda-diagnozer install` registers the exe itself as the service
|
||||
binary (no `pythonservice.exe`, no Python install on the diag host):
|
||||
|
||||
- **Auto-start** at boot and **restart on failure**: the SCM restarts the
|
||||
service process 5 s after the first and second failure (the failure counter
|
||||
resets after 24 h of clean running) — `sc qfailure OPCDA-Diagnozer` shows it.
|
||||
- **Config path** is recorded at install time (`install --config ...`); the
|
||||
service never depends on its working directory (the SCM starts services
|
||||
with CWD = System32). The default is `config.yaml` next to the exe.
|
||||
- **Clean stop**: a stop request parks the service in `STOP_PENDING` and
|
||||
gives the poll loop 30 s to finish; a COM poll stuck in a dead RPC longer
|
||||
than that is abandoned (the thread is never joined — spec §10.4).
|
||||
- **Event Log** records service start/stop and every configured reporter
|
||||
event; `install` also registers the event source so messages render
|
||||
correctly (needs the admin shell anyway).
|
||||
- **Status** works without admin: `opcda-diagnozer status` prints the SCM
|
||||
state (`STOPPED` / `RUNNING` / …).
|
||||
|
||||
Service **account** (spec §11): `LocalSystem` (the default) works for OPC
|
||||
DA servers on the same machine. Remote DCOM connections need a **dedicated
|
||||
domain account** that has Launch+Activation and Access permissions on the
|
||||
OPC server host (`dcomcnfg` — see the checklist above) and can authenticate
|
||||
across the network; install with `--account DOMAIN\USER --password ****`
|
||||
(the password is only used once, to register the account with the SCM).
|
||||
|
||||
**Deployment layout** (frozen exe):
|
||||
|
||||
```
|
||||
C:\Program Files\OPCDA-Diagnozer\
|
||||
opcda-diagnozer.exe # the console exe: every CLI verb AND the service host
|
||||
config.yaml # the deployed config (install records its path)
|
||||
C:\ProgramData\OPCDA-Diagnozer\
|
||||
logs\ # events.jsonl + anomalies-YYYYMMDD.log (report.dir)
|
||||
```
|
||||
|
||||
Log directories are created on demand; `%ProgramData%` is the default because
|
||||
the service account must be able to write the evidence logs.
|
||||
|
||||
### Configuration example (`config.example.yaml`)
|
||||
|
||||
```yaml
|
||||
@@ -253,7 +304,7 @@ The script refuses to run from a 64-bit interpreter (the exe must load the
|
||||
32-bit OPC DA wrapper DLLs, SPECIFICATION §11), re-verifies the produced PE
|
||||
really is 32-bit, embeds the project version in the exe properties, declares
|
||||
the hidden imports the code loads lazily (pywin32 COM, browse modules, the
|
||||
Phase 3 service host), and smoke-tests the artifact (`--version`,
|
||||
service host + its SCM modules), and smoke-tests the artifact (`--version`,
|
||||
`check-config`, `list-servers --source registry`) after building. It also
|
||||
installs PyInstaller into the venv automatically if it is missing.
|
||||
|
||||
@@ -266,10 +317,11 @@ Deployment notes:
|
||||
`CWD = C:\Windows\System32`, so the relative default would silently point
|
||||
there; the exe-dir default keeps the deployment layout simple
|
||||
(`C:\Program Files\OPCDA-Diagnozer\{opcda-diagnozer.exe, config.yaml}`).
|
||||
- The exe is a console application that hosts every CLI verb, including the
|
||||
future `run` / `probe` / service verbs. The Phase 3 Windows service
|
||||
(`install` verb) will point `sc.exe` at this same exe with the service-host
|
||||
entry point.
|
||||
- The exe is a console application that hosts every CLI verb **and the
|
||||
Windows service**: `install` registers this same exe with the SCM, and
|
||||
when the SCM starts it the process recognizes the fixed service-start
|
||||
argv shape (`exe service`, CWD = System32) and dispatches to the service
|
||||
host. No `pythonservice.exe`, no Python install on the diag host.
|
||||
- The Automation Wrapper DLL (`OPCAutomation.dll`) is **not** bundled — it is
|
||||
a machine-installed COM component (registered in the registry), exactly like
|
||||
the OPC DA servers the tool connects to. Only Python code and its
|
||||
|
||||
Reference in New Issue
Block a user