GLib Error, snap not working anymore

I had a running snap for my program, until I changed confinement and the place where some data is saved. I used to save it in the current directory but since this changes to where the user decides to start the program I decided to save the data file into something more appropriate:

/home/user/.local/share/myapp/file

I asked in askubuntu if I had to use the home plug to achieve this and I was told I didn’t.

But now my snap tries to save all the user home subdirs (downloads, Images, etc) but it’s not allowed and then it crashes with this error:

GLib-GIO-ERROR **: No GSettings schemas are installed on the system
Trace/breakpoint trap (imagem do nĂșcleo gravada)

I’m completely clueless about this error any help wold be welcome.
Thanks

PS. my snapcraft file is here: https://github.com/lapisdecor/bzoing/blob/master/snap/snapcraft.yaml

Interesting. We are in the same :ship:. I started a thread about this issue here.

Thanks for the report, we’re looking into that now.

Typically you must either 1) use the home interface to get access to some parts of the home directory (except for dot files), use 2) XDG_DATA_HOME that is derived from $HOME which snapd changes or 3) use $SNAP_USER_DATA and $SNAP_USER_COMMON where snapd will manage your application’s data across revisions.

I tried building your snap locally with snapcraft cleanbuild, and get a different error on startup:

$ bzoing
could't load task list file
new task id = 0
Monitor thread has started

(bzoing-now:30238): Gtk-CRITICAL **: gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
/snap/bzoing/x1/lib/python3.5/site-packages/bzoing/bzoing.py:81: Warning: invalid (NULL) pointer instance
  appindicator.IndicatorCategory.APPLICATION_STATUS)
/snap/bzoing/x1/lib/python3.5/site-packages/bzoing/bzoing.py:81: Warning: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
  appindicator.IndicatorCategory.APPLICATION_STATUS)

(bzoing-now:30238): Gtk-CRITICAL **: gtk_settings_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
/snap/bzoing/x1/lib/python3.5/site-packages/bzoing/bzoing.py:30: Warning: g_object_get_qdata: assertion 'G_IS_OBJECT (object)' failed
  Gtk.Menu.__init__(self)
Segmentation fault (core dumped)

This was running the snap on 17.10, so I don’t know if that is a related issue or not. The script did symlink and compile the schemas, so that particular part of the script seems to be functioning correctly.

Looking through the glib NEWS file, I did stumble on this though:

Overview of changes in GLib 2.53.2
==================================
...
* GSettings now consider XDG_DATA_HOME in addition to XDG_DATA_DIRS.
...

However, Ubuntu 16.04 shipped with an older version of GLib. As one of the cleanups in my PR, I removed $XDG_DATA_HOME from $XDG_DATA_DIRS on the basis that the spec said having it there was superfluous. I suspect adding it back will fix the problem you’re seeing, so I’ll put together a followup PR.

I think I missed this when testing apps using the gnome-platform snap because they ship a newer GLib.

I confirm that I was testing the snap on Ubuntu 16.04.

I’ve put up a new pull request that should fix this if I’ve correctly identified the root cause:

The easiest way to test this would probably be to run snapcraft prime, then manually make the change from the PR to prime/bin/desktop-launch and finish building the package. If that works for you, we’ll get the change merged ASAP.

@jamesh we’ve just come up against this. Tried your suggestion and PR and it works perfectly. Thank you so much!

1 Like

My program now works on Ubuntu 16.04. The snap still tries to create default user directories when it starts but after, it runs well. I’ve tested it on Ubuntu 17.10 and it gives the segmentation fault you showed. I wonder if I have to use the desktop-gnome-platform part to avoid this error on 17.10.

Note that if you’re hardcoding ~/.local/share as the directory under which you store your data you’re doing it wrong even without considering snaps. ~/.local/share is the default value of XDG_DATA_HOME; you’re supposed to check that first as it’s possible to have it pointing elsewhere (and I know people that do).

There’s not much we can do about that use case though: a sandboxed app is only going to be able to access those directories the AppArmor profile allows, and that profile can’t take per-user (or more accurately per-process) environment variables into account.

Maybe this is something we could address in the future via user mounts (e.g. make sure $XDG_DATA_HOME is mounted at ~/.local/share inside the sandbox), but for now I think having a 99% solution is useful.

my point was more that if the app is doing the right thing, setting XDG_DATA_HOME appropriately will have it read from inside the sandbox.

I’m only doing:

share_dir = os.path.expanduser('~/.local/share/myapp')
if not os.path.isdir(share_dir):
os.makedirs(share_dir)

is this acceptable? If not, can you show me example code on what I should be doing?

from xdg.BaseDirectory import save_data_path
share_dir = save_data_path("myapp")

that’ll ensure it looks at the right env vars, fallbacks to the default, and creates it if missing.

Thanks @chipaca, this is cool! :slight_smile: