Request for personal-files confinement for k9s + Popeye

Please note that the snap’s $HOME is set to ~/snap/<snap name>/<current snap revision> and snaps are allowed to created any files they desire within this directory, so the use of personal-files here does not seem needed. From https://forum.snapcraft.io/t/the-personal-files-interface/9357: “this interface is typically used to provide read-only access to top-level hidden data directories within a user’s home directory in order to support importing data from existing applications where the snap is the clear owner of the target directory.”

Example text for when the snap wants access but isn’t the clear owner: "This snap is not the clear owner but it does seem clear from the application’s intended usage that the application should have at least read-only access to the directory with auto-connection, so long as the interface reference is clear. Please use the following:

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

It is less clear that write-access is required, and if it is, it should probably be manually connected; with read-only access, the snap can import/sync to its per-snap area and not interfere with the target directory which is more in-line for the use of this interface and is much safer and robust. Can you provide more information?

As for /tmp, yes, there is nothing more you need to do.

@jdstrand Thank you so much for the explanation and example! I’ll switch over to enable personal-files as you’ve described here on the next release for both projects. K9s and Popeye currently only need read access to .kube/config to read Kubernetes clusters information.

What else would you need from me to make sure I can successfully drop the next snaps?

@derailed - there is a voting process for this. Now that you’ve stated you want access to ~/.kube/config. Currently your snap is using:

plugs:
  personal-files:
    read:
    - $HOME/.kube

but you said above that you need $HOME/.kube/config. Would changing the above to use $HOME/.kube/config be sufficient for the application? (I don’t know what else might be in $HOME/.kube).

@derailed - your response is needed to proceed with this request. Thanks

@jdstrand Sorry for the delay and thank you for your reply! I think $HOME/,kube is indeed what we want here as there can be many configs in there that a user may want to choose. These can be set directly via the command line or via $KUBECONFIG env var. Thus $HOME/.kube directory should indeed be accessible for both projects.

Please let me know if you need anything else from me.

Thank you!

+1 to allow use of personal-files with read-only access to $HOME/.kube with the interface reference of ‘kube-config’ for both k9s and popeye.

@derailed - since there is an additional requirement that the interface reference be meaningful to users of your snap, please adjust your snaps to use:

name: ...
plugs:
  kube-config:
    interface: personal-files
    read:
    - $HOME/.kube
apps:
  <cmd>:
    plugs:
    - kube-config
    ...

@reviewers - can some of you vote on these requests?

+1 from me as well with snap using as described in @jdstrand reply above. The kube-config interface is limited to read only to $HOME/.kube for k9s and popeye.

@jdstrand @Igor - Thank you both for looking into it! I do have a question.: I’ve noticed that kubectl snap is using classic confinement. Given K9s and Popeye are is essence using the same configuration do you guys feel that I should be using this confinement instead and force users to specify --classic?

@jdstrand - I’ve just tried to push a new K9s snap based on your recommended snap config updates. Can you please verify my changes to make sure I did this correctly based on your recommendation?

Guessing I’ve missed something here based on the following message:

The Store automatic review failed.
A human will soon review your snap, but if you can’t wait please write in the snapcraft forum asking for the manual review explicitly.
If you need to disable confinement, please consider using devmode, but note that devmode revision will only be allowed to be released in edge and beta channels.
Please check the errors and some hints below:

  • override not found for ‘plugs/kube-config’. Use of the personal-files interface is reserved for vetted publishers. If your snap legitimately requires this access, please make a request in the forum using the ‘store-requests’ category (https://forum.snapcraft.io/c/store-requests), or if you would prefer to keep this private, the ‘sensitive’ category.
  • human review required due to ‘allow-installation’ constraint (bool)

2 votes for, 0 against for granting read-only access to $HOME/.kube with auto-connection for both k9s and pop;eye. This is now live.

@derailed - it didn’t pass automated review for two reasons: 1) the votes hadn’t been tallied and so the request wasn’t processed (I did that just now) and 2) the review-tools need a separate update for the use of ‘kube-config’ since we don’t yet have a way to grant that via snap declaration. I’ve made the change to the review-tools for this, but it isn’t in production yet so they’ll have to be manually approved until it is.

FYI, popeye should be converted too. I see you are trying to have popeye access ~/.k9s. I suggest perhaps instead reorganizing things or using a content interface for this. That isn’t strictly required though since you are the owner of both snaps.

@jdstrand Thank you so much for the update and for your time on this issue! I’ve just corrected and pushed Popeye v0.3.8 but it hangs on the publish since 0.3.0 was never approved and it’s stuck in the queue with no way for me to remove it. Not sure how to proceed here. Can you take a look?

I saw this in the store queue and responded there (you left out ‘interface: personal-files’ with your interface reference).

@jdstrand Thank you so much! Right my bad! Missed a commit. Corrected in Popeye v0.3.9.

