diff options
author | Daniel DeLeo <dan@opscode.com> | 2011-03-17 16:10:36 -0700 |
---|---|---|
committer | Daniel DeLeo <dan@opscode.com> | 2011-03-17 16:10:36 -0700 |
commit | 4fc9da10432e7e6a14bb2e9a89337ec22db99008 (patch) | |
tree | ebe53df92fe3ad3e2be7fcf79499413ab7ad95e9 | |
parent | a35ad6a7f3eb4b58d30661e477df60fff3505b8c (diff) | |
parent | 652fac0115ed524e5e30321a0835d283a0831922 (diff) | |
download | chef-4fc9da10432e7e6a14bb2e9a89337ec22db99008.tar.gz |
Merge branch 'CHEF-1852'
-rw-r--r-- | chef/lib/chef/exceptions.rb | 1 | ||||
-rw-r--r-- | chef/lib/chef/provider/cookbook_file.rb | 41 | ||||
-rw-r--r-- | chef/lib/chef/provider/file.rb | 31 | ||||
-rw-r--r-- | chef/lib/chef/provider/remote_file.rb | 2 | ||||
-rw-r--r-- | chef/lib/chef/runner.rb | 22 | ||||
-rw-r--r-- | chef/spec/unit/lwrp_spec.rb | 10 | ||||
-rw-r--r-- | chef/spec/unit/provider/cookbook_file_spec.rb | 9 | ||||
-rw-r--r-- | chef/spec/unit/provider/file_spec.rb | 12 | ||||
-rw-r--r-- | chef/spec/unit/provider/remote_file_spec.rb | 10 | ||||
-rw-r--r-- | chef/spec/unit/resource/file_spec.rb | 5 |
10 files changed, 86 insertions, 57 deletions
diff --git a/chef/lib/chef/exceptions.rb b/chef/lib/chef/exceptions.rb index 74de82d952..dd8a0d2543 100644 --- a/chef/lib/chef/exceptions.rb +++ b/chef/lib/chef/exceptions.rb @@ -74,5 +74,6 @@ class Chef class InvalidEnvironmentRunListSpecification < ArgumentError; end class InvalidDataBagItemID < ArgumentError; end class InvalidDataBagName < ArgumentError; end + class EnclosingDirectoryDoesNotExist < ArgumentError; end end end diff --git a/chef/lib/chef/provider/cookbook_file.rb b/chef/lib/chef/provider/cookbook_file.rb index b831c9cbb4..082d2140f9 100644 --- a/chef/lib/chef/provider/cookbook_file.rb +++ b/chef/lib/chef/provider/cookbook_file.rb @@ -23,7 +23,7 @@ require 'tempfile' class Chef class Provider class CookbookFile < Chef::Provider::File - + def load_current_resource @current_resource = Chef::Resource::CookbookFile.new(@new_resource.name) @new_resource.path.gsub!(/\\/, "/") # for Windows @@ -33,21 +33,22 @@ class Chef def action_create - if file_cache_location && content_stale? - Chef::Log.debug("content of file #{@new_resource.path} requires update") - backup_new_resource - Tempfile.open(::File.basename(@new_resource.name)) do |staging_file| - Chef::Log.debug("staging #{file_cache_location} to #{staging_file.path}") - staging_file.close - stage_file_to_tmpdir(staging_file.path) - FileUtils.mv(staging_file.path, @new_resource.path) - end - @new_resource.updated_by_last_action(true) - else - set_all_access_controls(@new_resource.path) - end - @new_resource.updated_by_last_action? - end + assert_enclosing_directory_exists! + if file_cache_location && content_stale? + Chef::Log.debug("content of file #{@new_resource.path} requires update") + backup_new_resource + Tempfile.open(::File.basename(@new_resource.name)) do |staging_file| + Chef::Log.debug("staging #{file_cache_location} to #{staging_file.path}") + staging_file.close + stage_file_to_tmpdir(staging_file.path) + FileUtils.mv(staging_file.path, @new_resource.path) + end + @new_resource.updated_by_last_action(true) + else + set_all_access_controls(@new_resource.path) + end + @new_resource.updated_by_last_action? + end def action_create_if_missing if ::File.exists?(@new_resource.path) @@ -56,21 +57,21 @@ class Chef action_create end end - + def file_cache_location @file_cache_location ||= begin cookbook = run_context.cookbook_collection[resource_cookbook] cookbook.preferred_filename_on_disk_location(node, :files, @new_resource.source, @new_resource.path) end end - - # Determine the cookbook to get the file from. If new resource sets an + + # Determine the cookbook to get the file from. If new resource sets an # explicit cookbook, use it, otherwise fall back to the implicit cookbook # i.e., the cookbook the resource was declared in. def resource_cookbook @new_resource.cookbook || @new_resource.cookbook_name end - + # Copy the file from the cookbook cache to a temporary location and then # set its file access control settings. def stage_file_to_tmpdir(staging_file_location) diff --git a/chef/lib/chef/provider/file.rb b/chef/lib/chef/provider/file.rb index f8f01e53fc..b516cc47c8 100644 --- a/chef/lib/chef/provider/file.rb +++ b/chef/lib/chef/provider/file.rb @@ -75,12 +75,12 @@ class Chef return false if @new_resource.owner.nil? @set_user_id = case @new_resource.owner - when /^\d+$/, Integer - @new_resource.owner.to_i - else - # This raises an ArgumentError if you can't find the user - Etc.getpwnam(@new_resource.owner).uid - end + when /^\d+$/, Integer + @new_resource.owner.to_i + else + # This raises an ArgumentError if you can't find the user + Etc.getpwnam(@new_resource.owner).uid + end @set_user_id == @current_resource.owner end @@ -100,11 +100,11 @@ class Chef return false if @new_resource.group.nil? @set_group_id = case @new_resource.group - when /^\d+$/, Integer - @new_resource.group.to_i - else - Etc.getgrnam(@new_resource.group).gid - end + when /^\d+$/, Integer + @new_resource.group.to_i + else + Etc.getgrnam(@new_resource.group).gid + end @set_group_id == @current_resource.group end @@ -137,6 +137,7 @@ class Chef end def action_create + assert_enclosing_directory_exists! unless ::File.exists?(@new_resource.path) Chef::Log.info("Creating #{@new_resource} at #{@new_resource.path}") ::File.open(@new_resource.path, "w+") {|f| f.write @new_resource.content } @@ -205,6 +206,14 @@ class Chef private + def assert_enclosing_directory_exists! + enclosing_dir = ::File.dirname(@new_resource.path) + unless ::File.directory?(enclosing_dir) + msg = "Cannot create a file at #{@new_resource.path} because the enclosing directory (#{enclosing_dir}) does not exist" + raise Chef::Exceptions::EnclosingDirectoryDoesNotExist, msg + end + end + def new_resource_content_checksum @new_resource.content && Digest::SHA2.hexdigest(@new_resource.content) end diff --git a/chef/lib/chef/provider/remote_file.rb b/chef/lib/chef/provider/remote_file.rb index f4eaf4dbbb..e2c3cf58e2 100644 --- a/chef/lib/chef/provider/remote_file.rb +++ b/chef/lib/chef/provider/remote_file.rb @@ -35,6 +35,8 @@ class Chef end def action_create + assert_enclosing_directory_exists! + Chef::Log.debug("Checking #{@new_resource} for changes") if current_resource_matches_target_checksum? diff --git a/chef/lib/chef/runner.rb b/chef/lib/chef/runner.rb index 2f00e55364..7e94f40eca 100644 --- a/chef/lib/chef/runner.rb +++ b/chef/lib/chef/runner.rb @@ -8,9 +8,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -27,7 +27,7 @@ class Chef # == Chef::Runner # This class is responsible for executing the steps in a Chef run. class Runner - + attr_reader :run_context attr_reader :delayed_actions @@ -38,15 +38,7 @@ class Chef @run_context = run_context @delayed_actions = [] end - - def build_provider(resource) - provider_class = Chef::Platform.find_provider_for_node(run_context.node, resource) - Chef::Log.debug("#{resource} using #{provider_class.to_s}") - provider = provider_class.new(resource, run_context) - provider.load_current_resource - provider - end - + # Determine the appropriate provider for the given resource, then # execute it. def run_action(resource, action) @@ -71,7 +63,7 @@ class Chef end end end - + # Iterates over the +resource_collection+ in the +run_context+ calling # +run_action+ for each resource in turn. def converge @@ -84,7 +76,7 @@ class Chef run_context.resource_collection.execute_each_resource do |resource| begin Chef::Log.debug("Processing #{resource} on #{run_context.node.name}") - + # Execute each of this resource's actions. Array(resource.action).each {|action| run_action(resource, action)} rescue => e @@ -92,7 +84,7 @@ class Chef raise e unless resource.ignore_failure end end - + # Run all our :delayed actions delayed_actions.each do |notification| Chef::Log.info( "#{notification.notifying_resource} sending #{notification.action}"\ diff --git a/chef/spec/unit/lwrp_spec.rb b/chef/spec/unit/lwrp_spec.rb index 738c8dac2a..05e1eb9c20 100644 --- a/chef/spec/unit/lwrp_spec.rb +++ b/chef/spec/unit/lwrp_spec.rb @@ -171,23 +171,23 @@ describe "LWRP" do end it "should properly handle a new_resource reference" do - resource = Chef::Resource::LwrpFoo.new("morpheus") + resource = Chef::Resource::LwrpFoo.new("morpheus", @run_context) resource.monkey("bob") resource.provider(:lwrp_monkey_name_printer) - provider = @runner.build_provider(resource) + provider = Chef::Platform.provider_for_resource(resource) provider.action_twiddle_thumbs provider.monkey_name.should == "my monkey's name is 'bob'" end it "should properly handle an embedded Resource accessing the enclosing Provider's scope" do - - resource = Chef::Resource::LwrpFoo.new("morpheus") + resource = Chef::Resource::LwrpFoo.new("morpheus", @run_context) resource.monkey("bob") resource.provider(:lwrp_embedded_resource_accesses_providers_scope) - provider = @runner.build_provider(resource) + provider = Chef::Platform.provider_for_resource(resource) + #provider = @runner.build_provider(resource) provider.action_twiddle_thumbs provider.enclosed_resource.monkey.should == 'bob, the monkey' diff --git a/chef/spec/unit/provider/cookbook_file_spec.rb b/chef/spec/unit/provider/cookbook_file_spec.rb index 1c41a65ad9..a4ced07fba 100644 --- a/chef/spec/unit/provider/cookbook_file_spec.rb +++ b/chef/spec/unit/provider/cookbook_file_spec.rb @@ -63,6 +63,15 @@ EXPECTED end end + describe "when the enclosing directory of the target file location doesn't exist" do + before do + @new_resource.path("/tmp/no/such/intermediate/path/file.txt") + end + + it "raises a specific error alerting the user to the problem" do + lambda {@provider.action_create}.should raise_error(Chef::Exceptions::EnclosingDirectoryDoesNotExist) + end + end describe "when the file doesn't yet exist" do before do @install_to = Dir.tmpdir + '/apache2_modconf.pl' diff --git a/chef/spec/unit/provider/file_spec.rb b/chef/spec/unit/provider/file_spec.rb index fac48e8657..26d2e50e67 100644 --- a/chef/spec/unit/provider/file_spec.rb +++ b/chef/spec/unit/provider/file_spec.rb @@ -25,7 +25,7 @@ describe Chef::Provider::File do @node = Chef::Node.new @node.name "latte" @run_context = Chef::RunContext.new(@node, {}) - + @resource = Chef::Resource::File.new("seattle") @resource.path(File.expand_path(File.join(CHEF_SPEC_DATA, "templates", "seattle.txt"))) @provider = Chef::Provider::File.new(@resource, @run_context) @@ -339,6 +339,16 @@ describe Chef::Provider::File do @provider.backup end + describe "when the enclosing directory does not exist" do + before do + @resource.path("/tmp/no-such-path/file.txt") + end + + it "raises a specific error describing the problem" do + lambda {@provider.action_create}.should raise_error(Chef::Exceptions::EnclosingDirectoryDoesNotExist) + end + end + describe "when creating a file if it's missing" do before(:each) do @resource.path(File.expand_path(File.join(CHEF_SPEC_DATA, "templates", "seattle.txt"))) diff --git a/chef/spec/unit/provider/remote_file_spec.rb b/chef/spec/unit/provider/remote_file_spec.rb index 75e5ca5ff9..f4b4ba7d2e 100644 --- a/chef/spec/unit/provider/remote_file_spec.rb +++ b/chef/spec/unit/provider/remote_file_spec.rb @@ -63,6 +63,16 @@ describe Chef::Provider::RemoteFile, "action_create" do @resource.source("http://opscode.com/seattle.txt") end + describe "and the target location's enclosing directory does not exist" do + before do + @resource.path("/tmp/this/path/does/not/exist/file.txt") + end + + it "raises a specific error describing the problem" do + lambda {@provider.action_create}.should raise_error(Chef::Exceptions::EnclosingDirectoryDoesNotExist) + end + end + describe "and the resource specifies a checksum" do describe "and the existing file matches the checksum exactly" do diff --git a/chef/spec/unit/resource/file_spec.rb b/chef/spec/unit/resource/file_spec.rb index 7183369946..23a4fdecb2 100644 --- a/chef/spec/unit/resource/file_spec.rb +++ b/chef/spec/unit/resource/file_spec.rb @@ -24,11 +24,6 @@ describe Chef::Resource::File do @resource = Chef::Resource::File.new("fakey_fakerton") end - it "should create a new Chef::Resource::File" do - @resource.should be_a_kind_of(Chef::Resource) - @resource.should be_a_kind_of(Chef::Resource::File) - end - it "should have a name" do @resource.name.should eql("fakey_fakerton") end |