The system-files interface

The system-files interface enables a snap to access specific system files and directories (such as files in /etc). Consequently, the interface can provide access to privileged system data and is not connected by default.

This interface is typically used to provide read-only access to system configuration directories created by a non-snap version of an application now running from an equivalent snap.

Example

The Firefox, Chromium and Thunderbird snaps use this interface to enable access to system-installed policies to customise each respective application.

Interface documentation:

See Interface management and Supported interfaces for further details on how interfaces are used.


Developer details

Auto-connect: no
Super-privileged: yes
Transitional: no
Attributes:

  • read (plug): list of files and/or directories for read-only access (eg, ‘read: [ /etc/file-read, /etc/dir-read ]
  • write (plug): list of files and/or directories for read/write access (eg, ‘write: [ /etc/file-write, /etc/dir-write ]

Requires snapd version 2.37+.

Consumers of this interface require a snap declaration for distribution via the Snap Store and acceptance in the store requires that the interface is not be used to access:

  • system files where the snap is not the clear owner (eg, /dev, /proc, /sys, /usr, etc).
  • paths in /dev, such as /dev/sda1 Access to /dev device nodes requires both AppArmor policy and device control group inclusion, but the system-files interface does not have enough information to generate the necessary policy to enable these use cases. As such, purpose-specific interfaces should be used instead, such as block-devices or raw-volume.
Caution:

Do not share data between snaps. While system-files can be used to share data with another snap, such as within a configuration file, this behaviour is not recommended. The content interface should be used instead.

An additional requirement for acceptance in the Global store is using a descriptive interface reference for use with snap connections|interfaces|connect|disconnect.

For example, the ‘foo’ application is packaged as a snap and the snap publisher wants to import existing configuration from /etc/foo into the snap. The snapcraft.yaml might be:

name: foo
...
plugs:
  etc-foo:
    interface: system-files
    read:
    - /etc/foo

apps:
  foo:
    plugs:
    - etc-foo
    ...

Note, when declaring an instance of the system-files plug as above, it should be named with a descriptive name that indicates to a user what access it grants. In this case, the name etc-foo is used to reflect the access to /etc/foo.

With the above, a snap connect command would look like: snap connect foo:etc-foo.

Code examples

The source code for this interface is in the snapd repository: https://github.com/snapcore/snapd/blob/master/interfaces/builtin/system_files.go

1 Like

Is this currently enabled in the daily ppa version of snap/snapd or have I jumped the gun? I know the version on that states 2.36.3+git1072.d69ac16~ubuntu18.04.1 (and not 2.37) but the git sha its built from at least mentions system-files :slight_smile:

I’m trying it out but I get the error from my service that the path does not exist.

i.e. I have in my snapcraft.yaml

plugs:
  system-files:
    read:
      - /var/lib/veebers
    write:
      - /var/lib/veebers

I install snapd from the daily ppa and install my snap (using --dangerous etc.) I sudo mkdir /var/lib/veebers/ set the config to use that path and start the service where it fails with the complaint about the path not existing.

snap version gives:

snap    2.36.3+git1072.d69ac16~ubuntu18.04.1
snapd   2.36.3+git1072.d69ac16~ubuntu18.04.1
series  16
ubuntu  18.04
kernel  4.15.0-42-generic

This directory doesn’t exist in the snap’s runtime environment. The system-files interface is only really going to be useful for when directories from the host are passed into the snap, such as /etc. I suggest looking at the layout feature for your use case.

2 Likes

Sorry I should have been clearer in my original post (ugh, the /var/lib/veebers was a testing copy and paste, that should be /var/lib/juju).

I’m wanting the snap (in this case juju-db) to have access to /var/lib/juju where Juju stores bits and pieces (certs, the db dir etc.).
So in that case I think I do want system-files? (as it’s system directory access being granted to the snap, and not snap data being exposed as a system directory?)

While /var/lib/juju is a system directory, it is also not something that is passed into your snap’s runtime environment (use snap run --shell <your snap> and look for /var/lib/juju, it won’t be there). This interface is not about exposing arbitrary system locations into your snap; it is about allowing access to files that are already in the snap’s run time environment. I’ll update the description.

1 Like

Is there an example with system-files and other plugs? I can’t seem to get the syntax right on this;

plugs:
  - network
  - network-bind
  - timezone-control
  - system-files:
    read: [/etc/somefile]
    write: [/etc/somefile]

When running snapcraft it gives the following error

Issues while validating snapcraft.yaml: The 'apps/my-app/plugs[3]' property does not match the required schema: OrderedDict([('system-files', None), ('read', ['/etc/somefile']), ('write', ['/etc/somefile'])]) is not of type 'string'

Any feedback is appreciated

Just wanna to double confirm that system-files interfaces can handle with /etc/modprobe.d/* ?

From a technical POV, yes, but from a process POV, maybe not. Perhaps create a new topic with more details as to why you need access to this directory?

1 Like

Firefox may be added to the list of examples.

Thanks for the suggestion. I’ve added Firefox to the list.

1 Like

There is a grammatical error in this quote block here. There is a missing period between the sentences Caution: do not share data between snaps and While system-files can be used to share data with another snap, such as within a configuration file, this behaviour is not recommended.

Also, not sure about this one, but should do in the first sentence be capitalized? I am mostly going off of the first quote block Interface documentation since See is capitalized after the colon.

1 Like

Thanks for flagging this. The annotation format changed as there was originally a line feed. I’ve fixed this now, and also capitalised Do, as you suggest. I think it looks better too.

1 Like