Snap run --explain

We plan to support an --explain option to the snap run command, which should print while invoking the snap application information about setting up of its container aspects (sandboxing, namespaces) and its runtime environment. This option has the purpose of helping both understanding the mechanics and mechanism of snap invocation as well as in some cases aiding debugging.

Things that could be considered for printing:

  • Flags: classic, devmode…
  • Base/rootfs
    • Core16 vs core “rename” aka “fallback”
  • Mount namespace/layouts, snap-update-ns+snap-confine
    • High level + low level (filtered?) sequence of operations
  • Apparmor profile
    • “name/path of the profile(s) we switch to”
  • Seccomp
    • Profiles we attach
  • Cgroups
    • Cgroup setup we perform
  • Environment
  • Command chain
    • Running chain element A, B, C

This is a first sketch of the expected output (mainly @zyga-snapd’s work):

$ snap run --explain hello
The format of the output is not stable and is not suitable for parsing.

[snap run]

Invoked as /snap/bin/hello
Inferred application details:
   snap name: hello
   app name: hello
   confinement: strict
   base: core16 (using core instead)
Will exec through the following tools:
 - snap-confine (execution environment and sandboxing)
 - snap-exec (command chain and environment)


Sandbox overview:
 - apparmor profile: snap.hello.hello
   source: /var/lib/snapd/apparmor/profiles/snap.hello.hello
   binary: (loaded into the kernel, cached by platform)
   takes effect after next exec(2) call
 - applied seccomp profile: snap.hello.hello
   source: /var/lib/snapd/seccomp/bpf/snap.hello.hello.src
   binary: /var/lib/snapd/seccomp/bpf/snap.hello.hello.bin
 - applied seccomp profile: global profile for all snaps
   binary: /var/lib/snapd/seccomp/bpf/global.bin
 - device cgroup: snap.hello.hello
   path: /sys/fs/cgroup/devices/snap.hello.hello
   mode: permissive (all devices allowed)
 - freezer cgroup: snap.hello
   path: /sys/fs/cgroup/freezer/snap.hello
 - selinux context: unconfined_t

Execution environment:
 - Root file system is /snap/core/234/
 - Base snap has changed revision to 234, starting from scratach
 - Using private /tmp directory
   stored in /tmp/snap_hello.../
 - Reused mount namespace from /run/snapd/ns/hello.mnt
   desired fstab: /var/lib/snapd/mount/snap.hello.fstab
   effective fstab: /run/snapd/ns/snap.hello.fstab
   info file: /run/snapd/ns/
 - Setting PATH to …
- Changing to directory ...

setting environment:
 - SNAP_NAME=hello
 - ...
running command chain:
 - /snap/hello/current/command-chain/snapcraft-runner
 - /snap/hello/current/bin/hello


I’ve implemented a version of this in

There are many TODOs and more could be added, as the initial design did not explore interesting avenues in the code (e.g. hooks and timers). Some things are hard to structure the way we wanted inside the flow of snap-confine but virtually all of the output is there now.