summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerdar Sutay <serdar@opscode.com>2014-12-15 09:21:12 -0800
committerSerdar Sutay <serdar@opscode.com>2014-12-15 11:01:14 -0800
commit8a2a34a5c25666d55da7dfbb2014b626d7a87017 (patch)
tree9bb8cc2b0b4866de71bd1c7e203ca3236632bf82
parentfb845741bf4a2454d06ab0269e0dc7e139a2b033 (diff)
downloadchef-8a2a34a5c25666d55da7dfbb2014b626d7a87017.tar.gz
Merge pull request #2623 from opscode/sersut/revert-1901
Preserve relative paths in Link resource Conflicts: spec/functional/resource/link_spec.rb spec/unit/provider/link_spec.rb Conflicts: CHANGELOG.md
-rw-r--r--CHANGELOG.md1
-rw-r--r--lib/chef/provider/link.rb2
-rw-r--r--lib/chef/win32/api/file.rb20
-rw-r--r--spec/functional/resource/link_spec.rb63
-rw-r--r--spec/unit/provider/link_spec.rb10
5 files changed, 55 insertions, 41 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 668b5a1958..fc1d34c93b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@
* [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 2625](https://github.com/opscode/chef/issues/2625) Fix missing `shell_out!` for `windows_package` resource
+* [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 2220e973cf..2b616408d0 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)
@@ -179,8 +179,8 @@ describe Chef::Resource::Link do
end
it 'links to the target file' do
- symlink?(target_file).should be_true
- paths_eql?(readlink(target_file), to).should be_true
+ expect(symlink?(target_file)).to be_true
+ expect(readlink(target_file)).to eq(canonicalize(to))
end
it 'marks the resource updated' do
resource.should be_updated
@@ -200,8 +200,8 @@ describe Chef::Resource::Link do
end
it 'leaves the file linked' do
- symlink?(target_file).should be_true
- paths_eql?(readlink(target_file), to).should be_true
+ expect(symlink?(target_file)).to be_true
+ expect(readlink(target_file)).to eq(canonicalize(to))
end
it 'does not mark the resource updated' do
resource.should_not be_updated
@@ -278,8 +278,8 @@ describe Chef::Resource::Link do
context 'pointing at the target' do
before(:each) do
symlink(to, target_file)
- symlink?(target_file).should be_true
- paths_eql?(readlink(target_file), to).should be_true
+ expect(symlink?(target_file)).to be_true
+ expect(readlink(target_file)).to eq(canonicalize(to))
end
include_context 'create symbolic link is noop'
include_context 'delete succeeds'
@@ -293,8 +293,8 @@ describe Chef::Resource::Link do
@other_target = File.join(test_file_dir, make_tmpname('other_spec'))
File.open(@other_target, 'w') { |file| file.write('eek') }
symlink(@other_target, target_file)
- symlink?(target_file).should be_true
- paths_eql?(readlink(target_file), @other_target).should be_true
+ expect(symlink?(target_file)).to be_true
+ expect(readlink(target_file)).to eq(canonicalize(@other_target))
end
after(:each) do
File.delete(@other_target)
@@ -310,8 +310,8 @@ describe Chef::Resource::Link do
before(:each) do
nonexistent = File.join(test_file_dir, make_tmpname('nonexistent_spec'))
symlink(nonexistent, target_file)
- symlink?(target_file).should be_true
- paths_eql?(readlink(target_file), nonexistent).should be_true
+ expect(symlink?(target_file)).to be_true
+ expect(readlink(target_file)).to eq(canonicalize(nonexistent))
end
include_context 'create symbolic link succeeds'
include_context 'delete succeeds'
@@ -392,8 +392,8 @@ describe Chef::Resource::Link do
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
File.open(@other_target, "w") { |file| file.write("eek") }
symlink(@other_target, to)
- symlink?(to).should be_true
- paths_eql?(readlink(to), @other_target).should be_true
+ expect(symlink?(to)).to be_true
+ expect(readlink(to)).to eq(canonicalize(@other_target))
end
after(:each) do
File.delete(@other_target)
@@ -407,8 +407,8 @@ describe Chef::Resource::Link do
before(:each) do
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
symlink(@other_target, to)
- symlink?(to).should be_true
- paths_eql?(readlink(to), @other_target).should be_true
+ expect(symlink?(to)).to be_true
+ expect(readlink(to)).to eq(canonicalize(@other_target))
end
context 'and the link does not yet exist' do
include_context 'create symbolic link succeeds'
@@ -440,8 +440,8 @@ describe Chef::Resource::Link do
context 'when the link already exists and points at the target' do
before(:each) do
symlink(to, target_file)
- symlink?(target_file).should be_true
- paths_eql?(readlink(target_file), to).should be_true
+ expect(symlink?(target_file)).to be_true
+ expect(readlink(target_file)).to eq(canonicalize(to))
end
include_context 'create symbolic link is noop'
include_context 'delete succeeds'
@@ -449,8 +449,8 @@ describe Chef::Resource::Link do
context 'when the link already exists and points at the target with an absolute path' do
before(:each) do
symlink(absolute_to, target_file)
- symlink?(target_file).should be_true
- paths_eql?(readlink(target_file), absolute_to).should be_true
+ expect(symlink?(target_file)).to be_true
+ expect(readlink(target_file)).to eq(canonicalize(absolute_to))
end
include_context 'create symbolic link succeeds'
include_context 'delete succeeds'
@@ -477,8 +477,8 @@ describe Chef::Resource::Link do
context "and the link already exists and is a symbolic link pointing at the same file" do
before(:each) do
symlink(to, target_file)
- symlink?(target_file).should be_true
- paths_eql?(readlink(target_file), to).should be_true
+ expect(symlink?(target_file)).to be_true
+ expect(readlink(target_file)).to eq(canonicalize(to))
end
include_context 'create hard link succeeds'
it_behaves_like 'delete errors out'
@@ -551,8 +551,8 @@ describe Chef::Resource::Link do
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
File.open(@other_target, "w") { |file| file.write("eek") }
symlink(@other_target, to)
- symlink?(to).should be_true
- paths_eql?(readlink(to), @other_target).should be_true
+ expect(symlink?(to)).to be_true
+ expect(readlink(to)).to eq(canonicalize(@other_target))
end
after(:each) do
File.delete(@other_target)
@@ -562,10 +562,9 @@ describe Chef::Resource::Link do
resource.run_action(:create)
File.exists?(target_file).should be_true
# 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?)) do
- symlink?(target_file).should be_true
- paths_eql?(readlink(target_file), @other_target).should be_true
- end
+ 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_true
+ expect(readlink(target_file)).to eq(canonicalize(@other_target))
end
include_context 'delete is noop'
end
@@ -574,8 +573,8 @@ describe Chef::Resource::Link do
before(:each) do
@other_target = File.join(test_file_dir, make_tmpname("other_spec"))
symlink(@other_target, to)
- symlink?(to).should be_true
- paths_eql?(readlink(to), @other_target).should be_true
+ expect(symlink?(to)).to be_true
+ 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,8 +586,8 @@ describe Chef::Resource::Link do
else
File.exists?(target_file).should be_false
end
- symlink?(target_file).should be_true
- paths_eql?(readlink(target_file), @other_target).should be_true
+ expect(symlink?(target_file)).to be_true
+ expect(readlink(target_file)).to eq(canonicalize(@other_target))
end
end
include_context 'delete is noop'
diff --git a/spec/unit/provider/link_spec.rb b/spec/unit/provider/link_spec.rb
index 3ae8a71cff..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_true
+ 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_true
+ 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_true
+ 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)