fyne-io / systray

a cross platfrom Go library to place an icon and menu in the notification area
Apache License 2.0
223 stars 41 forks source link

systray not functional within snap sandbox #64

Open peterzen opened 9 months ago

peterzen commented 9 months ago

Checklist

Describe the bug

I have a Go application that uses systray to implement a tray menu, which works as expected on GNOME and KDE. When packaged up as a snap, however, the snap sandbox prevents the menu to function properly. I'm wondering if this is something others have noticed or potentially found a solution for?

The problem occurs on GNOME, but does not on KDE, it can be reproduced by running the Fyne systray example.

How to reproduce

  1. Start with an Ubuntu 22.04 environment
  2. Set up snapcraft: https://snapcraft.io/docs/snapcraft-quickstart
  3. Clone this repo: https://github.com/peterzen/systray-example-snap
  4. Build the snap:
    cd systray-example-snap
    snapcraft --verbose
    ...
    Created snap package example_0.1_amd64.snap                                    
  5. Install the snap in devmode:
    sudo snap install --devmode --dangerous example_0.1_amd64.snap
  6. Run the app: example
  7. Observe the systray menu has been created and it's functional (menu items work as expected)
  8. Remove the snap:
    sudo snap remove example
  9. Install the snap without --devmode:
    sudo snap install  --dangerous example_0.1_amd64.snap
  10. Run app: example
  11. Observe the systray icon being visible, but the menu does not respond to clicks.
  12. See AppArmor DENIED messages in the log:
    journalctl |grep dbus

    (further log information can be obtained using the snappy-debug tool.)

  13. Transfer the .snap file to a KDE system, install it without --devmode. Run the app, observe the systray menu being fully functional.

Log messages

= AppArmor =
Time: Nov  5 14:57:02
Log: apparmor="DENIED" operation="capable" profile="/snap/snapd/20290/usr/lib/snapd/snap-confine" pid=26423 comm="snap-confine" capability=12  capname="net_admin"
Capability: net_admin
Suggestions:
* adjust program to not require 'CAP_NET_ADMIN' (see 'man 7 capabilities')
* add one of 'bluetooth-control, firewall-control, netlink-audit, netlink-connector, network-control, qualcomm-ipc-router' to 'plugs'
* do nothing if using systemd utility (eg, timedatectl): https://forum.snapcraft.io/t/managing-time-date-and-timezone-in-ubuntu-core/408/44
* do nothing (https://launchpad.net/bugs/1465724)

= AppArmor =
Time: Nov  5 14:57:02
Log: apparmor="DENIED" operation="capable" profile="/snap/snapd/20290/usr/lib/snapd/snap-confine" pid=26423 comm="snap-confine" capability=38  capname="perfmon"
Capability: perfmon
Suggestions:
* adjust program to not require 'CAP_PERFMON' (see 'man 7 capabilities')
* do nothing if program otherwise works properly

= AppArmor =
Time: Nov  5 14:57:02
Log: apparmor="DENIED" operation="dbus_method_call"  bus="session" path="/StatusNotifierMenu" interface="org.freedesktop.DBus.Properties" member="GetAll" name=":1.29" mask="receive" pid=26423 label="snap.example.example" peer_pid=1317 peer_label="unconfined"
DBus access

= AppArmor =
Time: Nov  5 14:57:02
Log: apparmor="DENIED" operation="dbus_method_call"  bus="session" path="/StatusNotifierMenu" interface="com.canonical.dbusmenu" member="AboutToShow" name=":1.29" mask="receive" pid=26423 label="snap.example.example" peer_pid=1317 peer_label="unconfined"
DBus access
Suggestion:
* try adding 'unity7' to 'plugs'

= AppArmor =
Time: Nov  5 14:57:02
Log: apparmor="DENIED" operation="dbus_method_call"  bus="session" path="/StatusNotifierMenu" interface="com.canonical.dbusmenu" member="GetLayout" name=":1.29" mask="receive" pid=26423 label="snap.example.example" peer_pid=1317 peer_label="unconfined"
DBus access
Suggestion:
* try adding 'unity7' to 'plugs'

Example code

https://github.com/peterzen/systray-example-snap

Fyne version

fyne.io/systray v1.10.0

Go compiler version

1.21.3

Operating system and version

Ubuntu Linux 22.04, 20.04

Additional Information

From the logs it would appear that the Fyne systray lib tries to talk to the system/session dbus, but some of the AppArmor rules created by the sandbox do not allow it. (When the snap is installed with --devmode, the AppArmor rules do not apply, hence the app working correctly in that case.)

Other Snap applications with systray integration work correctly on both KDE and GNOME, that indicates that the problem is related to the way Fyne systray uses the dbus. See https://snapcraft.io/signal-desktop as an example.

andydotxyz commented 9 months ago
  1. See AppArmor DENIED messages in the log:

Can you please include the journalctl error messages here for people not running on a snap capable system?

@Jacalz does this relate to flatpack rules / fixes?

Jacalz commented 9 months ago

@Jacalz does this relate to flatpack rules / fixes?

I don't think so. To be fair, I have no idea about how Snap works and if they expose the XDG Desktop Portal API (it's not specific to Flatpak in any way; it even works outside of it on my system so it's possible they do). But then again, I don't think they have any systray API available through the portal API.

I honestly doubt that this is a bug in our code. The most likely culprit that I see is that your sandbox permissions isn't letting the DBus talk name through. You probably need to update your snap manifest (or whatever it's call there) to do something similar to what we do for notifications in flatpak_demo:

