Classic Confinement: Telemetry CLI

  • name: telemetry
  • description: Telemetry CLI is a command-line interface for managing devices, connectors, and MQTT topic rules in Canonical Telemetry. It authenticates a user and proxies management operations to the Telemetry Management Service HTTP API.
  • snapcraft: https://github.com/canonical/telemetry-cli/blob/main/snap/snapcraft.yaml
  • upstream: https://github.com/canonical/telemetry-cli
  • upstream-relation: The snap is built and published by Canonical Telemetry, which is also the upstream author and maintainer of the project.
  • supported-category: Criteria item “running arbitrary command (esp if user-configurable such as a developer tool)”. The CLI must launch the user’s own, runtime-configured $EDITOR/$VISUAL — the same mechanism used by git commit, kubectl edit
  • reasoning:

The telemetry CLI has an update-connector subcommand that lets a user edit a connector’s configuration interactively. It behaves exactly like git commit or kubectl edit: the CLI serialises the current configuration to a temporary file, launches the editor the user has configured, and reads the result back after the editor exits.

The editor is whatever the user sets via $EDITOR / $VISUAL (vim, nano, emacs, code --wait, etc.). That binary:

  • is not known at build time, so it cannot be bundled;
  • lives at an arbitrary path on the host (/usr/bin, /snap/bin, ~/.local/bin, …), discovered at runtime through $PATH;
  • must be executed with the host’s own libraries and configuration.

Under strict confinement this is not achievable with the existing interfaces.

Why this does not raise a security concern:

The CLI is a stateless management client with no elevated privileges and no long-running service.

This request has been added to the queue for review by the @reviewers team.

This is exactly why we ship the xdg-open command (as a special snap agnostic wrapper) inside all the base snaps… If you run this from inside your snap like: xdg-open /path/to/file It will automatically open your default editor (or show a dialog if you have multiple to pick from) if the file is a text file… (your snap will need to have the desktop plug set to allow xdg-open to call out to dbus)

Thanks for the pointer! Unfortunately xdg-open doesn’t work for this command.

I switched the snap back to strict confinement and added the desktop plug:

apps:
  telemetry:
    command: bin/telemetry
    plugs:
      - network   # reach the management API
      - home      # read/write the temp config file
      - desktop   # allow xdg-open to call out via D-Bus

and changed the update-connector code to call xdg-open <file> directly (instead of $EDITOR), which is the flow you described. update-connector writes the connector config to a temp JSON file, opens it, waits for the editor to exit, then reads the file back and PATCHes the API.

Portal declines the file (desktop session, plug connected)

On a normal Ubuntu desktop with the desktop interface connected:

$ telemetry update-connector <id>
user-open error: request declined by the user (code 2)
editor failed: exit status 1

Under strict confinement xdg-open isn’t the host binary but it’s snapd’s shim. For our JSON temp file that request is gated by the portal and gets declined (code 2), so the editor never opens.

Even if the portal allowed it, it still wouldn’t work

Two more issues make xdg-open unsuitable for this command, independent of the portal decision:

1. It opens the desktop MIME handler, not the terminal $EDITOR:

$ xdg-mime query default application/json
firefox_firefox.desktop

Loading a connector config into a browser doesn’t let the user edit and save it back.

2. It’s fire-and-forget. update-connector must block until the editor exits, then read the modified file back. xdg-open returns as soon as the handler is launched and gives no completion signal, so the CLI reads the file back before the user has finished editing.

So xdg-open can’t back the synchronous, terminal-$EDITOR, edit-then-read workflow that this command needs. We are separately adding a non-interactive --file/stdin mode that works fine under strict confinement for automation. But the interactive editor flow specifically requires executing the user’s configured $EDITOR on the host, which is what the classic request is for.

Ah, this is sad, I did indeed test it before suggesting but was not aware you are using json and need it blocking …

One thing to point out though is that with classic confinement your snap will not be installable on any IoT/Industrial devices using UbuntuCore as core does not allow installation of classic snaps at all … (it might make sense to have two variants in two different tracks (classic/strict) if you want to provide telemetry for UbuntuCore devices as well)

Hi @bjgiraudon,

The snap does not fall into any of the supported category as per Process for reviewing classic confinement snaps and that is a hard requirement. Also the functionality that you are trying to achieve with classic is dependent on the software only available on host, which comes under unsupported category.

That is why I am unable to grant classic for this request.

I would suggest you to stage some of the sensible defaults like vim and nano in the snap and ask users to choose one from the available options.