Update: Since I posted this thread I have come to the conclusion that I need the classic confinement. Read the posts below.
Hi!
Before I start, I just want to say that I am quite new to this so please excuse me if this is the wrong place to post this type of request.
I have published the package Wilfred on the snap store, but up to this point only to the edge channel and with the confinement level set to devmode.
The project source code is available on GitHub. I am also using the snapcraft builds for building the snap packages.
Wilfred is a CLI that uses the hosts Docker installation to create containers (for game servers). That means the package has to have access to the users Docker “socket”.
I’ve tried to do this in my snapcraft.yml.
plugs:
docker:
Is this the correct way to do it?
Anyway, the builds return the following message in my Snapcraft Dashboard: human review required due to 'allow-installation' constraint (bool) declaration-snap-v2_plugs_installation (docker, docker)
As far as I can see, this means that I have to request the ability to use the docker plug?
Yes, this is the correct way to do this, assuming your application talks to the docker socket directly rather than trying to use the docker command. If you need to use the docker command, you need to do an additional step, to declare a content interface plug that will connect to the slot from the docker snap to your snap so that the docker snap executables are accessible from inside your snap.
The network plug is auto-connected and doesn’t need a request like the docker interface does, so it should auto-connect when you install the snap without anything from the store.
I can’t get it to work, the snap package isn’t able to speak to the Docker socket. Does docker have to be installed via snap (because right now I have Docker installed separately)?
File "/snap/wilfred/x1/lib/python3.6/site-packages/docker/transport/unixconn.py", line 43, in connect
sock.connect(self.unix_socket)
PermissionError: [Errno 13] Permission denied
This is my snapcraft.yaml.
name: wilfred
base: core18
version: git # set version on release ('0.1.0') and use 'git' during dev
summary: A CLI for managing game servers using Docker # 79 char long summary
description: |
Wilfred is a command-line interface for running game servers locally. It uses Docker to run game servers in containers, which means they are completely separated. Wilfred can run any game that can run in Docker.
Wilfred is currently under development and should not be considered stable. Features may brake or may not be implemented yet. Use with caution.
grade: stable # 'stable' on release ('devel' during dev)
confinement: strict
plugs:
docker:
content: docker
default-provider: docker
interface: content
target: docker-env
network:
parts:
wilfred:
plugin: python
source: .
build-packages:
- python3-distutils
- build-essential
stage-packages:
- python3-distutils
- build-essential
apps:
wilfred:
command: bin/wilfred
plugs: [docker, network]
environment:
PYTHONIOENCODING: utf-8
LC_ALL: C.UTF-8
LANG: C.UTF-8
Well it’s awkward because the interface slot needs to be provided by the docker snap (indeed the only snap in the store which is allowed to have a docker slot), which means they need to have the docker snap installed. However, since all you really need I think is the docker slot to add the permissions to talk to the socket, it is conceivable you could try installing the docker snap to have that slot exposed and then disable the dockerd service from the snap (but don’t disable the whole snap since then the slot disappears), but this is not a supported use case and may not always work, while this is a supported use case with the docker snap.
I would suggest going for classic confinement if you truly desire to be able to talk to any docker version, however the reviewers may disagree with me here. Note that using classic confinement means that your snap cannot be used on Ubuntu Core.
Thank you very much for explaining it to me, I have had some trouble getting my head around these new concepts.
Due to the nature of the application I am building, it’s quite important that users can use the app without also using the Docker snap. I am fine with the application not being supported on Ubuntu Core.
I have just pushed a new commit with the confinement set to “classic”. I would like to request the classic confinement instead.
I’m not sure either, but I tried recommending that it be implicit and was told not to change it by @zyga-snapd IIRC in a PR from a long time ago. I vaguely remember the reasoning being something like the slot being tied to what’s actually providing the socket?
I’ve taken a TODO to investigate why it isn’t and to add it to implicit classic. We have plenty of things like this that exist on classic and could be a snap and our thinking around this has refined since the early days.
as for the request for classic confinement, I’m not opposed to that, in case of voting you have my support
as for docker interface being implicit on either classic or core, read on
At the time, and currently still mostly so, snapd will not auto-connect connections when there are multiple identical providers. If both the system/core/snapd snaps provide docker and someone installs docker as a snap, then snaps using docker will require manual connections. This is only a usability issue. With some of the new language that is growing in snap declaration assertions, we could say that a docker plug is greedy and connects to all implementations available on the system.
Thanks for looking into this and thank you for your support. Regarding the Docker interface, I just want to implement my application the best way possible with snap. I think this discussion is really interesting and it’s definitely something that could affect my application’s integration with snap. But maybe it’s a little bit out of this thread?
Currently, my application let’s the user choose a path for storing data. I just realized that might be another reason for why I’d like to request the classic confinement (in case the user would like to use a path outside of the confinement, if strict).
This is a perfect example of where “on-demand” confinements would be handy (because then the application would be able to request authorization to use a specific path through snap). That’s not possible as of now, right?