https://github.com/fyne-io/flatpak_demo/blob/4d7a57a2fbaea217cede7a4ffabe4e7ec9ab70af/io.fyne.flatpak_demo.yml#L18

However, I do realise that I have never tried getting systray to work in Flatpak so I ought to test that sometime.

Jacalz commented 9 months ago

It would probably be a good idea to look at another Snap application that has a working systray and see how they have their permissions set up.

peterzen commented 9 months ago

It would probably be a good idea to look at another Snap application that has a working systray and see how they have their permissions set up.

Is there something special about systray's approach vs other implementations (due to its cross platform nature perhaps)? I'll admit I don't know much about DBus and the way it's integrated into the GNOME desktop environment but from extensive testing it would appear that its DBus use is somewhat different than other apps'.

peterzen commented 9 months ago
  1. See AppArmor DENIED messages in the log:

Can you please include the journalctl error messages here for people not running on a snap capable system?

The log messages above are gathered from journalctl.

peterzen commented 9 months ago

I honestly doubt that this is a bug in our code. The most likely culprit that I see is that your sandbox permissions isn't letting the DBus talk name through.

I don't think it's a bug either - it's indeed the apparmor permissions put in place by snapd that prevent it from talking to DBus on GNOME (there's no problem on KDE).

You probably need to update your snap manifest (or whatever it's call there) to do something similar to what we do for notifications in flatpak_demo:

https://github.com/fyne-io/flatpak_demo/blob/4d7a57a2fbaea217cede7a4ffabe4e7ec9ab70af/io.fyne.flatpak_demo.yml#L18

The officially supported way in snap is via its interfaces (desktop-legacy and desktop), which essentially add apparmor rules that enable specified DBus connectivity.

This is a similar problem someone had a while back, it's not related to this issue but it sheds a light on how he went about debugging it:

https://forum.snapcraft.io/t/trouble-to-get-electron-apps-systray-icon-working-as-a-snap/26623

(I did a flatpak also from the same app also, didn't have any issues.)

peterzen commented 6 months ago

@Jacalz does this relate to flatpack rules / fixes?

I don't think so. To be fair, I have no idea about how Snap works and if they expose the XDG Desktop Portal API (it's not specific to Flatpak in any way; it even works outside of it on my system so it's possible they do). But then again, I don't think they have any systray API available through the portal API.

I honestly doubt that this is a bug in our code. The most likely culprit that I see is that your sandbox permissions isn't letting the DBus talk name through. You probably need to update your snap manifest (or whatever it's call there) to do something similar to what we do for notifications in flatpak_demo:

@jslarraz kindly tracked down this problem in the Snapcraft forum and provided a potential fix: https://forum.snapcraft.io/t/dbus-related-apparmor-denials/37422/1

Apparently the issue is related to the Dbus path Systray uses.

andydotxyz commented 6 months ago

If that is the case then it appears that the snap configuration has decided to be less flexible than the specification. Perhaps someone with snap could test the modified path and check it works for us. I don't see any reason we can't change our published path to satisfy their requirements.