Skip to content

feat(service): cmd.service takes a status action - #6

Merged
skeeeon merged 1 commit into
mainfrom
feat/service-status
Sep 24, 2026
Merged

skeeeon merged 1 commit into
mainfrom
feat/service-status

Conversation

@skeeeon

@skeeeon skeeeon commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

cmd.service gains a status action, so you can read one service's state on demand. Before, the only way to see it was to wait for the next service_check telemetry.

nats request "agents.server-01.cmd.service" '{"action":"status","service_name":"nginx"}'
{"status":"success","service_name":"nginx","action":"status",
 "result":"Service nginx is Running","service_status":"Running","ts":"..."}

Design

  • One lookup. QueryService calls GetServiceStatuses, the function the service_check telemetry already uses on every platform. The command and the telemetry can't describe the same service differently, and there's no new per-platform code.
  • One gate. The service must be in allowed_services, the same as start, stop and restart.
  • Same words as telemetry. service_status uses the telemetry's values: Running, Stopped, Starting, Stopping, Error, Unknown or NotInstalled.
  • Missing services aren't errors. A service that doesn't exist answers NotInstalled, as it does in telemetry.
  • Control replies are unchanged. service_status is absent for start, stop and restart, and the reply is otherwise the same shape as before.

Testing

  • Every platform: an unlisted service is refused before anything asks the service manager.
  • Linux, against the real systemd: systemd-journald reports Running, and a made-up service reports NotInstalled. The test skips on machines without systemd.
  • Full suite:
    • go test -race ./... passes
    • go vet is clean on Linux, Windows, FreeBSD and darwin
    • all four release targets build
    • golangci-lint shows nothing new
  • Not covered: the handler's routing branch (about ten lines). Its reply can't be captured without a live NATS connection, so only the executor side is tested.

Known limit

On Windows, status connects to the service manager the same way the telemetry does. That works when the agent runs as a service. From a non-admin shell it answers "Access is denied", just as the telemetry would.

Also

Fixes the example reply in docs/architecture.md's service diagram. It showed an output field that cmd.service has never sent; the field is result.

🤖 Generated with Claude Code

Reading one service's state meant waiting for the next service_check
telemetry. `{"action":"status","service_name":"nginx"}` now answers on
demand, with `service_status` in the telemetry's words (Running,
Stopped, NotInstalled, ...) beside the usual human-readable `result`.

QueryService goes through GetServiceStatuses, the call the telemetry
already makes on every platform, so the command and the telemetry
cannot describe a service differently and no platform code is new. It
uses the same allowed_services gate as start, stop and restart. A
service that does not exist answers NotInstalled, as in telemetry.

Also corrects the architecture doc's example reply, which showed an
`output` field cmd.service has never sent.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@skeeeon
skeeeon merged commit 3b69fe0 into main Sep 24, 2026
1 check passed
@skeeeon
skeeeon deleted the feat/service-status branch September 24, 2026 04:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant