summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerdar Sutay <serdar@opscode.com>2014-12-11 16:43:46 -0800
committerSerdar Sutay <serdar@opscode.com>2014-12-11 16:43:46 -0800
commitaf20f1f996b58bef6972da92e3226135318c60cd (patch)
tree62e2aec02fc4588d1eca658a14aba458e5e20efc
parentda59a45b758793562babf871a9aedb1cd51726fd (diff)
downloadchef-sersut/revert-1901.tar.gz
As https://github.com/opscode/chef/issues/2580 summarizes, Link resource need to support relative paths in its 'to' attribute since one can create a symlink pointing to a relative location. This is useful if the directory that symlink resides in moves to a different place (e.g. mounting a disk on a separate location).sersut/revert-1901
This commit preserves relative paths inside the "encode_path" method used by the link operations and expands relative paths in similar fashion when being used by file operations.
-rw-r--r--lib/chef/win32/api/file.rb16
-rw-r--r--spec/functional/resource/link_spec.rb8
2 files changed, 17 insertions, 7 deletions
diff --git a/lib/chef/win32/api/file.rb b/lib/chef/win32/api/file.rb
index 7a8dafd8b5..86b2b942c2 100644
--- a/lib/chef/win32/api/file.rb
+++ b/lib/chef/win32/api/file.rb
@@ -457,11 +457,21 @@ 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
@@ -478,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
@@ -495,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 209002b400..d39a0c2ef6 100644
--- a/spec/functional/resource/link_spec.rb
+++ b/spec/functional/resource/link_spec.rb
@@ -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(readlink(target_file)).to eq(canonicalize(@other_target))
+ 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(readlink(target_file)).to eq(canonicalize(@other_target))
+ expect(readlink(to)).to eq(canonicalize(@other_target))
end
context 'and the link does not yet exist' do
include_context 'create symbolic link succeeds'
@@ -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(readlink(target_file)).to eq(canonicalize(@other_target))
+ expect(readlink(to)).to eq(canonicalize(@other_target))
end
after(:each) do
File.delete(@other_target)
@@ -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(readlink(target_file)).to eq(canonicalize(@other_target))
+ 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