So just to summarize the state of this, it seems like there aren’t any other technical blockers identified by @jamesh with my proposal to share the socket that is inside the snap private directory of the cups snap via a bind mount somewhere inside the client snaps that wish to print, is that correct? It sounds like the credentials/user wishing to print and queues issue is not actually an issue?
If that is correct, then the proposal as it stands seems to be the following:
- The
cupssnap shall still slot thecupsinterface for client apps wishing to print to plug - The
cupssnap 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-providerworking so that thecupssnap is auto-installed everywhere properly) - Client snaps can plug
cupsand they will get auto-connected to the slot exposed by thecupssnap - Client snaps can also plug the
cups-auto-connect-hackcontent interface with thedefault-providerset tocups, such that when a user installs this snap (and they do not yet have thecupssnap installed), then thecupssnap will get automatically installed if it is not already installed. - The
cupsslot shall gain a new attribute (call itcups-socketreal name TBD) that thecupssnap 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 acupsinterface plug connected. This would be implemented with themountbackend internally in snapd interface code. - The
cupsinterface on the slot side shall be bind mounted the cupsd unix socket identified by the slot sidecups-socketattribute somewhere “standardized” which is not in the standard CUPS socket location that typical applications use (i.e./run/cups-snap/cups.socketor some such). - Snaps wishing to only submit print jobs shall set (either through directly setting the environment stanza in the snapcraft.yaml, a snapcraft extension or just wrapper scripts) the environment variable
CUPS_SERVERto the location agreed up on in 6. - Snaps wishing to do more than just submit print jobs and wishing to actually administrate and control printers etc, shall plug the
cups-controlslot, which can either be manually connected to the system, implicit slot or to the slot provided by thecupssnap. This interface would allow accessing the standard cups socket location/run/cups/cups.sockso 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
cupssnap specifically shall operate in one of two modes, it shall either be a proxy, and just listen on the/var/snap/cups/common/cups.socketsocket (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.sockfor traditional non-snap apps to print to directly. This means that app snaps usingcups-controland wishing to do printer administration may end up talking tocupsdfrom thecupssnap in the special case where the onlycupsdon the system is that of the snap.
Does all of that make sense? If so, then next steps here are to agree on:
- The source location that cupsd should listen on it’s socket to be bind mounted for client snaps just wishing to print (i.e. the proxying socket)
- The destination location that the cups proxying socket should be bind mounted to inside the client app snap wishing to print’s mount namespace - this will be the same location that we set CUPS_SERVER to.
- The name of the attribute for the
cupsinterface slot mentioned in 3 above - The easiest mechanism to ensure that client snaps can get CUPS_SERVER set appropriately without much hassle - I think snapcraft extensions are the easy thing to do here, but maybe that is overkill