I recently published Fingerpaint on Snapcraft, and I would like that the app to work out of the box (without manual connections).
The app allows you to draw using your touchpad, using it as a canvas (that means getting raw/absolute touch data from the sensor).
In order to do that I need:
The raw-input plug (for access to /dev/input/eventX)
The hardware-observe plug (for navigating /sys to know which device is the touchpad)
In addition, I add a udev rule (ENV{ID_INPUT_TOUCHPAD}=="1", MODE="0664") that allows non-root users to access this device (I consider this ok privacy-wise since it’s just a touchpad, not a keyboard, and since getting this data is rather trivial anyway when not running in a confined snap).
Adding the udev rule is handled by prompting the user to run a setup script as root (outside the sandbox) if the device is inaccessible.
From what I can tell from the snap’s description:
Your touchpad will not control the cursor while drawing, though external mice should still work
I assume that this snap takes the raw-input from the device rather than using the higher-level input interfaces provided by wayland / X etc? And so that is why it needs this low-level access?
Can you also explain more about the udev rule? What exactly do you prompt the user to do in this case? How does the snap handle removing this udev rule when it is uninstalled? Would it be better to instead ask the user to say add themselves to the input group? Or to split your snap into a privileged daemon that can run as root and access the device file directly and then have the frontend user-facing part communicate with the daemon to get the input events through it? Then a user should not have to do anything.
The udev rule grants raw access to the touchpad (bypassing any window server), and does not get removed on uninstall at the moment.
I prompt them to run a shell script outside the sandbox as root, since snap has no api for pkexec.
The input group idea hurts privacy (allows keylogging (not that it matters, breaking out of the snap sandbox is pretty trivial for on a desktop environment with gsettings)), and requires a logout (terrible UX).
The daemon idea seems overcomplicated (socket activation + fd over Unix socket) or slow/bloated (always running, sending events over socket) and introduces unnecessary attack surface for the root user.
I gave up on packaging this as a snap once I rewrote the app in GTK4 and encountered multiple bugs, a huge 50MiB+ (compressed, 150MiB+ uncompressed) package, and 10 second startup times on my top of the line Ryzen FROM RAM (liveusb with no persistent partition).
I refuse to ship an app under my name that takes more than a second to display a sign of life.
For comparison, the flatpak is 1MiB and works on Ubuntu 18.04 (unlike the snap, I ain’t debugging that).
So basically I won’t release a new update for this snap as long as the GTK4 experience wont improve
Thanks for your work and attention, and I hope for the sake of the Linux ecosystem y’all improve on these points.
looking at @Wazzaps snap (https://github.com/Wazzaps/fingerpaint/blob/feature/snap/snap/snapcraft.yaml) it seems to use a lot of external helper scripts pulled in via various stage-snap entries (tcltk-launch, debian-multiarch-triplet-provider-launch)… i wonder if all use the same base snap here, else you might indeed see a lot of harmful issues …
it also does not use the gnome extension so there will be a good bunch of duplicated (gtk) libs pulled in and such which will indeed result in a rather large size … i guess with a bit of clean up of the packaging to use the correct bits and pieces the snap won’t be (and behave) much different to the flatpak in the end.
(Note: I had to restart in the middle of this process since I noticed the build process is not hermetic and showed build files from previous tries which made it work)
Cannot pack snap file: Command '['snap', 'pack', '--filename', 'fingerpaint_1.4.0_amd64.snap', '--compression', 'xz', PosixPath('/root/prime'), PosixPath('/root/project')]' returned non-zero exit status 1. (2023/06/15 19:44:37.899502 container.go:215: in snap "fingerpaint": path "bin/fingerpaint" does not exist
error: cannot pack "/root/prime": snap is unusable due to missing files)
You shouldn’t need all the override stuff, the plugin should just process setup.py, but kens Patch removed the source: entry in line 39… that might have some impact…
EDIT: oops, sorry I’m obviously blind, it is there lower down…
It would be better to do a “snapcraft clean” in cases like that rather than using override-prime. Generally you shouldn’t end up in that state, but it’s always useful to do a clean to ensure your build is sane.
FWIW I just checked out @kenvandine’s branch locally and was able to build it successfully with just snapcraft. What version of snapcraft are you using?
Ok, finally got the time to look at this, sorry for the delay.
Re-installing snapd and snapcraft fixed the issue, I’m in the process of building it for ARM64 as well and then i’ll publish the new GTK-based version.
Thanks for the help!