Skip to content

Instantly share code, notes, and snippets.

@jneo8
Forked from dclane-code/snapd-interfaces.md
Created October 31, 2023 03:27
Show Gist options
  • Save jneo8/d756f55dc99c72055bf50bc4ae0fced2 to your computer and use it in GitHub Desktop.
Save jneo8/d756f55dc99c72055bf50bc4ae0fced2 to your computer and use it in GitHub Desktop.
snapd interface creation

Writing snapd interfaces

Goal of this is to create an interface that allows a snap to read (for example) /root/dclane.txt

Checkout snapd

$ git clone https://github.com/snapcore/snapd.git
$ git checkout 2.59.5       # best to be on a released version than HEAD

Hack on an interface.

In my case, i chose to take the removable-media interface as a template and replace it with my policy

$ cd ~/snapd/interfaces/builtin/
$ cp removable-media.go dclane-support.go

Rename the various required functions and interface name

$ sed -i 's/removableMedia/dclaneSupport/g' dclane-support.go
$ sed -i 's/removable-media/dclane-support/g' dclane-support.go

Then edit the file manually and define the actual interface rules you require:

$ cat dclane-support.go

package builtin

const dclaneSupportSummary = `allow access to /root/dclane.txt`

const dclaneSupportBaseDeclarationSlots = `
  dclaneSupport:
    allow-installation:
      slot-snap-type:
        - core
    deny-auto-connection: true
`

const dclaneSupportConnectedPlugAppArmor = `
# Description: can access /root/dclane.txt

/root/dclane.txt r,

`

func init() {
        registerIface(&commonInterface{
                name:                  "dclane-support",
                summary:               dclaneSupportSummary,
                implicitOnCore:        true,
                implicitOnClassic:     true,
                baseDeclarationSlots:  dclaneSupportBaseDeclarationSlots,
                connectedPlugAppArmor: dclaneSupportConnectedPlugAppArmor,
        })
}

No further reference needs to be made to the interface in order for it to be included in snapd :)

Build snapd


from @mvo

if you just want to hack on snapd could don't need to build the entire snap, just "sudo systemctl stop snapd.{socket,service}" and "cd cmd/snapd && go build && sudo ./snapd" should work too

$ cd cmd/snapd
$ go build

Run your snapd

Stop the existing snapd and start yours!

$ sudo systemctl stop snapd.{socket,service}
$ sudo ./snapd

Test your snap

Add a plug for your new interface into your snap. eg:

$ cat snapcraft.yaml
...
apps:
    interface-test:
       command: interface-test.py # eg: cat /root/dclane.txt, per the interface
       plugs:
       - dclane-support
...

Build and install your snap

$ snapcraft
(output snipped)
$ snap install ./dclane-test.snap

Attempt (without the interface connected)

$ sudo dclane-test.interface-test
Traceback (most recent call last):
  File "/snap/dclanebus/x1/interface-test.py", line 3, in <module>
    with open('/root/dclane.txt', 'r') as f:
PermissionError: [Errno 13] Permission denied: '/root/dclane.txt'

Fix by connecting your new interface

$ snap connect dclane-test:dclane-support

Profit

$ sudo dclane-test.interface-test
it works!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment