Skip to content

File getter creates Directory Junction when running on Windows #139

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

Open
apparentlymart opened this issue Dec 13, 2018 · 0 comments
Open

Comments

@apparentlymart
Copy link
Contributor

When the "file" getter is dealing with a local directory reference on a Windows system, it currently creates a directory junction:

// Use mklink to create a junction point
output, err := exec.Command("cmd", "/c", "mklink", "/J", dst, sourcePath).CombinedOutput()
if err != nil {
return fmt.Errorf("failed to run mklink %v %v: %v %q", dst, sourcePath, err, output)
}

I assume this is intended as an analog to creating a symlink on a Unix system, but directory junctions have some behaviors that differ from Unix symlinks, some of which can be harmful when combined with other software.

In particular, Git for Windows currently treats a directory junction as just a normal directory with no special handling at all, meaning that commands like git clean will recurse through the directory junction and delete the files and directories within, effectively destroying the source files that go-getter was asked to fetch. While this could be considered a bug in Git for Windows (discussed extensively in git-for-windows/git#437 with reasonable arguments on all sides), harmful treatments of directory junctions is common in Windows applications for historical reasons and so I think it is pragmatic to avoid using them for go-getter's use-case.

If we think that creating a symlink rather than a copy is the right behavior here then we might consider using NTFS Symbolic Links instead. Some brief research suggests that these have fewer caveats because the legacy Windows filesystem APIs do not present them as directories and so legacy software will not attempt to recurse into them, though I've not verified this behavior directly myself. Symlinks are supported since Windows Vista and Go's os.Symlink function will create them when supported.

We might instead conclude that a deep copy is the better behavior here: it's more consistent with how other getters behave (they create a local copy of something remote such that the local thing can be mutated without affecting the source), but the increased disk usage and time spent copying may be undesirable for some existing go-getter callers.


(This was originally reported in hashicorp/terraform#19628, but Terraform v0.12.0 and later won't be affected by this because Terraform now handles local file references as a special case itself, delegating to go-getter only for remote references.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant