Snapcraft top-level metadata

The top-level keys and values in snapcraft.yaml provide the snap build process, and the store, with the overarching details of a snap.

See Snapcraft app metadata and Snapcraft parts metadata for details on how apps and parts are configured within snapcraft.yaml.

Top-level details include a snap’s name, version and description, alongside operational values such as its confinement level and supported architecture.

adopt-info

Type: string (optional)

Incorporate external metadata via the referenced part.

See Using external metadata for more details.

architectures

Type: list[object] (optional)

List of build and run architectures.

For more details, see Architectures.

assumes

Type: list[string] (optional)

A list of features that must be supported by the core in order for this snap to install. For example to make the snap only installable on certain recent version of snapd(like 2.38) you can specify:

assumes:
- snapd2.38

Other potential values for assumes include:

  • common-data-dir: support for common data directory across revisions of a snap
  • snap-env: support for the “Environment:” feature in snap.yaml
  • command-chain: support for the “command-chain” feature for apps and hooks in snap.yaml
  • kernel-assets: support for kernel assets in gadget.yaml, such as to include volume content in the style $kernel:ref

base

Type: string (optional)

A snap of type base to be used as the execution environment for this snap. See Base snaps for further details.

Values:

bare Empty base snap, useful for fully statically linked snaps and testing
core Ubuntu Core 16
core18 Ubuntu Core 18
core20 Ubuntu Core 20
core22 Ubuntu Core 22
core24 Ubuntu Core 24

compression

Type: string (optional)

Sets the compression type for the snap. Can be xz or lzo. Defaults to xz when not specified.

Snaps are compressed using xz data compression by default. This offers the optimal performance to compression ratio for the majority of snaps.

However, there are certain types of snap, such as large desktop applications, that can benefit from using LZO compression. Snaps compressed with lzo are slightly larger but can decompress quicker, reducing the time it takes for freshly installed or refreshed snaps to launch.

To specify lzo compression, set compression: lzo in your snap’s snapcraft.yaml and rebuild your snap, as shown in the following example:

name: test-snapcraft-lzo
base: core18
version: "0.1"
summary: Test LZO snap
description: Test LZO snap
grade: stable
confinement: strict

# this line enables LZO compression for the snap
compression: lzo

parts:
  my-part:
    plugin: nil

apps:
  lzo-things:
    command: bin/something

confinement

Type: enum (optional)

Determines if the snap should be restricted in access or not.

Possible values are strict (for no access outside of declared interfaces through plugs), devmode (for unrestricted access) or classic. For more information, refer to Confinement.

Examples: strict, or devmode

contact

Type: list[string] | string (Introduced: Snapcraft 5.0 optional)

A contact for the snap in the form of a URL or email address.

description

Type: string (mandatory)

Multi-line description of the snap.

A more in-depth look at what your snap does and who may find it most useful.

donation

Type: list[string] | string (Introduced: Snapcraft 5.0 optional)

A link or list of links to receive donations for the snap.

epoch

type: integer (optional)

Controls when users receive a configuration-breaking application release.

Applications and their data formats are constantly evolving, and this requires applications to periodically break data compatibility with older versions. When this happens, applications and users often need to carefully manage data migration from one version to another, and this is where epochs can help. By default, snaps have an epoch of ‘0’. When a new version breaks data compatibility with this old version, incrementing the epoch in the new release stops those old users automatically refreshing to the new version.

See Snap epochs for further details.

grade

Type: enum (optional)

Defines the quality grade of the snap.

Can be either devel (i.e. a development version of the snap, so not to be published to the stable or candidate channels) or stable (i.e. a stable release or release candidate, which can be released to all channels).

A snap of type app (default) cannot be set to stable if the base is not on a stable channel.

Example: [stable or devel]

hooks

Type: list[dict] (optional)

Hooks permit executable files to run within a snap’s confined environment when a certain action occurs.

By default, hooks run with no plugs. If a hook needs more privileges, you can use this top-level hooks attribute:

hooks: # Top-level YAML attribute, parallel to `apps`
  configure: # Hook name, corresponds to executable name
    plugs: [network] # Or any other plugs required by this hook

See Snapcraft hook support for more details.

issues

Type: list[string] | string (Introduced: Snapcraft 5.0 optional)

A link or list of links to report issues for the snap.

icon

Type: string (optional)

Path to icon image that represents the snap in the snapcraft.io store pages and other graphical store fronts.

Note that the desktop menu does not use this icon. It uses the icon in the .desktop file of the application.

