Getting back to this now.
<TLDR;>
Due to limitations with the AppArmor parser and the design of snapd, we (IMO) have essentially two options:
- The Px/px idea is the cleanest implementation, but requires patching apparmor parser to fix bug #16965522. The problem with this approach is propagating that fix everywhere. It is possible for Solus to pick it up and for Ubuntu to SRU, but far less likely Ubuntu derivatives, Debian, SUSE, etc will pick it up. snapd could perform a runtime detection and do something smart-- eg distros with full AppArmor support only expose the interface if the fix is in place (partial AppArmor support doesn’t end up with the rule at all so no problem)
- We utilize a child profile with a Cx/cx rule and modify snapd to accommodate this. The least intrusive option is to put the child profile (ie what
plugs: [steam-game]
) in a separate file '#include’d by the parent (ie, what plugs: [steam-support]
) and adjust snapd to load/unload the parent profile with interface connect/disconnect for the child. We also adjust ‘command’ in snap.yaml to either require ‘null’ assignment or to be omitted when used with ‘steam-game’
I prefer ‘1’ since it is the cleanest implementation, but need an architect to decide if it is ok from a cross-distro perspective. ‘2’ is not as clean, but I think it can be done in a way that isn’t terrible from an implementation perspective (with a little design for the finer points (which can be done in PR review)).
Full context
jjohansen and I discussed options with apparmor wrt Px and Cx rules.
Because of the apparmor bug with Px/px, we can’t use the Px/px idea today. We could fix the parser for the bug, but that won’t propagate to everywhere snapd is supported (we could SRU for Ubuntu, but Solus, SUSE, Arch, Debian, Ubuntu derivatives, etc may not have the fix), but then the snap would operate differently on different distros. To remedy this, we could surface the interfaces on if the parser had the fix (it could be a runtime check).
The alternative is to use a child profile in some fashion. In practice, this results in variations on two choices:
- embed the child profile in the parent (eg
profile snap.snap-client.snap-client { game {} }
)
- put the child profile in a separate file
‘1’ might work with snap.yaml like the following:
name: steam-client
apps:
steam-client:
command: $SNAP/bin/client
plugs:
- steam-support
- network
- removable-media
- home
- desktop
- browser-support
- ...
With this, we have steam-support put one set of rules in the parent profile and another set in the child profile and we adjust snapd so that all the other interfaces are added to both. This is a somewhat complicated proposition within snapd in terms of adjusting interface connections, but not impossible. It also suffers from the fact that the client and the game have all the same interfaces (differing only in what stream-support
conditionally puts in each).
‘2’ might work with snap.yaml like the following:
name: steam-client
apps:
steam-client:
command: $SNAP/bin/client
plugs:
- steam-support
- network
- desktop
- home
- removable-media
game:
command: ???
plugs:
- steam-game
- network
- desktop
- home
- ...
With this, the client and the game can have different plugs
. Because the child profile for ‘game’ is in another profile, we either need to:
- be cognizant of load order (parent then child) and unload order (child then parent) and lexically name the profile such that the cache files load in the right order. This would require fairly involced changes to snapd profile load/unload
- have the parent ‘#include’ the child and have snapd ignore loading/unloading the child. This requires simpler changes to snapd
With ‘2’ , in order to avoid more complicated changes to snap run, snap-confine, etc for the profile name being snap.steam-client.steam-client//game
, we also have to decide how to deal with the fact that ‘steam-game’ is not actually a command and that it is a child profile of ‘steam-client’. One way to handle this is by ignoring command
when used with steam-game
. Eg:
name: steam-client
plugs:
steam-support:
child-command: game
apps:
steam-client:
command: $SNAP/bin/client
plugs:
- steam-support
- ...
game:
command: null
plugs:
- steam-game
...