Right. The problem I was alluding to was what happens when there are two candidates on the system for auto-connection (system:cups
and cups:printing
): at present, I think this results in neither slot being connected. That’s what the slots-per-plug
assertion can help with.
Se my post above again, I have completed it now.
In this case both slots should be connected, then all should work as I described in my previous post.
So then we should simply use a slots-per-plug: *
for both cups
and cups-control
for both connect and auto-connect. As there is only one cupsd on the standard resources (if at least one instance of CUPS is installed) the correct thing will happen when the user application’s plug plugs both the system’s slot and the slot of the CUPS Snap.
Is this how slots-per-plug
is implemented in current snapd?
Where have the slots-per-plug: *
declarations to be done?
slots-per-plug
is something that would go in the snap declaration published by the store. It is not something you can control from your snapcraft.yaml
file. This is the last time I made a request for such a declaration:
Back then, there was no policy for granting this type of request, so it was handled in an ad-hoc fashion. I’m not sure what the status is now.
Now for some other questions:
-
You’ve got both plugs and slots for the
cups
andcups-control
interfaces, with the plugs taking the default name, and the slots namedprinting
andadmin
respectively. Given that Most other snaps will generally be dealing with the CUPS snap’s slots, might it make more sense to give the slots the default names?With things like it is, it seems likely that people will try commands like
sudo snap connect app:cups-control cups:cups-control
and then get confused about them not working. -
Does your snap actually need a
cups
plug? I would have thought the utility commands would have enough access to the CUPS socket through thecups-control
slot. -
I can see the
cups-control
plug as being necessary in order for thesnapctl is-connected
checks to pass and allow administrative commands likelpadmin
to do their thing.I wonder if we could solve this by adding one more exit code to the
is-connected
command representing “not connected, but from the same snap”. That might be enough to get the bundled admin utilities to function without the plug. What do you think?
- Yes, I can do that. I simply did not know that it is possible and the default. If I do so, do we need to re-vote or is it simply understood?
- OK, as the permissions of a plug a given by-Snap and not by-app (one app plugs
cups-control
so all the other apps plugging onlycups
are also allowed to admin) I can let them all plugcups-control
and so the CUPS Snap does not plugcups
any more. - This is a good idea. Please implement it. But as it takes time for you to implement and for the mainyainers to approve the @reviewers should for now apply the auto connections as they are and I modify the CUPS Snap as soon as this new exit code is available.
@reviewers, is it OK if I rename the slots of the CUPS Snap to standard?
From
slots:
# Provide the cups-control and cups slots for other snaps to connect to
admin:
interface: cups-control
printing:
interface: cups
to
slots:
# Provide the cups-control and cups slots for other snaps to connect to
cups-control:
interface: cups-control
cups:
interface: cups
so that we now need the following auto-connections:
sudo snap connect cups:cups-control cups:cups-control
sudo snap connect cups:cups cups:cups
sudo snap connect cups:network-manager-observe
Does it work this way? Does it need a new voting? Or can I simply do this change right now and you apply the auto-connects this way in the Snap Store?
Could you apply the auto-connects this way then, set slots-per-plug: *
for connecting and auto-connecting both cups
and cups-control
for user applications uploaded into the Snap Store, and let the Snap Store allow auto-connection of cups
for uploaded user applications without explicit approval?
@jamesh, If I do the renaming of the slots (printing
-> cups
, admin
-> cups-control
) as described in my previous post and build the Snap I get the following error:
Snapping |
Failed to create snap, snap command failed:
stdout:
stderr:
error: cannot pack "/root/prime": cannot validate snap "cups": cannot have plug and slot with the same name: "cups-control"
We would appreciate it if you anonymously reported this issue.
No other data than the traceback and the version of snapcraft in use will be sent.
How do I do this correctly?
Plugs and slots share the same namespace, as that error message indicates. I was suggesting that you rename the plugs (which are only of interest to the cups snap) to something else, so the slots could use the default names.
So you mean the plug(s) for the command line tools which come with the Snap? So for example I use only one universal plug for the command line tools, like cups-internal
and let this get auto-connected to the slot cups:cups-control
via auto-connect? User applications then plug their cups
to cups:cups
and their cups-control
to cups:cups-control
?
This would mean that I also have to modify CUPS so that it accepts admin requests also on cups:cups-internal
? Or can I modify CUPS to accept admin requests simply if the SNAP NAME (not the interface plugged) is “cups” and then the tools do not need to plug anything at all?
And if I have to use cups-internal
for the CUPS tools does this not need to extend the design of snapd to support this plug?
I got it working now:
First I re-defined plugs and slots in snapcraft.yaml
:
plugs:
cups-internal:
interface: cups-control
slots:
# Provide the cups-control and cups slots for other snaps to connect to
cups-control:
interface: cups-control
cups:
interface: cups
I set the slots of cupsd as follows:
apps:
cupsd:
[...]
slots: [cups-control, cups]
On all other apps I replaced the plugs cups
and cups-control
by cups-internal
:
cups-browsed:
[...]
plugs: [network, network-bind, network-manager-observe, avahi-control, cups-internal]
lpinfo:
command: sbin/lpinfo
plugs: [network, cups-internal]
lpadmin:
command: sbin/lpadmin
plugs: [network, avahi-control, home, cups-internal]
lpstat:
command: bin/lpstat
plugs: [network, avahi-control, cups-internal]
[...]
I build CUPS with a configure option to call the cupsctl
API call with cups-control
as slot name:
parts:
[...]
cups:
[...]
configflags:
[...]
- --with-cups-control-slot=cups-control
[...]
Now I change the connection I requested in this thread to
sudo snap connect cups:cups-internal cups:cups-control
sudo snap connect cups:network-manager-observe
and for external utilities (example) I do the following connections:
sudo snap connect cups-admin-test:cups-control cups:cups-control
sudo snap connect cups-user-app-test:cups cups:cups
Now it all works as expected.
This means:
This request should be now considered as that following auto-connections are requested:
sudo snap connect cups:cups-internal cups:cups-control
sudo snap connect cups:network-manager-observe
The auto-connections are internally doing the same as the original ones, the interfaces are only renamed.
It must be assured that a Snap of a user application which prints and is put into the Snap Store should auto-connect its cups
plug to BOTH :cups
AND cups:cups
on installation. slots-per-plug: *
should be used at the right place for that.
Same for Snaps of printer managers using cups-control
with the difference that here explicit permission should be needed for auto-connection. Also here slots-per-plug: *
at the right place should be used.
@reviewers: I will commit my above-mentioned changes now, could you apply the changes as I described here? Thanks in advance.
@reviewers, @jamesh, Changes for new slot names cups:cups
and cups:cups-control
are committed to the CUPS Snap now. The Snap Store is rebuilding it currently.
Here is a PR adding the extra snapctl is-connected
exit code:
And here’s one that adds an implicit system:cups
slot:
@jamesh, thank you very much for your pull requests.
@jamesh, one question, can the client-is-from-the-same-Snap case not be checked much more easily? Keeping in mind that the Snap Store can only hold one Snap named “cups” and on a system there also can be only one Snap called “cups” be installed, CUPS could identify inquiries from the same snap by the AppArmor context? For CUPS it starts always with snap.cups.
and for other Snaps it never starts with snap.cups.
.
Yes, you could interpret the snap name in the AppArmor label yourself as a temporary measure. If that lets you get rid of the cups-control
plug on the snap, I’d do that: if you can get by without the self connections, it should make your snap a bit more robust.
@reviewers, as it will take time until @jamesh’s pull requests will get implemented in snapd and the CUPS Snap is working as it is now, I ask you to apply the auto-connections of interfaces and the slots-per-plug: *
as I described in post #31 to make the CUPS Snap working in a user-friendly way right now. Thanks in advance.
@jamesh, with the check of the AppArmor label I can free myself from the requirement that the Snap Store team has to approve the self connection as auto connection. Independent of this, the utilities have to plug one of cups
or cups-control
as otherwise AppArmor blocks their access to the CUPS Socket, even if the utilities belong to the same Snap, and I get a lpstat: Bad file descriptor
. I have quickly tested it right now, simply removing the cups-internal
plug from lpstat
and lpinfo
in snapcraft.yaml
.
So the only way to get access to the socket at all for the utilities is to create the cups-internal
alias to the cups-control
plug as I am using right now (see my longer post above). This is independent of the method how to allow administrative inquiries, checking the AppArmor label (or adding another exit code to snapctl
) only reduces the number of auto-connections to be approved by the Snap Store team.
@jamesh, in the second pull request, in interfaces/builtin/cups.go
you have deny-auto-connection: true
. Should that not be false
as for simple printing (no admin) we want to auto-connect by default. Am I right?
Re. the “bad file descriptor” error, Try removing the “slots:” stanza from the cupsd app definition in your snapcraft.yaml. This will cause those slots to be associated with every app of the snap, which should give the utilities access to the slot.
Re. auto-connection of the cups
interface, this matches the current policy of cups-control
. It seemed easier to propose just one change at a time.
@jamesh, because of the auto-connection of the cups
interface, we have inrtroduced it to have separate cups
and cups-comtrol
so that cups
auto-connects and cups-control
not. So therefore we should let cups
do auto-connect right from the beginning.