The issue I saw with using /run/cups/cups.sock
as the bind mount destination for the cups socket originating from the cups
snap is that it excludes using cups-control
at the same time with the real socket at that location - this means that in order to give a snap using the cups
interface additional admin privileges, you would have to disconnect the cups
interface, whereas if the socket from cups that does proxying is bind mounted elsewhere, then you can have both sockets accessible at the same time.
I suppose maybe this is a disadvantage though, since client apps probably won’t have an easy way to switch which socket location they use, and at least with bind mounting the proxying socket in the same location, snap apps don’t need to change where they look for the socket if they want to switch between using the cups
and the cups-control
interface, and the way to switch is just disconnecting cups
and connecting cups-control
. In the case where cupsd on the host is actually coming from the cups
snap, then client snaps don’t need to disconnect cups
, as the cupsd from the cups
snap will be able to identify that the client end of the socket has the cups-control
interface connected.
I think I’ve been convinced and instead what we should do is a simpler version of above:
- The
cups
snap shall still slot thecups
interface for client apps wishing to print to plug - The
cups
snap shall provide a basically emptycups-auto-connect-hack
(name TBD) content interface that client snaps wishing to print can plug (but note that client snaps wishing to print do not need to plug this - this content interface exists purely so we can getdefault-provider
working so that thecups
snap is auto-installed everywhere properly) (eventually this content interface can go away when we supportdefault-provider
for thecups
interface) - Client snaps can plug
cups
and they will get auto-connected to the slot exposed by thecups
snap - Client snaps can also plug the
cups-auto-connect-hack
content interface with thedefault-provider
set tocups
, such that when a user installs this snap (and they do not yet have thecups
snap installed), then thecups
snap will get automatically installed if it is not already installed. - The
cups
slot shall gain a new attribute (call itcups-socket
real name TBD) that thecups
snap can use to specify the location the unix socket that cupsd listens on that can be bind mounted by snapd into the mount namespace of the client snap that has acups
interface plug connected. This would be implemented with themount
backend internally in snapd interface code. - The
cups
interface on the slot side shall perform a bind mount of the cupsd unix socket identified by the slot sidecups-socket
attribute to the standard location of the cups socket/run/cups/cups.sock
- Snaps wishing to do more than just submit print jobs and wishing to actually administrate and control printers etc, shall plug the
cups-control
slot, which can either be manually connected to the system, implicit slot or to the slot provided by thecups
snap. This interface would allow accessing the standard cups socket location/run/cups/cups.sock
(regardless of whether that socket location is a bind mount from thecups
interface or not) so that snaps could talk directly to cupsd, whether that be the version in the snap, or a version installed on the host system through debs/rpms/etc. - The
cups
snap specifically shall operate in one of two modes, it shall either be a proxy, and just listen on the/var/snap/cups/common/cups.socket
socket (which is the source for the bind mount explained above and is the actual socket file that client snaps talk to) or it shall be the “real” cupsd and expose itself to unconfined apps on the host by listening also on/run/cups/cups.sock
for traditional non-snap apps to print to directly. This means that app snaps usingcups-control
and wishing to do printer administration may end up talking tocupsd
from thecups
snap in the special case where the onlycupsd
on the system is that of the snap.
This means we just need the following change in snapd:
- the cups interface shall implement a bind mount from the location identified on the slot side of the interface to
/run/cups/cups.socket
inside the plug side snap’s mount namespace
And then the cups snap would need the following changes:
- expose the content interface slot that client snaps can use with default-provider as described above
- change the
cups
slot declaration to specify the attributecups-socket: $SNAP_COMMON/cups.socket
or some such
and client snaps need no changes except to add the content interface plug definition with default-provider: cups
for the best install experience.