Content interface plugs autoconnect to the wrong provider

Bug #1674824 reported by Pat McGowan
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Canonical System Image
Fix Released
Critical
Unassigned
snapd (Ubuntu)
Fix Released
Undecided
Unassigned

Bug Description

I have ubuntu-app-platform installed which exposes a slot called "platform"
I created a consumer that looks for slots provider1:shared1 and provider2:shared2

This is snap interfaces after installing my test snaps and without issuing any connect commands. Note that these (consumer, provider) are local snaps installed with --dangerous.

provider1:shared1 -
provider2:shared2
ubuntu-app-platform:platform consumer:shared1,consumer:shared2

$ snap version
snap 2.23.5
snapd 2.23.5
series 16
ubuntu 16.04
kernel 4.4.0-66-generic

Running consumer reports
cannot mount /snap/ubuntu-app-platform/34 at /snap/consumer/x1/shared1 with options bind,ro: No such file or directory

Only tested on a classic system, Xenial and Zesty

In another case, I had a snap that plugged ubuntu-app-platform and mir-libs, similar symptom but in fact the content from platform showed up in the mir-libs folder of the snap.

Manually connecting (and discard-ns) makes it work

summary: - Content inteface plugs autoconnect to the wrong provider
+ Content interface plugs autoconnect to the wrong provider
Changed in canonical-devices-system-image:
importance: Undecided → Critical
milestone: none → u8c-2
status: New → Confirmed
Revision history for this message
Pat McGowan (pat-mcgowan) wrote :
description: updated
Revision history for this message
Pat McGowan (pat-mcgowan) wrote :

Also happens with apps from the store without --dangerous

Revision history for this message
Pat McGowan (pat-mcgowan) wrote :

What also happens is the snap is plugged into two different snaps at the same time, not sure if thats expected.

This is after manually connecting mir-libs without first disconnecting from u-a-p

$ snap interfaces | grep mir-libs
mir-libs:mir-libs ubuntu-calculator-app,ubuntu-docviewer-app
ubuntu-app-platform:platform ubuntu-calculator-app,ubuntu-calculator-app:testability,ubuntu-docviewer-app:mir-libs,ubuntu-docviewer-app

Revision history for this message
Pat McGowan (pat-mcgowan) wrote :

This is what is the the assert file for ubuntu-app-platform

Shouldn't this be declaring autoconnect for the slot "platform" and not "content"?

type: snap-declaration
format: 1
authority-id: canonical
revision: 1
series: 16
snap-id: lVVvNqHcPT7JmLDWqwJ6q6ron9QBXcEz
publisher-id: canonical
slots:
  content:
    allow-auto-connection: true
snap-name: ubuntu-app-platform
...

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

@Pat - 'Shouldn't this be declaring autoconnect for the slot "platform" and not "content"?'

No, 'content' is correct because that is the interface name. 'platform' is a reference used by the snaps and not for the snap declaration.

Revision history for this message
Pat McGowan (pat-mcgowan) wrote :

to repro currently install these packages from edge:
ubuntu-app-platform
mir-libs
ubuntu-docviewer-app

Revision history for this message
Jamie Strandboge (jdstrand) wrote :
Download full text (3.4 KiB)

There are several things going on:

1. your snap is using this for plugging the ubuntu-app-platform content interface:

plugs:
  shared1:
    content: shared1
    interface: content
    target: shared1
    default-provider: provider1:shared1
  shared2:
    content: shared2
    interface: content
    target: shared2
    default-provider: provider2:shared2

This yaml is using an invalid name for 'default-provider', is specifying a non-existent 'content' value and does not ship /run/consumer/current/shared1 or shared2. See https://github.com/snapcore/snapd/wiki/Interfaces#content for how these interface attributes are to be used.

Since the ubuntu-app-platform has this in its yaml:

slots:
  platform:
    content: ubuntu-app-platform1
    interface: content
    read:
    - .

your snapcraft.yaml should be something like for the ubuntu-app-platform snap:
plugs:
  uap1:
    content: ubuntu-app-platform1
    default-provider: ubuntu-app-platform
    target: shared1

where 'content' is the same as the 'content' value in the providing snap (ie, ubuntu-app-platform1), 'default-provider' is the name of the providing snap (ie, ubuntu-app-platform) and 'target' is the name of a directory in $SNAP for you snap (this directory *must* exist because it cannot be created for you).

2. 'sudo snap install ./consumer*snap --dangerous' results in autoconnecting ubuntu-app-platfrom despite all of the above issues with your snap.yaml. This is because of a too-lenient snap declaration.

3. Because of the too lenient snap declaration for ubuntu-app-platform, if you have a snap that plugs both ubuntu-app-platform and mir-libs, since mir-libs does not currently have a snap declaration, both plugs would be auto-connected to ubuntu-app-platform and mir-libs skipped.

Note that local unasserted snap installs of content snaps don't have a signed snap declaration on the system, so only the base declaration can be consulted. This accounts for differences in behavior with snaps installed with and without --dangerous.

I have adjusted the snap declaration for ubuntu-app-platform to have:

slots:
  content:
    allow-auto-connection:
      -
        plug-attributes:
          content: $SLOT(content)
        slot-attributes:
          content: ubuntu-app-platform1

This means that the auto-connection can only happen with the plugging snap that uses "content: ubuntu-app-platform1", which is precisely how it is supposed to work.

To fix your snap for ubuntu-app-platform and mir-libs, use this yaml:

plugs:
  uap1:
    interface: content
    content: ubuntu-app-platform1
    target: shared1
    default-provider: ubuntu-app-platform
  ml0:
    interface: content
    content: mir0
    target: shared2
    default-provider: mir-libs

then create the shared1 and shared2 directories beside your snapcraft.yaml file, then snapcraft will generate a snap that will work for you. Specifically, if you install ubuntu-app-platform first, upon install of your snap ubuntu-app-platform will be mounted on $SNAP/shared1 and nothing will be mounted on $SNAP/shared2 (since mir-libs doesn't yet have a snap declaration for auto-connection). When you 'sudo snap connect consumer:ml0 mir-libs:mir-libs',...

Read more...

Changed in snapd (Ubuntu):
status: New → Fix Released
Revision history for this message
Jamie Strandboge (jdstrand) wrote :

FYI for future reference, I refined the snap declaration to be even more specific:

slots:
  content:
    allow-auto-connection:
      -
        plug-attributes:
          content: $SLOT(content)
        slot-attributes:
          content: ubuntu-app-platform1
        slot-publisher-id:
          - canonical
        slot-snap-id:
          - lVVvNqHcPT7JmLDWqwJ6q6ron9QBXcEz

In this manner, if this is the ubuntu-app-platform snap (snap id lVVvNqHcPT7JmLDWqwJ6q6ron9QBXcEz) from canonical, then a plugging snap that uses 'content: ubuntu-app-platform1' will be auto-connected.

Changed in canonical-devices-system-image:
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.