Refreshing gimp snap failed: cannot create symlink in "/etc/gimp": existing file in the way

I just ran snap refresh, and a new revision of the gimp snap (on the stable channel) was downloaded, but when installing it failed with the following error:

osomon@bribon:~$ snap refresh
erreur : cannot perform the following tasks:
- Lancer le post-rafraîchissement du point d'accroche du snap "gimp" si existant (run hook "post-refresh": 
-----
cannot update snap namespace: cannot create symlink in "/etc/gimp": existing file in the way
snap-update-ns failed with code 1: File exists
-----)

Is this a known issue (with this specific snap or with snapd)?

2 Likes

@zyga - have you seen this before?

1 Like

I’ve seen various times mount-namespace collisions. I’ve been unable to determine exactly what the causes are or how to reliably reproduce them. It can affect any snap using layouts seemingly at random.

Most times you can get past the conflict by running /usr/lib/snapd/snap-discard-ns $SNAPNAME

The gimp definition for layouts is:

layout:
  /etc/gimp:
    symlink: $SNAP/etc/gimp
  /etc/ld.so.cache:
    bind-file: $SNAP_DATA/etc/ld.so.cache
  /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/babl-0.1:
    symlink: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/babl-0.1
  /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/gegl-0.4:
    symlink: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/gegl-0.4
  /usr/lib/gimp:
    symlink: $SNAP/usr/lib/gimp
  /usr/lib/python2.7:
    symlink: $SNAP/usr/lib/python2.7
  /usr/lib/$SNAPCRAFT_ARCH_TRIPLET/gvfs:
    symlink: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/gvfs
  /usr/share/color:
    symlink: $SNAP/usr/share/color
  /usr/share/ghostscript:
    symlink: $SNAP/usr/share/ghostscript
  /usr/share/gimp:
    symlink: $SNAP/usr/share/gimp
  /usr/share/mypaint-data:
    symlink: $SNAP/usr/share/mypaint-data

Do you have an /etc/gimp directory or file on your host (i.e. outside of the snap)?

Yes I did. It was leftover configuration from the gimp-data deb package. I purged it, and refreshing the gimp snap worked.

can we get snapd to switch to a bind-style mount if it can’t create a symlink? I still think it’s weird that as a snapcrafter we need to guess whether we need a symlink or a bind-file or a bind. It would be much simpler to just have

layout:
  fake-location: real-location

instead of

layout:
  fake-location:
    symlink: real-location
  # OR
  fake-location2:
    bind: real-location
  # OR
  fake-location3:
    bind-file: real-location

This is unfortunately an expected flaw with layouts, because currently (quoting the docs here :wink:):

Layouts cannot replace an existing but incompatible filesystem object

so if /etc/gimp is not already a symlink, snapd currently can’t replace that with anything else.

This is an acknowledged shortcoming we wish to solve someday, however before we go about adding additional features like this, we have some other bugs with layouts we need to fix. We are optimizing developer time for correctness first.

I’m not sure if we can make yaml changes at this point or not, since we would still need to support the current structure. As to your point about guessing which one to use, the way we hope to solve this is to just create a mimic tmpfs every time we need to replace something with a layout, which would then easily allow us to replace unlike filesystem objects and so then symlinks and bind mounts would always work everywhere and it would just be a matter of preference as to your snap which one to use.

1 Like

for changing the yaml syntax, which I appreciate would need developer time to implement, I think it should be possible to detect whether each layout value is a string or an object and choose different implementation for each - string being my new thought above, and object being the current way it works now.

I also have this problem. How do I fix it?

I think I’ve only installed GiMP via snap.

As suggested, I ran sudo /usr/lib/snapd/snap-discard-ns gimp

Then
snap refresh

It started to download and install GIMP. Then gave this error message

error: cannot perform the following tasks:
- Run post-refresh hook of "gimp" snap if present (run hook "post-refresh": 
-----
cannot update snap namespace: cannot create symlink in "/etc/gimp": existing file in the way
snap-update-ns failed with code 1: File exists
-----)

If I try to run GIMP, I get this message

ln: failed to create symbolic link '/home/edent/snap/gimp/227/.config/gtk-2.0/gtkfilechooser.ini': File exists
Gtk-Message: 17:17:57.501: Failed to load module "appmenu-gtk-module"
Gtk-Message: 17:17:57.501: Failed to load module "gail"
Gtk-Message: 17:17:57.502: Failed to load module "atk-bridge"
Gtk-Message: 17:17:57.502: Failed to load module "canberra-gtk-module"
/snap/gimp/227/usr/bin/gimp: Gimp-Widgets-WARNING: parse_iso_codes: error parsing '/build/gimp/parts/gimp/install/usr/share/xml/iso-codes/iso_639.xml': No such file or directory

check if you have any files or folders at /etc/gimp. I’m going to swap the configuration but in the meantime moving /etc/gimp out of the way should let you continue…

I’ve also rolled-back the broken revision in the store until the builder has built the fixed version :slight_smile:

Try this:

sudo apt purge gimp-data

This is, most likely, a known issue. I’ll investigate it quickly to double check and reference the relevant bug reports.

This is indeed a known limitation.

Quoting from Snap layouts

Incompatible existing file, directory or symbolic link

Layouts cannot replace an existing but incompatible filesystem object. This means, for example, that files cannot replace directories or symbolic links, files cannot replace a directory, and existing symbolic links cannot be redirected to a new target. You can, however, replace a directory with another directory.

While this limitation is unfortunate, especially considering /etc which can have a multitude of unknown files. I think this, along with one more bug, should be lifted with a rumoured rewrite of the algorithm powering snap-update-ns.

When I was testing this, the snap was updated to use a bind mount layout for /etc/gimp so the presence of a /etc/gimp directory did not pose a problem.