It is a relative path to a .png/.svg file from the source tree root. The recommended size is 256x256 pixels. Aspect ratio needs to be 1:1. Image size can vary from 40x40 to 512x512 px and the file size should not be larger than 256 KB.

Examples: _package_name_.svg, or snap/gui/logo.png

layout

Type: list[dict] (optional)

Layouts modify the execution environment of a strictly-confined snap.

With layouts, you can make elements in $SNAP , $SNAP_DATA , $SNAP_COMMON accessible from locations such as /usr , /var and /etc . This helps when using pre-compiled binaries and libraries that expect to find files and directories outside of locations referenced by $SNAP or $SNAP_DATA .

See Snap layouts for more details.

Example:

layout:
  /var/lib/foo:
    bind: $SNAP_DATA/var/lib/foo
  /usr/share/foo:
    bind: $SNAP/usr/share/foo
  /etc/foo.conf:
    bind-file: $SNAP_DATA/etc/foo.conf

license

Type: string (optional)

A license for the snap in the form of an SPDX expression for the license.

In the legacy Snapcraft syntax (not using the base key), this key is only available through the passthrough key.

Currently, only SPDX 2.1 expressions are supported. A list of supported values is also available at snapd/licenses.go at master · snapcore/snapd.

For “or later” and “with exception” license styles refer to the Appendix V of the SPDX Specification 2.1.

Examples: GPL-3.0+, MIT, Proprietary

name

Type: string (mandatory)

The identifying name of the snap.

It must start with an ASCII character and can only contain letters in lower case, numbers, and hyphens, and it can’t start or end with a hyphen. The name must be unique if you want to publish to the Snap Store.

For help on choosing a name and registering it on the Snap Store, see Registering your app name.

Example: my-awesome-app

package-repositories

Type: list[dict] (optional)

Adds package repositories as sources for build-packages and stage-packages, including those hosted on a PPA, the Personal Package Archive, which serves personally hosted non-standard packages.

See Snapcraft package repositories for more details.

Example:

package-repositories:
  - type: apt
    components: [main]
    suites: [xenial]
    key-id: 78E1918602959B9C59103100F1831DDAFC42E99D
    url: http://ppa.launchpad.net/snappy-dev/snapcraft-daily/ubuntu

passthrough

Type: type[object] (optional)

Attributes to passthrough to snap.yaml without validation from snapcraft.

See Using development features in snapcraft for more details.

source-code

Type: list[string] | string (Introduced: Snapcraft 5.0 optional)

A link to the source of the snap (i.e.; the repository containing snapcraft.yaml).

summary

Type: string (mandatory)

Sentence summarising the snap.

Max len. 78 characters, describing the snap in short and simple terms.

Example: The super cat generator

system-usernames

Type: dict (optional)

Common example is snap_daemon: shared to use a daemon user, see system-usernames for more details.

title

Type: string (optional)

The canonical title of the application, displayed in the software centre graphical frontends.

Max length 40 characters.

In the legacy Snapcraft syntax (not using the base key), this key is only available through the passthrough key.

Example: My Awesome Application

type

Type: enum (optional)

The type of snap, implicitly set to app if not set.

For more details, see: gadget, kernel, base.

Example: [app|core|gadget|kernel|base]

version

Type: string (mandatory, unless using adopt-info)

A user facing version to display.

This field is mandatory unless version information is provided by adopt-info . See Using external metadata for details.

Max len. 32 chars. Needs to be wrapped with single-quotes when the value will be interpreted by the YAML parser as non-string.

Examples: '1', '1.2', '1.2.3', git (will be replaced by a git describe based version string)

website

Type: list[string] | string (Introduced: Snapcraft 5.0 optional)

A link to a product website from the publisher of the snap.

Plugs and slots for an entire snap

Plugs and slots for an interface are assigned to apps and daemons on a per-app and per-daemon basis. See Snapcraft app metadata for details. Configuring plugs and slot attributes is done with the top-level plugs and slots keywords.

It is not recommended to define a top level plug or slot to implicitly assign it to all apps or daemons. Instead, the plug or slot should be defined for each app or daemon. If a plug or slot is defined at the top level and does not have any configuration, Snapcraft will warn that the plug or slot should be defined per-app or per-daemon.

plugs

Type: dict (optional)

These plugs apply to all apps and differs from apps.<app-name>.plugs in that the type is in a dict rather than a list format, :(colon) must be postfixed to the interface name and shouldn’t start with - (dash-space).

plugs.<plug-name>

Type: dict (optional)

A set of attributes for a plug.

Example: read attribute for the home interface.

plugs.<plug-name>.<attribute-name>

Type: string (optional)

