Skip to content
This repository has been archived by the owner on Sep 9, 2020. It is now read-only.

internal/fs: don't clone symlinks on windows #781

Merged
merged 2 commits into from
Aug 1, 2017

Conversation

ibrasho
Copy link
Collaborator

@ibrasho ibrasho commented Jun 21, 2017

What does this do / why do we need it?

fs.copyFile calls fs.copySymlink on Windows which fails if the user doesn't have the required permission. This is a very common case since symlinks are used heavily on Windows.

This change renames fs.copySymlink to fs.cloneSymlink to clarify the intent and skips calling it when on Windows to fall back to copying the file content instead.

What should your reviewer look out for in this PR?

Generic review.

Which issue(s) does this PR fix?

Fixes #773

@ibrasho ibrasho force-pushed the fix-symlink-cloning-on-windows branch 2 times, most recently from 1ab4923 to 34d3314 Compare June 21, 2017 20:12
if err = os.Symlink(srcPath, symlinkPath); err != nil {
t.Fatalf("could not create symlink: %v", err)
}
if runtime.GOOS == "window" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"windows"

@sdboyer
Copy link
Member

sdboyer commented Jun 27, 2017

Transforming symlinks into their referent directory and copying them is a pretty drastic change. For some of the uses of this func, it's likely fine. Others might present complications, though.

Could we please enumerate each of the places this logic will be triggered (so, calls from outside the fs package that end up in copyFile()), so that we can develop a clear sense of what all may be impacted by this?

@ibrasho
Copy link
Collaborator Author

ibrasho commented Jun 27, 2017

Just to clarify, we don't transform the symlink into anything.
We merely copy the symlink file content instead of creating a new symlink on Windows. (Which is pretty much how Git for Windows behave when core.symlinks is false). This results in a text file containing the target of the symlink (if it was a POSIX symlink).

If false, symbolic links are checked out as small plain files that contain the link text. - core.symlinks documentation

This renders the symlink useless on Windows. So if a dependency relies on symlinks functioning, something will most likely break and that is the part that really worries me.

@ibrasho
Copy link
Collaborator Author

ibrasho commented Jun 27, 2017

For the record,fs.copyFile can be invoked from outside internal/fs though either fs.RenameWithFallback or fs.CopyDir.

// Creating symlinks on Windows require an additional permission regular
// users aren't granted usually. So we skip cloning the symlink nd copy the
// file content as a fall back instead.
if sym && runtime.GOOS != "windows" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if we were to try it even on windows, and if we encounter the particular error, then fall back to cloning?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should work.

I'm only worried about not having a clear path of execution. The more conditionals paths we have the harder it's to reproduce output or debug strange behavior because the input list grows exponentially.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

of course - more if branches, more cyclomatic complexity. but the side effects here worry me enough that i think it's merited 😄

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@ibrasho ibrasho force-pushed the fix-symlink-cloning-on-windows branch 2 times, most recently from db67dbf to 80ad660 Compare July 21, 2017 02:39
Copy link
Member

@sdboyer sdboyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, the review looked good, but apparently we have test failures 😢

@ibrasho ibrasho force-pushed the fix-symlink-cloning-on-windows branch from d4803f7 to 2ea710d Compare July 23, 2017 20:20
@ibrasho
Copy link
Collaborator Author

ibrasho commented Jul 23, 2017

Fixed tests.

This change updates TestCopyFileSymlink tests and renames copySymlink to
cloneSymlink to clarify the intention.

Fixes golang#773

Signed-off-by: Ibrahim AshShohail <ibra.sho@gmail.com>
@ibrasho ibrasho force-pushed the fix-symlink-cloning-on-windows branch 4 times, most recently from 545881f to 90c2a36 Compare July 24, 2017 06:50
} else if sym {
return cloneSymlink(src, dst)
if err := cloneSymlink(src, dst); err != nil {
if runtime.GOOS == "windows" && strings.HasSuffix(err.Error(), "A required privilege is not held by the client.") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't i18n-friendly. not a blocker, necessarily, but is there any way we could sniff the system actual error type here? obviously that means syscall, so this'd have to be a in a windows-tagged file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Didn't think of that. Updating now.

Copy link
Collaborator Author

@ibrasho ibrasho Jul 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I solved it in an OS-independent way. Let me know if a windows-tagged file is still needed.

Signed-off-by: Ibrahim AshShohail <ibra.sho@gmail.com>
@ibrasho ibrasho force-pushed the fix-symlink-cloning-on-windows branch from fb26cc3 to ced76d2 Compare July 28, 2017 08:34
Copy link
Member

@sdboyer sdboyer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, i think we're good here. thanks for your patience, as always! 🎉

@sdboyer sdboyer merged commit 44a454b into golang:master Aug 1, 2017
@ibrasho ibrasho deleted the fix-symlink-cloning-on-windows branch November 29, 2017 06:18
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Symlink issue on Windows: A required privilege is not held by the client.
3 participants