Need advice for redirecting directories inside $HOME

Hi there, I need some advice on modifying a snap here’s the scenario:

Normally, inside ~/.config/accs is a file this application (VLC) needs access to. I’ve granted access to this directory using the personal-files interface and this has worked fine, the application has permission to see the file now:

plugs:
  dot-config-aacs:
    interface: personal-files
    read:
    - $HOME/.config/aacs

and later…

  plugs:
    - dot-config-aacs

However, checking env inside the snap shell, I can see the $HOME variable inside the snap is redirected to ~/snap/vlc/3078. So VLC ends up being redirected to looking inside of ~/snap/vlc/3078/.config/aacs.

So my next plan was to use layout to symlink the real ~/.config/aacs directory into the snap one like this:

layout:
  $HOME/.config/aacs:
    symlink: $SNAP_USER_DATA/.config/aacs

But… this doesn’t work. Snap complains I’m creating a top-level directory and the documentation says you can’t use layout inside of $HOME so I’m not sure this will work anyway:

Snapping...
Sorry, an error occurred in Snapcraft:
Failed to create snap, snap command failed:
stdout:

stderr:
error: cannot pack "/builds/0/project-0/extras/package/snap/prime": cannot validate snap "vlc": layout "$HOME/.config/aacs" defines a new top-level directory "/.config"

Traceback (most recent call last):
  File "/snap/snapcraft/current/bin/snapcraft", line 33, in <module>
    sys.exit(load_entry_point('snapcraft==5.0', 'console_scripts', 'snapcraft')())
  File "/snap/snapcraft/current/lib/python3.6/site-packages/click/core.py", line 1137, in __call__
    return self.main(*args, **kwargs)
  File "/snap/snapcraft/current/lib/python3.6/site-packages/click/core.py", line 1062, in main
    rv = self.invoke(ctx)
  File "/snap/snapcraft/current/lib/python3.6/site-packages/click/core.py", line 1668, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/snap/snapcraft/current/lib/python3.6/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/snap/snapcraft/current/lib/python3.6/site-packages/click/core.py", line 763, in invoke
    return __callback(*args, **kwargs)
  File "/snap/snapcraft/current/lib/python3.6/site-packages/snapcraft/cli/lifecycle.py", line 387, in snap
    _execute(steps.PRIME, parts=tuple(), pack_project=True, output=output, **kwargs)
  File "/snap/snapcraft/current/lib/python3.6/site-packages/snapcraft/cli/lifecycle.py", line 107, in _execute
    output=output,
  File "/snap/snapcraft/current/lib/python3.6/site-packages/snapcraft/cli/lifecycle.py", line 253, in _pack
    snap_filename = _run_pack(command)
  File "/snap/snapcraft/current/lib/python3.6/site-packages/snapcraft/cli/lifecycle.py", line 199, in _run_pack
    f"Failed to create snap, snap command failed:\nstdout:\n{stdout}\nstderr:\n{stderr}"
RuntimeError: Failed to create snap, snap command failed:
stdout:

stderr:
error: cannot pack "/builds/0/project-0/extras/package/snap/prime": cannot validate snap "vlc": layout "$HOME/.config/aacs" defines a new top-level directory "/.config"

You can find the traceback in file '/tmp/tmphbh_3wgz/trace.txt'.
make: *** [package.mak:3: snap] Error 1

I don’t necessarily want to remove the entire $HOME redirection but do I have any other options?

Turns out the VLC Snap already runs a shell-script as a start command, so I just added a symlink command to that script:

# Link the aacs directory from $HOME
if [ ! -L "$HOME/.config/aacs" ]; then
    ln -s $SNAP_REAL_HOME/.config/aacs $HOME/.config/aacs
fi

The snapcraft.yaml looks like this:

apps:
  vlc:
    desktop: usr/share/applications/vlc.desktop
    command: bin/desktop-launch $SNAP/bin/vlc-snap-wrapper.sh

Good idea, but wrong tool :wink:

what you want is to use a hook

you can try to either use a connect hook for the personal-files interface you created and have it create the symlink when the connection appears (i.e. when the dir becomes readable) or you can request auto-connection for the interface and simply use an install hook …

(and indeed a startup wrapper script is always a last resort fallback as you found yourself already :slight_smile: )

Thanks I’ll give it a go :+1:

I’ve given hooks a go but I’m not sure it can do what I need. The symlink goes into the running user’s $HOME, but the hook seems to run in the context of root and doesn’t have the same $HOME and $SNAP_REAL_HOME variables.

I’m also not sure what to do about other users, if one person connects the plug then it will make the link for themselves, but if another user logs in and tries to open the application it won’t have the symlink even though the plug is still connected.

If I’ve missed any features that can do this let me know please :+1:

Hmm, no, you are indeed correct, I’m just packaging too many daemons lately, in an end-user context hooks are indeed not useful and a command-chain or wrapper script are the best option, sorry for causing confusion

no worries it was a good learning experience :smiley: Thanks for your help.

1 Like