Interface request: "cups-control" on CUPS snap and including D-Bus

If you want to print (or do printer administration) from a snapped application you add a plug to the “cups-control” interface, to connect to the domain socket of CUPS. The slot is most probably provided by the classic emvironment with a Debian-package-based CUPS installed.
Some time a go, I started the developemt of a CUPS snap:


First thought of it was to allow printing in an all-snap distribution like Ubunru Core, but also to provide a distribution-independent implementation of a printing stack on OpenPrinting, for everyone being able to use a printinf stack composed from the newest components. I brought it even to a first test release in the Snap Store.
Now Ubuntu development is going to provide more and more components of the Desktop distribution to be provided in snaps. Also CUPS should come from a snap soon.
Therefore I have picked up the developemnt of the CUPS Snap again and done a lot of bug fixes and improvements for better reliability and usability of the snap.
Now I was hitting into some problems with the interface:

  1. A snapped application has a plug to the “cups-control” interface. This leads to a CUPS installed from Debian packages into the base system
  2. If there is no such CUPS but the CUPS snap installed instead, “cups-control” should point into the snapped CUPS, so the snapped CUPS needs to provide the “cups-control” slot. There needs to by some kind of automatic switch for which CUPS is actually installed.
  3. CUPS does not provide only a domain socket (/var/run/cups.sock in the case of CUPS in Debian packages) but also IP access via localhost:631 and also D-Bus services (AFAIK /org/cups/cupsd/Notifier and /com/redhat/PrinterSpooler at least). The interface needs to allow access to all of these channels for every snap with plug to “cups-control” but also to unsnapped (Debian-installed) applications.
  4. The “dbus” snap interface is not very well suited for CUPS as a client snap would need to connect to “cups-control” and two “dbus” interfaces, so 3 interfaces would need to get connected, therefore I like to have that all in one “cups-control” interface.

My request is to get the “cups-control” interface appropriately extended so that snapped applications have always full access to CUPS, independent whether CUPS comes from Debian packages or from the snap, and also that unsnapped applications have full access to CUPS, also to the D-Bus services.
Note that the CUPS snap will soon get renamed, from the current “printing-stack-snap” to “ipp-service-cups”.
I hope that this is possible to get implemented.

Till

My 2 pence on this is that from a clean slate we should have 2 interfaces for cups:

  • cups which allows an application to talk to the cups daemon over DBus, access the CUPS socket, etc.
  • cups-support which provides the accesses necessary to operate as the cups daemon

The cups interface would be plugged by an application like LibreOffice that wishes to print. It would either connect to a slot provided by the core/system snap if and only if there is not an “official” cups snap, but if there is an “official” cups snap installed, the slot comes from that snap instead (this distinction is useful because we can have different accesses depending on if the snap is connecting to an unconfined cups daemon, or if it is connecting to a confined cups daemon that is packaged as a snap.

The cups-control interface would be plugged by only the confined ipp-service-cups snap, much like lxd-support is only plugged by the official lxd snap.

The only caveat I will add to this is that I seem to remember @jdstrand mentioning some time that the cups-control interface has some specific accesses that make it unsafe or unreasonably powerful and that we couldn’t properly mediate it, so some apps have been denied auto-connect for the cups-control interface. This might complicate my proposal above, meaning that we can’t have cups and instead need to have cups-control and all its unreasonably wide accesses for applications wanting to print using the official ipp-service-cups snap.

I don’t quite follow this, are you saying that installing a snap application that plugs cups-control triggers debian packages to be installed on the system?

I don’t know that this work is completely done, but there is work around a “greedy” snap declaration which allows a snap application to declare that it should connect to “all such slots”, but I think this could perhaps be extended to have some logic like connecting to “the system slot if it exists, or a specific slotting snap if that snap is installed”. See Plug/slot declaration rules: greedy plugs for the current state of things. There has been prior requests for this kind of behavior at least at https://github.com/snapcore/snapd/pull/7417 for example.

Does this just mean a network port? Is there a reason why the network interface is insufficient for this specific access?

This should be fine to add to the interfaces.

Rather than have apps plug cups-control and 2 dbus interfaces, we should probably just add the dbus rules to the cups interface I mentioned above, then applications only need to plug cups.

AFAIK, the store does not support renames, is there a significant user base here of the printing-stack-snap? If so you will probably want to put together a migration plan to get users to manually install the ipp-service-cups snap instead.

How is the cups-control interface exactly defined? Is this documented somewhere? Who provides the slot currently? What does @jdstrand tell what is too powerful on this interface?
Yes, I also think it could make sense to have 2 interfaces, a simple cups one which allows printing and checking and handling jobs via domain socket, localhost:631, and D-Bus, for the apps which want to print. and a cups-control or cups-support one for apps which want to create print queues, modify the CUPS configuration, …, which should get admin access (like a user in the lpadmin group in classic Ubuntu.
Somehow we need also automatic switching that the interfaces are provided by the ipp-service-cups package when it is installed.

  • A snapped application has a plug to the “cups-control” interface. This leads to a CUPS installed from Debian packages into the base system

I don’t quite follow this, are you saying that installing a snap application that plugs cups-control triggers debian packages to be installed on the system?

I do not mean here that the installation of Debian packages is triggered, I mean here that there are Debian packages of CUPS already present in the current standard installations of Ubuntu. Snapped apps have a plug to the cups-control interface and through this they access this CUPS which current;ly comes from Debian packages. If we replace these Debian packages by the ipp-service-cups snap, we need to assure that these applications print through the snapped CUPS.

This is exactly what I mean.

No, there is no real user base on printing-stack-snap. When I first loaded that into the Snap Store something like two years ago no one actually downloaded it and I did not get any feedback. So we can simply set up ipp-service-cups as a new package.
Till

The interface is defined in snapd source code here: https://github.com/snapcore/snapd/blob/master/interfaces/builtin/cups_control.go