Skip to content

feat: support thin-edge.io service commands for containers - #245

Merged
reubenmiller merged 1 commit into
mainfrom
feat/service-plugin-actions
Nov 4, 2026
Merged

reubenmiller merged 1 commit into
mainfrom
feat/service-plugin-actions

Conversation

@reubenmiller

Copy link
Copy Markdown
Collaborator

Summary

Adds support for the thin-edge.io service commands. Container and container-group services can now be started, stopped and restarted from the Commands tab of the service in Cumulocity, using the workflow that tedge-agent ships.

This requires thin-edge.io > 2.0.1, which is currently only the main channel. Older versions behave exactly as before.

Changes

  • Service plugins: tedge-container service-plugins container|container-group <action> <name>, which implements the Service Plugin API.
    • Installed as /usr/share/tedge/service-plugins/{container,container-group}, root:root, mode 0755.
    • Actions: start, stop, restart, pause, unpause.
    • Exit codes: 2 for an unsupported action, 1 for a failure, with the reason on stderr.
    • Arguments are never parsed as flags.
  • Action declaration: the daemon publishes retained te/<service>/cmd/<action> capabilities for start, stop and restart on each container service.
    • Published once per process, only after the service registered successfully, and again after a re-registration.
    • Controlled by a new [service_commands] section: enabled = "auto" | true | false, and actions. In "auto", actions are declared only when tedge config get service.plugin_paths succeeds and the plugin is installed.
    • pause and unpause are not declared, as tedge-agent ships no workflow for them. The README shows how to add the workflow and declare them manually.
  • Self-protection: no actions are declared on the container that hosts thin-edge.io (e.g. tedge-container-bundle). The plugins also refuse to act on it, because stopping it would disconnect the device and restarting it would interrupt the running workflow.
  • Container-group lookup: the new LookupGroupService matches the exact compose project and service labels, and includes stopped containers. The previous lookup used a container-name substring match and only covered running containers.
    • The container-group log plugin uses it too, so it now finds the logs of stopped containers.
    • The service plugins reject a compose service scaled to more than one container.
  • Docs: a README section on service commands. The design, specs and tasks are in the archived OpenSpec change openspec/changes/archive/2026-10-20-add-service-plugin-actions/.

Testing

  • Unit tests for the plugin dispatch and exit codes, plugin path parsing, action filtering, the declaration bookkeeping (declare once, re-declare after deregistration, retry after a failed publish, skip the hosting container), and invalid container-group names. go test ./..., go vet and golangci-lint all pass.
  • New system test suite tests/service-commands.robot. Its tests are skipped when the device's thin-edge.io lacks service plugin support (<= 2.0.1).
    • Ran locally against debian-14-docker-28 (tedge 2.0.2~425) with a Cumulocity tenant. All 6 tests passed, though not all in one run. In the final full run, the container-group test failed during its nginx install because the local Docker VM was out of memory and the kernel killed tedge-agent. That happened before any service command ran, and the test passed when rerun.
    • Coverage: c8y_SupportedServiceCommands; RESTART/STOP/START via c8y_ServiceCommand for a container and for a container-group service; plugin exit codes; pause/unpause via tedge service; capabilities cleared when a container is removed; enabled=false.
  • goreleaser snapshot build: confirmed the plugin files and their modes in the deb, rpm and apk packages.

Known limitations

  • The test devices run their own container engine (docker-in-docker), so the protection of the hosting container is only covered by unit tests.
  • Detecting the hosting container reuses Self(), which can match the wrong container when containers use network_mode: host.
  • Whether podman treats starting a running container, or stopping a stopped one, as success has not been checked yet. The podman matrix jobs will show it.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Robot Results

✅ Passed ❌ Failed ⏭️ Skipped Total Pass % ⏱️ Duration
62 0 0 62 100 22m4.539568s

Add the container and container-group service plugins
(https://thin-edge.github.io/thin-edge.io/next/references/service-plugin-api/)
so that containers can be started, stopped and restarted via the
Cumulocity service commands, using the service command workflow shipped
by tedge-agent.

* tedge-container service-plugins container|container-group <action> <name>,
  installed as /usr/share/tedge/service-plugins/{container,container-group}
  (root:root, 0755). Supports start, stop, restart, pause and unpause, and
  exits 2 for unsupported actions
* the daemon declares the start, stop and restart actions (cmd/<action>)
  on each registered container service, once per process, only when
  thin-edge.io supports service plugins (service_commands.enabled = "auto")
* no actions are declared on (and the plugins refuse to act on) the
  container hosting thin-edge.io
* container-group services are looked up by their exact compose
  project/service labels, including stopped containers (also used by the
  container-group log plugin)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@reubenmiller
reubenmiller added this pull request to the merge queue Nov 4, 2026
Merged via the queue into main with commit e734006 Nov 4, 2026
17 checks passed

This branch was previously deployed

1 inactive deployment
Test Auto — 8e7c4109 Deployed Nov 4, 2026 by reubenmiller via Test debian-13-docker-26 #635
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