Value of the attribute. Example: all for read attribute of the home interface.

slots

Type: dict (optional)

A set of slots that the snap provides, applied to all the apps.

slots.<slot-name>

Type: dict (optional)

A set of attributes of the slot.

slots.<slot-name>.<attribute-name>

Type: dict (optional)

Value of the attribute.

1 Like

The separation of description to individual rows confuses me as the horizontal separator line is visible, hinting that the lower description belongs to another key.

Yes, I agree. It’s a bit of a compromise at the moment. The table layout on the final output has fixed equal divisions that makes more than 2 columns illegible (issue here: Table column width · Issue #58 · canonical-web-and-design/docs.snapcraft.io · GitHub).

We did experiment with other layouts (see List and table presentation ideas) and settled on the above as a stop-gap. I’ll try and push the table rendering issue up the priority list so we can do a better job of this and its related tables.

1 Like

What’s the difference between this page and snapcraft-yaml-reference?

Note that this page resolves to https://snapcraft.io/docs/snapcraft-top-level-metadata on the docs site. This page is meant just for defining metadata specifically for a snap - it is a subset of all the keys on the full YAML reference you linked to.

The documentation for base looks quite misleading on the docs:

obraz

Maybe use a table instead?

Good idea - thanks for the suggestion!

As I read it from the schema, the top-level “hooks” property can define four attributes: command-chain, environment, plugs and passthrough, yet only plugs is mentioned here, and if you follow links, there still doesn’t seem to be much discussion of those other hooks attributes, so we can start with one question: Unless you need to define one of those hooks attributes for a hook, is there any reason to have a top-level hooks entry at all? Or is it sufficient to just populate the snap/hooks/ directory?

Some compelling use cases would be handy to explain all of those attributes.

Regarding the “assumes:” meta-data entry, first, it omits “kernel-assets”. Also, while it supports values of “common-data-dir” and “snap-env”, it’s hard to understand what exactly those two things accomplish. I’m looking for the underlying code that implements those two things, and I don’t see it. Regarding “common-data-dir”, does that not just refer to the common data directory $SNAP_COMMON? You don’t actually have to ask for that feature, do you? Don’t you get it automatically?

1 Like

Since each snap supports a common data directory by default ($SNAP_COMMON), what is the value of “common-data-dir” as part of “assumes”? Can you turn it off?

This document is implicitly encouraging what I see as an antipattern. Specifically with the plugs and slots definitions we are saying that it is ok to do this:

plugs:
  desktop:
  desktop-legacy:

This is incorrect in my opinion and should be discouraged. The top-level plugs and slots should only be used to alter the default behaviour of the plug or slot, or to define a new plug or slot against an interface (such as using the content interface). It should not be used to apply “global plugs and slots configuration for an entire snap”, but only to customise their default behaviours via setting the options that an interface exposes.

I have seen several snaps and snap authors using this anti pattern now.

For the avoidance of doubt, IMO, plugs and slots should always be specified on the apps entry!

@sergiusens can we set the schema to explicitly disallow an empty dict here, please, to prevent this from being abused?

2 Likes

@pedronis do you think we risk breaking anything by adding this restriction in Snapcraft (or snapd’s pack)?

We would need to check with the store but I suspect there are quite a few snaps that do this, so at most we would have to start with a warning. Or do something in the store for new uploads but not really in snapd itself. It’s also not unreasonable in some contexts but yes it’s prone to result in excessive permissions.

A warning sounds like a good idea

I’m still interested in whether the allegedly possible assumes: values of “snap-env” or “common-data-dir” have any value. Or for that matter even “command-chain” since that seems to be the default.

assumes are not about turning things on or off, they are about failing early when installing on a snapd that does not support the feature, some old snapds didn’t support the corresponding features. Snapcraft itself adds some of these automatically I think, for example command-chain.

Hi, sorry for necro’ing this discussion! I’m working on adding a warning for this issue (as blocking it altogether would be too disruptive now) and I’m wondering if, as the original reporter, you have a suggestion on a concise message that we can use to explain to users why this behavior is discouraged. Something that summarizes the (very good) argument you made here.

How about something like:

Implicit [plug|slot] assignment. [Plugs|Slots] should be assigned to the app that they apply, and not implicitly assigned via the global [plugs:|slots:] stanza which is intended for configuration only.

Looks pretty good to me, many thanks!

1 Like

As a result of the recent consolidation of the schema docs, this page now redirects to https://snapcraft.io/docs/snapcraft-yaml-schema.

For further discussion about this topic, please use the YAML schema’s thread. Thanks!

2 Likes