The snap format


#1

A snap is a squashfs file carrying content and a bit of metadata that tells the system how to manipulate it. When installed the squashfs file is mounted read-only under

  • /snap/<snap name>/<revision>/

This means fast and extremely predictable installations, with no leftovers and no way for the content to be mutated over traditional means. Either it’s all installed and available as originally built, or it is not available at all.

Applications declared in the snap become commands at

  • /snap/bin/<snap name>[.<app name>]

The suffix is omitted if <app name> matches <snap name>. That file is not the actual application, though, but rather a command that will trigger the real application to be run under the proper isolation and confinement rules, based on the default restricted environment plus any allowances granted to it via the interface system.

Setup files

The following files control the behavior of a snap:

  • meta/snap.yaml - Basic snap details (see below).
  • meta/hooks/ - Hooks called on specific events (see below).
  • meta/gui/icon.svg - Icon for the snap.
  • meta/gui/*.desktop - Desktop files for the snap (see below).

snap.yaml

Every snap package contains a meta/snap.yaml file that holds the basic metadata for the snap.

Please take note of this important distinction:

  • snap.yaml - Lives inside every snap package, read by snapd.
  • snapcraft.yaml - Instructions to create a snap package, read by snapcraft.

Most of the content supported in snap.yaml is optional. In fact, the simplest snap possible may have as little as this inside snap.yaml:

name: simplest
version: 1.0

A snap that offers an application to run is still very simple:

name: simple
version: 1.0
apps:
    hello:
        command: bin/hello --world

The following specification defines what is supported inside it:

# The suggested snap name, constrained to the [a-z0-9] charset and inner
# dashes. The final name when the snap is installed is defined by the
# snap-declaration assertion associated with the snap, if any.
name: <name>

# An optional title for the snap, may contain uppercase letters and spaces.
title: <title>

# Version of the software packed inside the snap. Has no semantic value
# in the system (no greater/lower-than rules are ever applied to it).
version: <version>

# More details about what is contained in the snap.
summary: <line>
description: <text>

# License for the snap content, based on SPDX license expressions.
license: <expression>

# Type of snap, defaults to "app".
type: app | core | gadget | kernel | base

# List of architectures the snap may run on. Defaults to [all].
architectures:
    - all | amd64 | i386 | armhf | ...

# The base snap that defines the underlying filesystem this snap
# will be assembled on top of.
base: <name>

# List of applications (commands, binaries, daemons) in the snap. 
apps:

  <app name>:

      # Path to executable (relative to snap base) and arguments to use
      # when this application is run.
      command: <command line>

      # Path to a bash snippet to use for tab completion.
      # (snapcraft 2.33+, snapd 2.30+)
      # See https://forum.snapcraft.io/t/2261
      completer: <path to file>

      # List of plug names this application is associated with.
      # When a plug is connected to one of these slots, this application
      # will be granted the permissions specified for that interface.
      # If attributes are required or the plug name does not match the
      # interface name, more details must be declared under the top-level
      # "plugs" field (see below).
      plugs:
          - <plug name>

      # List of slot names this application is associated with.
      # Same details as described above, but for slots.
      slots:
          - <slot name>

      # If daemon is set, the command is a daemon to run as specified.
      # See systemd documentation for details on those kinds.
      daemon: simple | forking | oneshot | notify

      # Optional command to use for stopping a daemon.
      stop-command: <command line>

      # Optional time to wait for daemon to stop.
      stop-timeout: <n>ns | <n>us | <n>ms | <n>s | <n>m

      # Optional command to run after daemon stops.
      post-stop-command: <command line>

      # Condition to restart the daemon under. Defaults to on-failure.
      # See the systemd.service manual on Restart for details.
      restart-condition: \
          on-failure | on-success | on-abnormal | on-abort | always | never

      # Service watchdog timeout. For watchdog to work, the application requires
      # access to systemd notification socket, which can be declared by listing a 
      # daemon-notify plug in the plugs section. Note, the interface is not auto connected
      # and needs to be connected manually.
      # (snapd 2.33+)
      watchdog-timeout: <n>ns | <n>us | <n>ms | <n>s | <n>m

      # Command to use to ask the service to reload its configuration.
      # In the absence of this, when asked to reload  (e.g. via
      # `snap restart --reload snap.app`) the service is restarted instead.
      reload-command: <command line>

      # List of applications that are ordered to be started before the current one.
      # Applications must be part of the same snap.
      # (snapd 2.31+)
      after:
          - <other app name>

      # List of applications that are ordered to be started after the current one.
      # Applications must be part of the same snap.
      # (snapd 2.31+)
      before:
          - <other app name>

      # Name of the desktop file placed by the application in 
      # $SNAP_USER_DATA/.config/autostart to indicate that application 
      # should be started when user desktop session starts up
      # (snapd 2.32.4+)
      autostart: <command line>

Hooks

Hooks provide a mechanism for snapd to alert snaps that something has happened, or to ask the snap to provide its opinion about an operation that is in progress. See the topic on supported hooks for more details.

Interfaces

Interfaces allow snaps to communicate or share resources according to the protocol established by the interface and play an important part in security policy configuration.

Desktop files

The meta/gui/ directory (snap/gui/ with snapcraft) may contain *.desktop files for the snap. Those desktop files may contain all valid desktop entries from the XDG Desktop Entry Specification version 1.1 with some exceptions listed below. Lines with unknown keys are silently removed from the desktop file on install.

The Exec= line must necessarily look like the following to be valid:

  • Exec=<snap name>[.<app name>] [<argument> ...]

As in the executables contained under /snap/bin, the .<app name> suffix is omitted if the application name and snap name are the same.

For example, assuming this content in snap.yaml:

name: http
version: 1.0
apps:
    get:
        command: bin/my-downloader

This desktop file is valid:

[Desktop Entry]
Name=My Downloader
Exec=http.get %U

Unsupported desktop keys

The DBusActivatable, TryExec and Implements keys are currently not supported and will be silently removed from the desktop file on install.


The gadget snap
Documentation outline
Security policy and sandboxing
Best practice for logging
#2

Content moved out of the wiki.


#3

The link disagrees directly with that statement - where is one meant to look now?


#4

Right here. The statement says the content was taken from the wiki and moved here.


#5

‘title’ should be added to the “more details” section, i.e.

# More details about what is contained in the snap.
title: <line>
summary: <line>
description: <text>

#6

‘license’ is a new field (see Snap license metadata)

proposed:

# Software license snap is provided under
license: <SPDX expression>

#7

Should this section make some brief mention of aliases?