@jdstrand Thank you for enabling K9s and Popeye builds! It looks like the snap builds are coming thru now.

K9s snaps can’t still access $HOME/.kube for reading or $HOME/.k9s directory for read/write. Several users are reporting issues with the snap builds. K9s is not able to load/save configuration is $HOME/.k9s. For the .kube dir, setting $KUBECONFIG env var seems to work to locate the .kube dir but this less than ideal. K9s tells user their log files are in /tmp/k9s.log but in reality they land on /tmp/snap.k9s/tmp/… I think the same apply to the user home directory. So the question here what do I need to do to make this work as expected. I am hoping I don’t have to change my code to do anything special when released as a snap. Is this correct?

So at this time, K9s can’t read for $HOME/.kube or read/write to $HOME/.k9s. I am not sure how to best proceed from here… Please advise. Thank you!

For $HOME/.kube, it looks like the snap has everything it needs:

$ sudo snap install k9s
k9s 0.7.9 from Fernand Galiana (derailed) installed

$ snap list k9s
Name  Version  Rev  Tracking  Publisher  Notes
k9s   0.7.9    138  stable    derailed   -

$ snap connections k9s
Interface       Plug             Slot             Notes
home            k9s:home         :home            -
network         k9s:network      :network         -
personal-files  k9s:kube-config  :personal-files  -

and from the apparmor policy in /var/lib/snapd/apparmor/profiles/snap.k9s.k9s:

# Description: Can access specific personal files or directories in the 
# users's home directory.
# This is restricted because it gives file access to arbitrary locations.
owner "@{HOME}/.kube{,/,/**}" rk,

I then verified the policy allows it with:

$ mkdir -p ~/.kube
$ echo "it worked!" > ~/.kube/foo
bash in the snap$ snap run --shell k9s
bash in the snap$ cat "$(getent passwd $USER | cut -d : -f 6)/.kube/foo"
it worked!
$ exit

This seems to be a problem with the snap. Note that the personal-files interface is granting access to the user’s actual home directory on the system. Perhaps the snap is trying to access $HOME which evaluates to ~/snap/k9s/<revision> and ~/snap/k9s/<revision>.kube doesn’t exist? If that is the case, see the getent command above to find the user’s home directory on the system.

For $HOME/.k9s, I actually suspect something similar where there is confusion in the snap about where $HOME/.k9s is (ie ~/.k9s vs ~/snap/k9s/<revision>.k9s. The snap is currently only allowed to use ~/snap/k9s/<revision>.k9s.

@jdstrand Thank you so much for this great analysis!! So there lies the problem. In both K9s and Popeye I am using a standard GO stdlib call to locate the user home dir and the tmp dir. I am guessing Kubernetes does the same to locate the .kube dir. Looking at the GO std lib call to get the user home dir it dives into the current process id struct to extract user info and picks out the user home from the c struct. I’ve cruised over the the kubectl snap and it looks like they are using classic mode probably for this very reason. What would be the process to request classic mode for both K9s and Popeye? I could work thru custom code to assess the user actual home dir while deployed as a snap, but that would prove brittle and less than ideal. Does this make sense or did I miss it? Thank you!!

@jdstrand Any update on this? I think the confinement regarding the $HOME is too strict and not what these tools require. K9s leverages the actual $HOME dir to store artifacts for the tool. Based on your previous comment this sandboxed home will change for every release ie ~/snap/k9s/rev.k9s and hence all K9s artifacts would be lost as the home dir is a moving target and will change on every new updates. Also K9s allows the user to shell out to kubectl which is found by checking user’s $PATH once again using GO std lib calls. This also turns out to be a dud given K9s current confinement. So what can I do to get this story wrapped up and have the K9s snap working correctly? This is slowing my tools adoption due to this currently inadequate confinement. Thank you!!

The snap is allowed to write to ~/snap/k9s/<revision>/* (including .kube) by default and the personal-files interface grants additional access to ~/.kube. If you can’t get your application to prefer one over the other via configuration or code change, simply create a symlink from ~/snap/k9s/<revision>/.kube to ~/.kube. You can create a small wrapper script or adjust your program to do something like:

snap_kube="$HOME/.kube"
myid=$(id -u)
myid_home=$(getent passwd $myid | cut -d : -f 6)
if [ ! -e "$snap_home ]; then
    ln -sf "$myid_home" "$snap_home"
fi

In this manner, whether your application uses getpwent or $HOME, it should work.

@jdstrand Thank you for your input! Still seems less than ideal as the home is now a moving target on each release drop as the symlink will need to change. You did not answer my question regarding classic confinement. My understanding is all these problems will go away if k9s and popeye where to use it. Is this correct? And if so how can I proceed with the request?

Thank you!

This is handled by snapd. The script snippet I gave itself isn’t hardcoding any revisions so you should be ok there too. Also keep in mind that there is a current symlink down in ~/snap/k9s/current if you need it for some reason.