-
Notifications
You must be signed in to change notification settings - Fork 561
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enabled symbolic link following in mounts #495
Conversation
02df955
to
e73be4e
Compare
Resolves #498 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, this is great! Now I can remove all my extra mounts for symlink targets from override.yaml
again. 😄
Leaving the merging to @AkihiroSuda in case there are any security concerns, but I can't think of any myself.
Can we have a test to ensure that the symlink is resolved inside the guest VFS, not in the host VFS? Lines 149 to 163 in 03b4ac1
|
I guess we can have a test, but it really would be testing But I just realized another potential issue: Since this option "hides" symlinks from the guest, it means certain commands (e.g $ ls -lR loop
total 0
-rw-r--r-- 1 jan staff 0 27 Dec 01:29 file
lrwxr-xr-x 1 jan staff 1 27 Dec 01:30 loop -> .
$ lima ls -lR loop
loop:
total 4
-rw-r--r-- 1 jan dialout 0 Dec 27 09:29 file
drwxr-xr-x 1 jan dialout 128 Dec 27 09:30 loop
loop/loop:
total 4
-rw-r--r-- 1 jan dialout 0 Dec 27 09:29 file
drwxr-xr-x 1 jan dialout 128 Dec 27 09:30 loop
[...]
loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop:
ls: cannot access 'loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop': Operation not permitted
total 0
-rw-r--r-- 1 jan dialout 0 Dec 27 09:29 file
?????????? ? ? ? ? ? loop
$ find loop -name file
loop/file
$ lima find loop -name file
loop/file
loop/loop/file
loop/loop/loop/file
loop/loop/loop/loop/file
loop/loop/loop/loop/loop/file
loop/loop/loop/loop/loop/loop/file
[...]
find: ‘loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop/loop’: Operation not permitted I still think this is fine, but maybe needs to be documented or configurable. |
Doesn't seem fine to me. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, but #495 (comment)
Do we really need the extra |
SSHFS will be abolished as soon as the 9p patch gets merged. So I'd prefer to have the |
Well, either we can support it with 9p, or if we can't, we "undocument" the field and throw an error during validation if it is still set to I somewhat dislike leaking implementation details to the names of user settings. Furthermore I dislike adding additional struct levels with just a single field in them. But if you feel strongly about this, then that's ok too... |
c309350
to
e4741a8
Compare
@jandubois / @AkihiroSuda: I've made the changes to allow for this to be configurable via a new SSHFS->follow_symlinks parameter in the mount section of the yaml file. If you would like an automated test for this, let me know which test(s) files you think would be most applicable to update. For example: |
@AkihiroSuda, perhaps I've mistaken the comment. But Reference: |
pkg/limayaml/default.yaml
Outdated
@@ -42,8 +42,15 @@ mounts: | |||
# CAUTION: `writable` SHOULD be false for the home directory. | |||
# Setting `writable` to true is possible, but untested and dangerous. | |||
writable: false | |||
# SSHFS has an optional flag called 'follow_symlinks'. This allows mounts | |||
# to be properly resolved in the guest os and allow for access to the | |||
# contents in the symlnked folder. This defaults to false if not supplied. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a note that explains that followSymlinks
does not map the symlink end-points into the guest, but makes them look like regular files/directories. With the option enabled, there are no symlinks in the mounted tree, and symlinks in the tree cannot be created from the guest.
It turns out that with jan@lima-default:/Users/jan$ ln -s .lima lima
ln: failed to create symbolic link 'lima': Input/output error This is a strong argument against making this enabled by default, and makes me question if this change is desirable after all. It is only helpful for symlinks that point outside the mapped tree, so maybe adding the symlink targets explicitly to the mounts is a better option (which was one of the reasons I wanted the |
I can make that change to the default.yaml to ensure that in the examples it's default off. That said, I think this feature is very useful. At my company, we have people wanting files to be specified from any number of locations. To automate this, we have a specific source folder that they can just add a symbolic link so that nothing needs to be edited with lima. This also meeds nothing to restart or to reload, it just works. TLDR; |
@jandubois, regarding creating symbolic links in the guest. One can actually do this, but I think it would probably make more sense to actually do this on the host side of things as it would be more sticky. that said, I did this with the default config with no changes. Guest VM - Readonly: Rightfully fails because mounted as read-only by default
Guest VM - Readonly: Creating a symlink outside a mounted location works
Gest VM - Writable: Creating symlink works since mount is read writable
Host - With the execution of the last "Guest VM" will show that the symbolic link exists on the host machine
|
Interesting, it does actually work. I wonder why I get an error though: $ lima
jan@lima-default:/Users/jan$ ln -s .lima lima; echo $?
ln: failed to create symbolic link 'lima/.lima': Operation not permitted
1
jan@lima-default:/Users/jan$ ls -ld lima
drwx------ 1 jan dialout 288 Dec 27 22:15 lima
jan@lima-default:/Users/jan$ rm lima
rm: cannot remove 'lima': Is a directory And of course, even though you can create the symlink, you cannot delete it, because inside the guest it is a directory, not a symlink. This kind of violates the lima premise that the environment on the guest and the host behave as similar as possible (so it looks like you run I'm not opposed to keeping the feature, I'm just saying it should not be the default in the builtin template anymore. And the caveats need to be clearly documented. Also remember that @AkihiroSuda said that this feature may not be supportable when we switch from |
pkg/limayaml/default.yaml
Outdated
@@ -45,6 +45,8 @@ mounts: | |||
# SSHFS has an optional flag called 'follow_symlinks'. This allows mounts | |||
# to be properly resolved in the guest os and allow for access to the | |||
# contents in the symlnked folder. This defaults to false if not supplied. | |||
# As a result, symlinked folders on the Host system will look and feel like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is both files and directories, not just directories. Please also mention that symlinks to directories cannot be deleted inside the guest.
Please squash commits, to eliminate the refactoring from the history! |
pkg/limayaml/defaults.go
Outdated
@@ -299,6 +299,7 @@ func FillDefault(y, d, o *LimaYAML, filePath string) { | |||
for _, mount := range append(append(d.Mounts, y.Mounts...), o.Mounts...) { | |||
if i, ok := location[mount.Location]; ok { | |||
mounts[i].Writable = mount.Writable | |||
mounts[i].SSHFS = mount.SSHFS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unfortunately not enough. Both mount.Writable
and mount.SSHFS.ForwardSymlinks
need to become pointers to booleans, so they can be independently defaulted/overridden. This should also be added to the defaults_test.go
to make sure it works.
Not making mount.Writable
a pointer to start with was a mistake already, but it becomes more obvious now that we have multiple properties on a mount.
Out of curiosity, why don't you just let Github handle this for you? Instead of |
pkg/hostagent/mount.go
Outdated
@@ -40,16 +40,21 @@ func (a *HostAgent) setupMount(ctx context.Context, m limayaml.Mount) (*mount, e | |||
if err := os.MkdirAll(expanded, 0755); err != nil { | |||
return nil, err | |||
} | |||
// NOTE: allow_other requires "user_allow_other" in /etc/fuse.conf | |||
ssh_options := "allow_other" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- s/ssh/sshfs/
- We use camelCase, not snake_case
Because it feels kind of wrong to attach a DCO sign-off to a merge-commit that has not been created directly by the author. Maybe it is fine; idk what kind of policy the big foundations (Linux Foundations, CNCF) have. Letting the author squash is keeping it on the safe side. The other reason though is that not all commits should be squashed for every PR. We want to squash false starts and refactoring, but not commits that have been intentionally created to address different aspects of the PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The merging of followSymlinks
does not work correctly (and has no tests).
I can make the updates for Mount#Writable, but I figured that probably warrants its own PR.
Yes, logically it should be a separate PR, but since it is closely related to how followSymlinks
is handled, I wouldn't object to including it here. Your choice!
pkg/limayaml/defaults.go
Outdated
if i, ok := location[mount.Location]; ok { | ||
mounts[i].SSHFS.FollowSymlinks = mount.SSHFS.FollowSymlinks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You only overwrite if the pointer is not nil
:
mounts[i].SSHFS.FollowSymlinks = mount.SSHFS.FollowSymlinks | |
if mount.SSHFS.FollowSymlinks != nil { | |
mounts[i].SSHFS.FollowSymlinks = mount.SSHFS.FollowSymlinks | |
} |
pkg/limayaml/defaults.go
Outdated
@@ -297,7 +297,11 @@ func FillDefault(y, d, o *LimaYAML, filePath string) { | |||
mounts := make([]Mount, 0, len(d.Mounts)+len(y.Mounts)+len(o.Mounts)) | |||
location := make(map[string]int) | |||
for _, mount := range append(append(d.Mounts, y.Mounts...), o.Mounts...) { | |||
if mount.SSHFS.FollowSymlinks == nil { | |||
mount.SSHFS.FollowSymlinks = pointer.Bool(false) | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting the default cannot happen here; you need to merge from all the sources first, and then have another loop over the final result, filling in the missing values with their defaults. Look at how the networks
are being merged, and copy that mechanism.
Adding test cases for this to defaults_test.go
would help to show that the current logic does not work as expected.
bb9bcde
to
b663c48
Compare
@jandubois / @AkihiroSuda: I think all your concerns should now be addressed in the latest iteration. |
@jandubois, I've got the refactored Writable ready to be turned into a PR as soon as this one goes out. :) |
0dac92a
to
b709cb9
Compare
Signed-off-by: Jason W. Ehrlich <jwehrlich@outlook.com>
b709cb9
to
3fa3af4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed sshOptions
to sshfsOptions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, LGTM now. Waiting for @AkihiroSuda review before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
This update will allow for symbolic links to be followed in mounts in sshfs.