Handling of the "cups" plug by snapd, especially auto-connection

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:

  1. The cups snap shall still slot the cups interface for client apps wishing to print to plug
  2. The cups snap shall provide a basically empty cups-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 get default-provider working so that the cups snap is auto-installed everywhere properly)
  3. Client snaps can plug cups and they will get auto-connected to the slot exposed by the cups snap
  4. Client snaps can also plug the cups-auto-connect-hack content interface with the default-provider set to cups, such that when a user installs this snap (and they do not yet have the cups snap installed), then the cups snap will get automatically installed if it is not already installed.
  5. The cups slot shall gain a new attribute (call it cups-socket real name TBD) that the cups 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 a cups interface plug connected. This would be implemented with the mount backend internally in snapd interface code.
  6. The cups interface on the slot side shall be bind mounted the cupsd unix socket identified by the slot side cups-socket attribute somewhere “standardized” which is not in the standard CUPS socket location that typical applications use (i.e. /run/cups-snap/cups.socket or some such).
  7. 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_SERVER to the location agreed up on in 6.
  8. 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 the cups snap. This interface would allow accessing the standard cups socket location /run/cups/cups.sock 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.
  9. 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 using cups-control and wishing to do printer administration may end up talking to cupsd from the cups snap in the special case where the only cupsd on 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 cups interface 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