summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanielsdeleo <dan@opscode.com>2013-07-02 15:44:57 -0700
committerdanielsdeleo <dan@opscode.com>2013-07-02 19:04:02 -0700
commitc2407b4187f16747979956b90a6dc98f3997b01c (patch)
treee8c17f1147683eac995291486400f8accdb1dcd1
parenta3565d9d674c777d9988bcbaa778862a02da5466 (diff)
downloadchef-c2407b4187f16747979956b90a6dc98f3997b01c.tar.gz
Use symlink source when inspecting current permissions
Fixes CHEF-4341 http://tickets.opscode.com/browse/CHEF-4341 When manage_symlink_source is enabled, File providers update current_resource with the security attributes of the source file. Subsequent actions (e.g., running FileAccessControl) use the values set on current_resource to determine if they need to modify the system, so setting them incorrect leads to a file resource being (not) updated incorrectly.
-rw-r--r--lib/chef/provider/file.rb3
-rw-r--r--lib/chef/resource/file.rb2
-rw-r--r--lib/chef/scan_access_control.rb7
-rw-r--r--spec/support/shared/functional/file_resource.rb60
-rw-r--r--spec/unit/scan_access_control_spec.rb6
5 files changed, 64 insertions, 14 deletions
diff --git a/lib/chef/provider/file.rb b/lib/chef/provider/file.rb
index 012073f674..e727aa9ec1 100644
--- a/lib/chef/provider/file.rb
+++ b/lib/chef/provider/file.rb
@@ -74,7 +74,7 @@ class Chef
# Let children resources override constructing the @current_resource
@current_resource ||= Chef::Resource::File.new(@new_resource.name)
@current_resource.path(@new_resource.path)
- if real_file?(@current_resource.path) && ::File.exists?(@current_resource.path)
+ if ::File.exists?(@current_resource.path) && ::File.file?(::File.realpath(@current_resource.path))
if @action != :create_if_missing && @current_resource.respond_to?(:checksum)
@current_resource.checksum(checksum(@current_resource.path))
end
@@ -292,6 +292,7 @@ class Chef
converge_by(description) do
unlink(@new_resource.path)
end
+ @current_resource.checksum = nil
@file_unlinked = true
end
end
diff --git a/lib/chef/resource/file.rb b/lib/chef/resource/file.rb
index 15adb9dae8..676cbf200a 100644
--- a/lib/chef/resource/file.rb
+++ b/lib/chef/resource/file.rb
@@ -36,6 +36,8 @@ class Chef
state_attrs :checksum, :owner, :group, :mode
end
+ attr_writer :checksum
+
provides :file, :on_platforms => :all
def initialize(name, run_context=nil)
diff --git a/lib/chef/scan_access_control.rb b/lib/chef/scan_access_control.rb
index 1384656a8b..01630a7254 100644
--- a/lib/chef/scan_access_control.rb
+++ b/lib/chef/scan_access_control.rb
@@ -127,7 +127,12 @@ class Chef
end
def stat
- @stat ||= @new_resource.instance_of?(Chef::Resource::Link) ? ::File.lstat(@new_resource.path) : ::File.stat(@new_resource.path)
+ @stat ||= if @new_resource.instance_of?(Chef::Resource::Link)
+ ::File.lstat(@new_resource.path)
+ else
+ realpath = ::File.realpath(@new_resource.path)
+ ::File.stat(realpath)
+ end
end
end
end
diff --git a/spec/support/shared/functional/file_resource.rb b/spec/support/shared/functional/file_resource.rb
index 83947f8afb..30f012bb0d 100644
--- a/spec/support/shared/functional/file_resource.rb
+++ b/spec/support/shared/functional/file_resource.rb
@@ -523,15 +523,8 @@ shared_examples_for "a configured file resource" do
resource.path(link_path)
# create symlinks for test context
File.symlink(path, link_path)
-
- # Create source (real) file
- File.open(path, "wb") { |f| f.write(wrong_content) }
end
- include_context "setup broken permissions"
-
- include_examples "a securable resource with existing target"
-
after(:each) do
# shared examples should not change our test setup of a file resource
# pointing at a symlink:
@@ -539,9 +532,56 @@ shared_examples_for "a configured file resource" do
FileUtils.rm_rf(link_path)
end
- it "does not replace the symlink with a real file" do
- resource.run_action(:create)
- File.should be_symlink(link_path)
+ context "and the permissions are incorrect" do
+ before do
+ # Create source (real) file
+ File.open(path, "wb") { |f| f.write(expected_content) }
+ end
+
+
+ include_context "setup broken permissions"
+
+ include_examples "a securable resource with existing target"
+
+ it "does not replace the symlink with a real file" do
+ resource.run_action(:create)
+ File.should be_symlink(link_path)
+ end
+
+ end
+
+ context "and the content is incorrect" do
+ before do
+ # Create source (real) file
+ File.open(path, "wb") { |f| f.write(wrong_content) }
+ end
+
+ it "updates the source file content" do
+ pending
+ end
+
+ it "marks the resource as updated" do
+ resource.run_action(:create)
+ resource.should be_updated_by_last_action
+ end
+
+ it "does not replace the symlink with a real file" do
+ resource.run_action(:create)
+ File.should be_symlink(link_path)
+ end
+ end
+
+ context "and the content and permissions are correct" do
+ let(:expect_updated?) { false }
+
+ before do
+ # Create source (real) file
+ File.open(path, "wb") { |f| f.write(expected_content) }
+ end
+ include_context "setup correct permissions"
+
+ include_examples "a securable resource with existing target"
+
end
end
diff --git a/spec/unit/scan_access_control_spec.rb b/spec/unit/scan_access_control_spec.rb
index 8fcda0edb1..c83a552626 100644
--- a/spec/unit/scan_access_control_spec.rb
+++ b/spec/unit/scan_access_control_spec.rb
@@ -21,7 +21,8 @@ require 'chef/scan_access_control'
describe Chef::ScanAccessControl do
before do
- @new_resource = Chef::Resource::File.new("/tmp/foo/bar/baz/qux")
+ @new_resource = Chef::Resource::File.new("/tmp/foo/bar/baz/link")
+ @real_file = "/tmp/foo/bar/real/file"
@current_resource = Chef::Resource::File.new(@new_resource.path)
@scanner = Chef::ScanAccessControl.new(@new_resource, @current_resource)
end
@@ -49,7 +50,8 @@ describe Chef::ScanAccessControl do
before do
@stat = mock("File::Stat for #{@new_resource.path}", :uid => 0, :gid => 0, :mode => 00100644)
- File.should_receive(:stat).with(@new_resource.path).and_return(@stat)
+ File.should_receive(:realpath).with(@new_resource.path).and_return(@real_file)
+ File.should_receive(:stat).with(@real_file).and_return(@stat)
File.should_receive(:exist?).with(@new_resource.path).and_return(true)
end