Install Hook difficulty - notify-send: not found

I’m working on building my first snap. I am trying to make the install hook create a visible alert so that I can troubleshoot more easily. I found I got more direct feedback from the install script than from the remove script, which is the one I really need to work. So I’m using the install script for my troubleshooting.

#!/bin/sh
notify-send 'Install Alert' "It is working"

The code works fine on my Parallels Ubuntu VM when I run bash install from a directory with that file in it, but when I try to install the snap on the same Ubuntu VM I get the error: hooks/install: notify-send: not found. I added libnotify-bin to my build-packages and my stage-packages under the part that represents my python-app code in my snapcraft.yaml to no avail.

I’ve also added every plug under the sun to my install hook in snapcraft.yaml. But that has not helped either. You can probably tell I don’t really know what I’m doing!

Is it possible to make a simple, visible alert from an install (or remove) script? And why is my method failing? What am I not doing correctly?

I suspect notify-send requires access to dbus user session whilst the install hook runs in its own environment as root. AFAIK, hooks are meant to be non interactive for them to be triggered by multiple external events.

I wrote to a text file instead. That provided me with enough information for troubleshooting. Very awkward and cumbersome though! Would be nice if there were an easy way to flash a message or something like that.

#!/bin/sh
echo "Hello message" | tee /home/my-username/snap/my-snap-app/logfile.txt

This is specifically because your hook doesn’t have the right environment variables setup for it to find notify-send, either due to https://bugs.launchpad.net/snapcraft/+bug/1824255 or else something similar.

However @sergiusens is right you should not be coding your hooks to be interactive, as they should be quick running and non-interactive (and indeed snapd will forcibly kill the hook if it takes too long to run IIRC)

Then perhaps the remove hook is not the best place to do what I want to do. My ultimate goal in using the remove hook was to launch a popup with a text box that asked the user why they were uninstalling, and then store the fact of the uninstall, along with the reason for the uninstall that the user typed in, on our remote servers. This is expected behavior with our software on all platforms and users will complain if it isn’t included in Linux.

Could you provide me with a quick summary of how you would think something like this could be implemented? Just something to point me in the right direction? It sounds from your description like the remove hook won’t work for this.

Many thanks!

I guess I would recommend putting this inside a “remove-survey” app in your snap and instruct users to run “your-snap.remove-survey” (or through a GUI app instead perhaps) before uninstalling with snap remove?

Unfortunately that won’t work very well for our use-case. We need the survey to pop up (and the uninstall process to store, at bare minimum, the date-time of the uninstall on our server) regardless of how the user tries to uninstall.

I guess I could probably store the date-time remotely with the remove hook, right? Just send a POST to our server and forget about it. But maybe I won’t be able to get the reason with the remove hook.

Is there a snap-way to make the survey itself programmatically uninstall the snap app when the user completes it? I’m working in python and have had difficulty running subprocess commands which require sudo permissions from inside the app, which would be the only way I know of to uninstall it programmatically.

subprocess.call('sudo snap remove my-snap-app-name', shell=True)

This sounds find for a remove hook, as it’s unlikely to block unless there is no network.

Unfortunately no, it’s not in design for snaps to remove themselves. Additionally, running snap remove will not be allowed anyways, even if the app is able to switch to root or somehow use sudo, as this would allow any snap application to remove other snaps which could be abused.

I’m not sure that we have ever considered your use case in architecting the design of snaps. While there is probably not anything we could do short-term, perhaps someone like @pedronis could think about this use case (a snap wanting to run something interactively right before it is being removed)?

Thanks for the information!

it’s not in design for snaps to remove themselves

I find that rather surprising… Chrome extensions allow for it:

Android has a mechanism for it:
https://stackoverflow.com/questions/9928152/android-application-self-uninstall#answer-9932589

I would have expected snaps to have something…

Either way though, thank you again for the information!

I should have been more specific, it’s not currently within the design, but we could add something for this, we just haven’t encountered this use-case AFAIK. Something else for @pedronis to think about