-
Notifications
You must be signed in to change notification settings - Fork 145
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
(SDK-268) Create directory junctions instead of symlinks on windows #192
Conversation
CLA signed by all contributors. |
it looks like the symlink code does error on Windows:
this is running this code against a repo with no .fixtures.yml. Maybe that's a 2.1 vs 2.3 distinction, but that won't save us long-term. |
Hmm, it doesn't error for me on Ruby 2.3, but I am using Puppet 4.10.1 for testing. Will investigate further (it's an easy enough fix to catch the exception above, but i'm curious why it doesn't get raised on my VM) |
I was tracking down why CreateSymbolicLinkW was returning non-zero when failing on one test VM and not a different one (puppetlabs/puppetlabs_spec_helper#192). Turns out CreateSymbolicLinkW returns a `BOOLEAN` (1 byte) rather than a `BOOL` (4 bytes), so I was getting random garbage in the upper 3 bytes and therefore a non-zero result.
Found the cause and it looks like a valid bug in Puppet, so time well spent. |
I was tracking down why CreateSymbolicLinkW was returning non-zero when failing on one test VM and not a different one (puppetlabs/puppetlabs_spec_helper#192). Turns out CreateSymbolicLinkW returns a `BOOLEAN` (1 byte) rather than a `BOOL` (4 bytes), so I was getting random garbage in the upper 3 bytes and therefore a non-zero result.
if is_windows | ||
fail "Cannot symlink on Windows unless using at least Puppet 3.5" if !puppet_symlink_available | ||
Puppet::FileSystem::exist?(target) || Puppet::FileSystem::symlink(source, target) | ||
unless File.symlink(target) |
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.
Did you mean File.symlink?
here?
This may have been fixed in later Ruby versions, but IIRC, symlink support was pretty broken in Ruby on Windows in earlier versions.
- CreateSymbolicLinkW was intermittently returning non-zero on different tests hosts, under similar circumstances. Some discussion in: puppetlabs/puppetlabs_spec_helper#192 - The signature for CreateSymbolicLinkW should return a BOOLEAN (BYTE - aka unsigned char) value not a BOOL (4 byte / 32-bit signed int). Based on the presence of random data in the incorrectly sized return value, the code may behave incorrectly. - Fix the problem by sizing the return value correctly
- CreateSymbolicLinkW was intermittently returning non-zero on different tests hosts, under similar circumstances. Some discussion in: puppetlabs/puppetlabs_spec_helper#192 Note the original PR was wrong and updated in: puppetlabs/puppetlabs_spec_helper@bb46874 - The signature for CreateSymbolicLinkW should return a BOOLEAN (BYTE - aka unsigned char) value not a BOOL (4 byte / 32-bit signed int). Based on the presence of random data in the incorrectly sized return value, the code may behave incorrectly. - Fix the problem by sizing the return value correctly
- CreateSymbolicLinkW was intermittently returning non-zero on different tests hosts, under similar circumstances. Some discussion in: puppetlabs/puppetlabs_spec_helper#192 Note the original PR was wrong and updated in: puppetlabs/puppetlabs_spec_helper@bb46874 - The signature for CreateSymbolicLinkW should return a BOOLEAN (BYTE - aka unsigned char) value not a BOOL (4 byte / 32-bit signed int). Based on the presence of random data in the incorrectly sized return value, the code may behave incorrectly. - Fix the problem by sizing the return value correctly
Expands on the windows symlink functionality by falling back to using directory junctions if
Puppet::FileSystem.symlink
fails to create the symlink (or isn't available). Unlike symlinks, NTFS junctions don't require administrator access 🎉 and provide identical behaviour for our purposes.As
Puppet::FileSystem.symlink
doesn't raise an exception when run as non-administrator, we can just check for the existence of the link target after it (File.symlink?
conveniently returnstrue
for junctions) in order to fall back to using junctions.The win32-dir gem extends
Dir
with acreate_junction
method that we try to use first. If that gem isn't available then we fall back to shelling out tomklink
to create the junction.