diff options
author | Serdar Sutay <serdar@opscode.com> | 2014-12-15 09:21:12 -0800 |
---|---|---|
committer | Serdar Sutay <serdar@opscode.com> | 2014-12-15 09:21:12 -0800 |
commit | ed93756f31aa062067bfc1ca5f6c67fb467c637a (patch) | |
tree | 9a829d349889084818658792a6c7683d9876efe0 | |
parent | 98ffba31bb92a71b51681d3fabf03f5c098c79d5 (diff) | |
parent | f2f98664fe89aab08aebb9b9d2ba5e224e75c4d3 (diff) | |
download | chef-ed93756f31aa062067bfc1ca5f6c67fb467c637a.tar.gz |
Merge pull request #2623 from opscode/sersut/revert-1901
Preserve relative paths in Link resource
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | lib/chef/provider/link.rb | 2 | ||||
-rw-r--r-- | lib/chef/win32/api/file.rb | 20 | ||||
-rw-r--r-- | spec/functional/resource/link_spec.rb | 32 | ||||
-rw-r--r-- | spec/unit/provider/link_spec.rb | 10 |
5 files changed, 40 insertions, 25 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index ba22906a20..8027055203 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ * [Issue 2578](https://github.com/opscode/chef/issues/2578) Check that `installed` is not empty for `keg_only` formula in Homebrew provider. * [Issue 2609](https://github.com/opscode/chef/issues/2609) Resolve the circular dependency between ProviderResolver and Resource. * [Issue 2596](https://github.com/opscode/chef/issues/2596) Fix nodes not writing to disk +* [Issue 2580](https://github.com/opscode/chef/issues/2580) Make sure the relative paths are preserved when using link resource. ## 12.0.1 diff --git a/lib/chef/provider/link.rb b/lib/chef/provider/link.rb index 417d6a21b0..c811c13cdf 100644 --- a/lib/chef/provider/link.rb +++ b/lib/chef/provider/link.rb @@ -86,7 +86,7 @@ class Chef end def canonicalize(path) - Chef::Util::PathHelper.canonical_path(path) + Chef::Platform.windows? ? path.gsub('/', '\\') : path end def action_create diff --git a/lib/chef/win32/api/file.rb b/lib/chef/win32/api/file.rb index da9713e119..86b2b942c2 100644 --- a/lib/chef/win32/api/file.rb +++ b/lib/chef/win32/api/file.rb @@ -457,11 +457,25 @@ BOOL WINAPI DeviceIoControl( # takes the given path pre-pends "\\?\" and # UTF-16LE encodes it. Used to prepare paths # to be passed to the *W vesion of WinAPI File - # functions + # functions. + # This function is used by the "Link" resources where we need + # preserve relative paths because symbolic links can actually + # point to a relative path (relative to the link itself). def encode_path(path) + (path_prepender << path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR)).to_wstring + end + + # Expands the path, prepends "\\?\" and UTF-16LE encodes it. + # This function is used by the "File" resources where we need + # convert relative paths to fully qualified paths. + def canonical_encode_path(path) Chef::Util::PathHelper.canonical_path(path).to_wstring end + def path_prepender + "\\\\?\\" + end + # retrieves a file search handle and passes it # to +&block+ along with the find_data. also # ensures the handle is closed on exit of the block @@ -474,7 +488,7 @@ BOOL WINAPI DeviceIoControl( # broader fix to map all the paths starting with "/" to # SYSTEM_DRIVE on windows. path = ::File.expand_path(path) if path.start_with? "/" - path = encode_path(path) + path = canonical_encode_path(path) find_data = WIN32_FIND_DATA.new handle = FindFirstFileW(path, find_data) if handle == INVALID_HANDLE_VALUE @@ -491,7 +505,7 @@ BOOL WINAPI DeviceIoControl( # ensures the handle is closed on exit of the block def file_handle(path, &block) begin - path = encode_path(path) + path = canonical_encode_path(path) handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, nil) diff --git a/spec/functional/resource/link_spec.rb b/spec/functional/resource/link_spec.rb index b4c6412e5d..d39a0c2ef6 100644 --- a/spec/functional/resource/link_spec.rb +++ b/spec/functional/resource/link_spec.rb @@ -72,8 +72,8 @@ describe Chef::Resource::Link do end end - def paths_eql?(path1, path2) - Chef::Util::PathHelper.paths_eql?(path1, path2) + def canonicalize(path) + windows? ? path.gsub('/', '\\') : path end def symlink(a, b) @@ -180,7 +180,7 @@ describe Chef::Resource::Link do it 'links to the target file' do expect(symlink?(target_file)).to be_truthy - expect(paths_eql?(readlink(target_file), to)).to be_truthy + expect(readlink(target_file)).to eq(canonicalize(to)) end it 'marks the resource updated' do expect(resource).to be_updated @@ -201,7 +201,7 @@ describe Chef::Resource::Link do it 'leaves the file linked' do expect(symlink?(target_file)).to be_truthy - expect(paths_eql?(readlink(target_file), to)).to be_truthy + expect(readlink(target_file)).to eq(canonicalize(to)) end it 'does not mark the resource updated' do expect(resource).not_to be_updated @@ -279,7 +279,7 @@ describe Chef::Resource::Link do before(:each) do symlink(to, target_file) expect(symlink?(target_file)).to be_truthy - expect(paths_eql?(readlink(target_file), to)).to be_truthy + expect(readlink(target_file)).to eq(canonicalize(to)) end include_context 'create symbolic link is noop' include_context 'delete succeeds' @@ -294,7 +294,7 @@ describe Chef::Resource::Link do File.open(@other_target, 'w') { |file| file.write('eek') } symlink(@other_target, target_file) expect(symlink?(target_file)).to be_truthy - expect(paths_eql?(readlink(target_file), @other_target)).to be_truthy + expect(readlink(target_file)).to eq(canonicalize(@other_target)) end after(:each) do File.delete(@other_target) @@ -311,7 +311,7 @@ describe Chef::Resource::Link do nonexistent = File.join(test_file_dir, make_tmpname('nonexistent_spec')) symlink(nonexistent, target_file) expect(symlink?(target_file)).to be_truthy - expect(paths_eql?(readlink(target_file), nonexistent)).to be_truthy + expect(readlink(target_file)).to eq(canonicalize(nonexistent)) end include_context 'create symbolic link succeeds' include_context 'delete succeeds' @@ -393,7 +393,7 @@ describe Chef::Resource::Link do File.open(@other_target, "w") { |file| file.write("eek") } symlink(@other_target, to) expect(symlink?(to)).to be_truthy - expect(paths_eql?(readlink(to), @other_target)).to be_truthy + expect(readlink(to)).to eq(canonicalize(@other_target)) end after(:each) do File.delete(@other_target) @@ -408,7 +408,7 @@ describe Chef::Resource::Link do @other_target = File.join(test_file_dir, make_tmpname("other_spec")) symlink(@other_target, to) expect(symlink?(to)).to be_truthy - expect(paths_eql?(readlink(to), @other_target)).to be_truthy + expect(readlink(to)).to eq(canonicalize(@other_target)) end context 'and the link does not yet exist' do include_context 'create symbolic link succeeds' @@ -441,7 +441,7 @@ describe Chef::Resource::Link do before(:each) do symlink(to, target_file) expect(symlink?(target_file)).to be_truthy - expect(paths_eql?(readlink(target_file), to)).to be_truthy + expect(readlink(target_file)).to eq(canonicalize(to)) end include_context 'create symbolic link is noop' include_context 'delete succeeds' @@ -450,7 +450,7 @@ describe Chef::Resource::Link do before(:each) do symlink(absolute_to, target_file) expect(symlink?(target_file)).to be_truthy - expect(paths_eql?(readlink(target_file), absolute_to)).to be_truthy + expect(readlink(target_file)).to eq(canonicalize(absolute_to)) end include_context 'create symbolic link succeeds' include_context 'delete succeeds' @@ -478,7 +478,7 @@ describe Chef::Resource::Link do before(:each) do symlink(to, target_file) expect(symlink?(target_file)).to be_truthy - expect(paths_eql?(readlink(target_file), to)).to be_truthy + expect(readlink(target_file)).to eq(canonicalize(to)) end include_context 'create hard link succeeds' it_behaves_like 'delete errors out' @@ -552,7 +552,7 @@ describe Chef::Resource::Link do File.open(@other_target, "w") { |file| file.write("eek") } symlink(@other_target, to) expect(symlink?(to)).to be_truthy - expect(paths_eql?(readlink(to), @other_target)).to be_truthy + expect(readlink(to)).to eq(canonicalize(@other_target)) end after(:each) do File.delete(@other_target) @@ -564,7 +564,7 @@ describe Chef::Resource::Link do # OS X gets angry about this sort of link. Bug in OS X, IMO. pending('OS X/FreeBSD/AIX symlink? and readlink working on hard links to symlinks') if (os_x? or freebsd? or aix?) expect(symlink?(target_file)).to be_truthy - expect(paths_eql?(readlink(target_file), @other_target)).to be_truthy + expect(readlink(target_file)).to eq(canonicalize(@other_target)) end include_context 'delete is noop' end @@ -574,7 +574,7 @@ describe Chef::Resource::Link do @other_target = File.join(test_file_dir, make_tmpname("other_spec")) symlink(@other_target, to) expect(symlink?(to)).to be_truthy - expect(paths_eql?(readlink(to), @other_target)).to be_truthy + expect(readlink(to)).to eq(canonicalize(@other_target)) end context 'and the link does not yet exist' do it 'links to the target file' do @@ -587,7 +587,7 @@ describe Chef::Resource::Link do expect(File.exists?(target_file)).to be_falsey end expect(symlink?(target_file)).to be_truthy - expect(paths_eql?(readlink(target_file), @other_target)).to be_truthy + expect(readlink(target_file)).to eq(canonicalize(@other_target)) end include_context 'delete is noop' end diff --git a/spec/unit/provider/link_spec.rb b/spec/unit/provider/link_spec.rb index ab5b439eac..0f95ce997e 100644 --- a/spec/unit/provider/link_spec.rb +++ b/spec/unit/provider/link_spec.rb @@ -38,8 +38,8 @@ describe Chef::Resource::Link, :not_supported_on_win2k3 do result end - def paths_eql?(path1, path2) - Chef::Util::PathHelper.paths_eql?(path1, path2) + def canonicalize(path) + Chef::Platform.windows? ? path.gsub('/', '\\') : path end describe "when the target is a symlink" do @@ -68,7 +68,7 @@ describe Chef::Resource::Link, :not_supported_on_win2k3 do expect(provider.current_resource.link_type).to eq(:symbolic) end it "should update the source of the existing link with the links target" do - expect(paths_eql?(provider.current_resource.to, "#{CHEF_SPEC_DATA}/fofile")).to be_truthy + expect(provider.current_resource.to).to eq(canonicalize("#{CHEF_SPEC_DATA}/fofile")) end it "should set the owner" do expect(provider.current_resource.owner).to eq(501) @@ -110,7 +110,7 @@ describe Chef::Resource::Link, :not_supported_on_win2k3 do expect(provider.current_resource.link_type).to eq(:symbolic) end it "should update the source of the existing link to the link's target" do - expect(paths_eql?(provider.current_resource.to, "#{CHEF_SPEC_DATA}/fofile")).to be_truthy + expect(provider.current_resource.to).to eq(canonicalize("#{CHEF_SPEC_DATA}/fofile")) end it "should not set the owner" do expect(provider.current_resource.owner).to be_nil @@ -221,7 +221,7 @@ describe Chef::Resource::Link, :not_supported_on_win2k3 do expect(provider.current_resource.link_type).to eq(:hard) end it "should update the source of the existing link to the link's target" do - expect(paths_eql?(provider.current_resource.to, "#{CHEF_SPEC_DATA}/fofile")).to be_truthy + expect(provider.current_resource.to).to eq(canonicalize("#{CHEF_SPEC_DATA}/fofile")) end it "should not set the owner" do expect(provider.current_resource.owner).to eq(nil) |