Request - Interface Personal-files: read-write

@review-team

  • Hi, I’m the developer for warrensbox.
  • For my tfswitch application, I need access for my application to read and write to $HOME/bin

What is tfswitch?
The tfswitch command line tool lets you switch between different versions of terraform.
If you do not have a particular version of terraform installed, tfswitch will download the version you desire.
The installation is minimal and easy.
Once installed, simply select the version you require from the dropdown and start using terraform.

https://tfswitch.warrensbox.com/ for more info.

Why I need access to $HOME/bin/?

  1. tfswitch downloads the terraform binary into $SNAP_USER_COMMON/.terraform.versions
  2. Next tfswitch created a symlink /usr/local/bin/terraform -> $SNAP_USER_COMMON/.terraform.versions but not all users have access to /usr/local/bin/.
  3. So, tfswitch lets users to pass in their custom bin location. For example - $HOME/bin. User would later add $HOME/bin to their $PATH.
  4. For users that install tswitch with snapcraft, even if users are able to pass their own custom bin location ($HOME/bin), snapcraft does not let you create a symlink.

My solution was to use interface: personal-files to read and write to $HOME/bin . That way tfswitch can still create a symlink for users while not being overly obtrusive.

Here the snippet of what I have:

plugs:
 home-bin:
   interface: personal-files
   read:
   - $HOME/bin
   write:
   - $HOME/bin

I appreciate any suggestions. Thank you!

Hi @emitorino,

I was wondering how the snapcraft review process works. I have submitted my proposal. But when and how will I know if this is looked at?

Any reply would most certainly help.

Thank you.

Hey @warrensbox, thanks for your post!

So there is a process involved in reviewing requests, here you can find the details about this specific one (use/auto-connection of interfaces).

You will hear from us soon! Thanks!

1 Like

Hey @warrensbox,

I see you could achieve your needs by plugging personal-files, but it does not look like the correct approach. The personal-files interface, is typically used to provide read-only access to top-level hidden data directories within a user’s real home directory in order to support importing data from existing applications where the snap is the clear owner of the target directory.

Have you explore the possibility of shipping the desired terraform versions into your snap instead? (i.e., add to stage-packages (if needed you can add apt repositories), or even build from source?)

@warrensbox - ping, can you please provide the requested information?

@emitorino suggested shipping the desired terraform versions into your snap instead?

Is there another way?

the $HOME/bin path is fully writable through the normal home plug, there is no need at all to use personal-files since ~/bin is not a hidden dir. just add the home plug to your app …

I will test this out and get back to you shortly

@warrensbox - were you able to get this working? Can you please update this thread with the current status? Thanks.

@alexmurray I am still having issues.
Snap is unable to create a symlink from ~/bin (/home/ubuntu) to /home/ubuntu/snap/tfswitch/common/.terraform.versions/terraform_1.0.4

This is my yaml file: https://github.com/warrensbox/terraform-switcher/blob/master/snapcraft.yaml

$ snap run --shell picviewer
...
$ echo $HOME
/home/ogra/snap/picviewer/17
...

note that ~/bin might not point to where you expect it to point (and that dir might not exist in that path either)

what you could do its to make your app call out to getent like:

$ getent passwd $USER|cut -d: -f6
/home/ogra
$ 

to get the correct path here …

You are right it’s referencing: /home/ubuntu/snap/tfswitch/49

I need to get getent passwd $USER|cut -d: -f6 working with golang. Otherwise I won’t be able to get to the actual ~/bin directory

there is surely a getent implementation for go, the rest is just string parsing …

Wait, this should work right? SNAP_REAL_HOME=/home/ubuntu

It looks like SNAP_REAL_HOME points to the user’s home dir not snap’s home. I’ll give that a shot

@ogra

I tried the method you suggested but snap has no write access to /home/ubuntu/bin (~/bin) .
What I am trying to do is create a symlink /home/ubuntu/bin/terraform -> /home/ubuntu/snap/tfswitch/common/.terraform.versions/terraform_1.0.3
Here’s my syntax:

apps:
  tfswitch:
    command: bin/tfswitch
    plugs:
      - home
      - network
      - network-bind

Here is the connection output:

ubuntu@ip-172-xxxxx:~$ snap connections tfswitch
Interface     Plug                   Slot           Notes
home          tfswitch:home          :home          -
network       tfswitch:network       :network       -
network-bind  tfswitch:network-bind  :network-bind  -

I think this might be a bug in snapd/apparmor - it is specific to creating a symlink in $HOME/bin. Making a symlink elsewhere seems to work just fine.

Access to $HOME/bin is explicitly excluded by the home interface.

2 Likes

Thank you for clarifying this. I wish this was clarified sooner. It would have saved a lot of debugging time

Is it possible you could rely without the home interface and just use personal-files in this instance?

I’m not an expert here, but my assumption would be that an explicit denial is stronger than an explicit allow. Since the denial comes from the home interface itself, if you do without it, then the personal-files interface might work on the basis it’s an explicit allow that’s more specific than the usual base policy.

Obviously this is a solution that I wouldn’t be suggesting for any generic application because it’s cutting you off from the rest of $HOME (apart from $SNAP_USER_COMMON and $SNAP_USER_DATA), but having briefly read your requirements, maybe it’s good enough here?