diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | lib/chef/config.rb | 22 | ||||
-rw-r--r-- | spec/integration/knife/chef_repo_path_spec.rb | 3 | ||||
-rw-r--r-- | spec/integration/knife/deps_spec.rb | 3 | ||||
-rw-r--r-- | spec/integration/knife/list_spec.rb | 3 | ||||
-rw-r--r-- | spec/integration/knife/raw_spec.rb | 3 | ||||
-rw-r--r-- | spec/integration/knife/redirection_spec.rb | 3 | ||||
-rw-r--r-- | spec/integration/knife/show_spec.rb | 3 | ||||
-rw-r--r-- | spec/support/shared/context/config.rb | 21 | ||||
-rw-r--r-- | spec/unit/client_spec.rb | 1 | ||||
-rw-r--r-- | spec/unit/config_spec.rb | 78 | ||||
-rw-r--r-- | spec/unit/role_spec.rb | 6 | ||||
-rw-r--r-- | spec/unit/run_lock_spec.rb | 2 |
13 files changed, 134 insertions, 15 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index ed50c7d1b1..c4edd543ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ * chef-full template gets knife options to override install script url, add wget/curl cli options, and custom install commands (CHEF-4697) * knife now bootstraps node with the latest current version of chef-client. (CHEF-4911) * Add config options for attribute whitelisting in node.save. (CHEF-3811) +* Use user's .chef as a fallback cache path if /var/chef is not accessible. (CHEF-5259) ## Release: 11.12.4 (04/30/2014) http://www.getchef.com/blog/2014/04/30/release-chef-client-11-12-4-ohai-7-0-4/ diff --git a/lib/chef/config.rb b/lib/chef/config.rb index d884aabc3d..65ef1ac576 100644 --- a/lib/chef/config.rb +++ b/lib/chef/config.rb @@ -142,7 +142,7 @@ class Chef end end else - platform_specific_path("/var/chef") + cache_path end end @@ -240,10 +240,28 @@ class Chef if local_mode "#{config_dir}local-mode-cache" else - platform_specific_path("/var/chef") + primary_cache_root = platform_specific_path("/var") + primary_cache_path = platform_specific_path("/var/chef") + # Use /var/chef as the cache path only if that folder exists and we can read and write + # into it, or /var exists and we can read and write into it (we'll create /var/chef later). + # Otherwise, we'll create .chef under the user's home directory and use that as + # the cache path. + unless path_accessible?(primary_cache_path) || path_accessible?(primary_cache_root) + secondary_cache_path = File.join(user_home, '.chef') + secondary_cache_path.gsub!(File::SEPARATOR, platform_path_separator) # Safety, mainly for Windows... + Chef::Log.info("Unable to access cache at #{primary_cache_path}. Switching cache to #{secondary_cache_path}") + secondary_cache_path + else + primary_cache_path + end end end + # Returns true only if the path exists and is readable and writeable for the user. + def self.path_accessible?(path) + File.exists?(path) && File.readable?(path) && File.writable?(path) + end + # Where cookbook files are stored on the server (by content checksum) default(:checksum_path) { path_join(cache_path, "checksums") } diff --git a/spec/integration/knife/chef_repo_path_spec.rb b/spec/integration/knife/chef_repo_path_spec.rb index 87619d8a58..72d2ffbf75 100644 --- a/spec/integration/knife/chef_repo_path_spec.rb +++ b/spec/integration/knife/chef_repo_path_spec.rb @@ -16,6 +16,7 @@ # limitations under the License. require 'support/shared/integration/integration_helper' +require 'support/shared/context/config' require 'chef/knife/list' require 'chef/knife/show' @@ -801,6 +802,8 @@ EOM end context 'when data_bag_path is set and nothing else' do + include_context "default config options" + before :each do %w(client cookbook environment node role user).each do |object_name| Chef::Config.delete("#{object_name}_path".to_sym) diff --git a/spec/integration/knife/deps_spec.rb b/spec/integration/knife/deps_spec.rb index 5ede0caef3..7f434f844d 100644 --- a/spec/integration/knife/deps_spec.rb +++ b/spec/integration/knife/deps_spec.rb @@ -16,6 +16,7 @@ # limitations under the License. require 'support/shared/integration/integration_helper' +require 'support/shared/context/config' require 'chef/knife/deps' describe 'knife deps' do @@ -340,6 +341,8 @@ EOM end context 'remote' do + include_context "default config options" + when_the_chef_server 'has a role with no run_list' do role 'starring', {} it 'knife deps reports no dependencies' do diff --git a/spec/integration/knife/list_spec.rb b/spec/integration/knife/list_spec.rb index b9d75ce1f1..b9e72c5573 100644 --- a/spec/integration/knife/list_spec.rb +++ b/spec/integration/knife/list_spec.rb @@ -16,12 +16,15 @@ # limitations under the License. require 'support/shared/integration/integration_helper' +require 'support/shared/context/config' require 'chef/knife/list' describe 'knife list' do extend IntegrationSupport include KnifeSupport + include_context "default config options" + when_the_chef_server "is empty" do it "knife list / returns all top level directories" do knife('list /').should_succeed <<EOM diff --git a/spec/integration/knife/raw_spec.rb b/spec/integration/knife/raw_spec.rb index c2ef02175b..2a9b5d8904 100644 --- a/spec/integration/knife/raw_spec.rb +++ b/spec/integration/knife/raw_spec.rb @@ -16,6 +16,7 @@ # limitations under the License. require 'support/shared/integration/integration_helper' +require 'support/shared/context/config' require 'chef/knife/raw' require 'chef/knife/show' @@ -24,6 +25,8 @@ describe 'knife raw' do include KnifeSupport include AppServerSupport + include_context "default config options" + when_the_chef_server "has one of each thing" do client 'x', '{}' cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"' } diff --git a/spec/integration/knife/redirection_spec.rb b/spec/integration/knife/redirection_spec.rb index b92e3252c7..ebfd40966e 100644 --- a/spec/integration/knife/redirection_spec.rb +++ b/spec/integration/knife/redirection_spec.rb @@ -16,6 +16,7 @@ # limitations under the License. require 'support/shared/integration/integration_helper' +require 'support/shared/context/config' require 'chef/knife/list' describe 'redirection' do @@ -23,6 +24,8 @@ describe 'redirection' do include KnifeSupport include AppServerSupport + include_context "default config options" + when_the_chef_server 'has a role' do role 'x', {} diff --git a/spec/integration/knife/show_spec.rb b/spec/integration/knife/show_spec.rb index a061fab040..5b15110e41 100644 --- a/spec/integration/knife/show_spec.rb +++ b/spec/integration/knife/show_spec.rb @@ -16,12 +16,15 @@ # limitations under the License. require 'support/shared/integration/integration_helper' +require 'support/shared/context/config' require 'chef/knife/show' describe 'knife show' do extend IntegrationSupport include KnifeSupport + include_context "default config options" + when_the_chef_server "has one of each thing" do client 'x', '{}' cookbook 'x', '1.0.0', { 'metadata.rb' => 'version "1.0.0"' } diff --git a/spec/support/shared/context/config.rb b/spec/support/shared/context/config.rb new file mode 100644 index 0000000000..1412356f3a --- /dev/null +++ b/spec/support/shared/context/config.rb @@ -0,0 +1,21 @@ + +# +# Define config file setups for spec tests here. +# https://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-context +# + +# Required chef files here: +require 'chef/config' + +# Required spec files here: +require 'spec_helper' + +# Basic config. Nothing fancy. +shared_context "default config options" do + before do + Chef::Config[:cache_path] = windows? ? 'C:\chef' : '/var/chef' + end + + # Don't need to have an after block to reset the config... + # The spec_helper.rb takes care of resetting the config state. +end diff --git a/spec/unit/client_spec.rb b/spec/unit/client_spec.rb index 36a0e9fc1b..37a2dc09ca 100644 --- a/spec/unit/client_spec.rb +++ b/spec/unit/client_spec.rb @@ -272,6 +272,7 @@ describe Chef::Client do before do Chef::Config[:client_fork] = enable_fork + Chef::Config[:cache_path] = windows? ? 'C:\chef' : '/var/chef' stub_const("Chef::Client::STDOUT_FD", stdout) stub_const("Chef::Client::STDERR_FD", stderr) diff --git a/spec/unit/config_spec.rb b/spec/unit/config_spec.rb index 82506f556c..c467d7d553 100644 --- a/spec/unit/config_spec.rb +++ b/spec/unit/config_spec.rb @@ -138,13 +138,71 @@ describe Chef::Config do end describe "default values" do + def primary_cache_path + if windows? + "#{Chef::Config.env['SYSTEMDRIVE']}\\chef" + else + "/var/chef" + end + end - it "Chef::Config[:file_backup_path] defaults to /var/chef/backup" do - backup_path = if windows? - "#{ENV['SYSTEMDRIVE']}\\chef\\backup" + def secondary_cache_path + if windows? + "#{Chef::Config[:user_home]}\\.chef" + else + "#{Chef::Config[:user_home]}/.chef" + end + end + + before do + if windows? + Chef::Config.stub(:env).and_return({ 'SYSTEMDRIVE' => 'C:' }) + Chef::Config[:user_home] = 'C:\Users\charlie' else - "/var/chef/backup" + Chef::Config[:user_home] = '/Users/charlie' + end + + Chef::Config.stub(:path_accessible?).and_return(false) + end + + describe "Chef::Config[:cache_path]" do + context "when /var/chef exists and is accessible" do + it "defaults to /var/chef" do + Chef::Config.stub(:path_accessible?).with(Chef::Config.platform_specific_path("/var/chef")).and_return(true) + Chef::Config[:cache_path].should == primary_cache_path + end end + + context "when /var/chef does not exist and /var is accessible" do + it "defaults to /var/chef" do + File.stub(:exists?).with(Chef::Config.platform_specific_path("/var/chef")).and_return(false) + Chef::Config.stub(:path_accessible?).with(Chef::Config.platform_specific_path("/var")).and_return(true) + Chef::Config[:cache_path].should == primary_cache_path + end + end + + context "when /var/chef does not exist and /var is not accessible" do + it "defaults to $HOME/.chef" do + File.stub(:exists?).with(Chef::Config.platform_specific_path("/var/chef")).and_return(false) + Chef::Config.stub(:path_accessible?).with(Chef::Config.platform_specific_path("/var")).and_return(false) + Chef::Config[:cache_path].should == secondary_cache_path + end + end + + context "when /var/chef exists and is not accessible" do + it "defaults to $HOME/.chef" do + File.stub(:exists?).with(Chef::Config.platform_specific_path("/var/chef")).and_return(true) + File.stub(:readable?).with(Chef::Config.platform_specific_path("/var/chef")).and_return(true) + File.stub(:writable?).with(Chef::Config.platform_specific_path("/var/chef")).and_return(false) + + Chef::Config[:cache_path].should == secondary_cache_path + end + end + end + + it "Chef::Config[:file_backup_path] defaults to /var/chef/backup" do + Chef::Config.stub(:cache_path).and_return(primary_cache_path) + backup_path = windows? ? "#{primary_cache_path}\\backup" : "#{primary_cache_path}/backup" Chef::Config[:file_backup_path].should == backup_path end @@ -167,18 +225,14 @@ describe Chef::Config do end it "Chef::Config[:data_bag_path] defaults to /var/chef/data_bags" do - data_bag_path = - Chef::Config.platform_specific_path("/var/chef/data_bags") + Chef::Config.stub(:cache_path).and_return(primary_cache_path) + data_bag_path = windows? ? "#{primary_cache_path}\\data_bags" : "#{primary_cache_path}/data_bags" Chef::Config[:data_bag_path].should == data_bag_path end it "Chef::Config[:environment_path] defaults to /var/chef/environments" do - environment_path = if windows? - "C:\\chef\\environments" - else - "/var/chef/environments" - end - + Chef::Config.stub(:cache_path).and_return(primary_cache_path) + environment_path = windows? ? "#{primary_cache_path}\\environments" : "#{primary_cache_path}/environments" Chef::Config[:environment_path].should == environment_path end diff --git a/spec/unit/role_spec.rb b/spec/unit/role_spec.rb index f36b7f13bd..7410b3a0c6 100644 --- a/spec/unit/role_spec.rb +++ b/spec/unit/role_spec.rb @@ -250,6 +250,11 @@ description "like Aliens, but furry" EOR describe "when loading from disk" do + before do + default_cache_path = windows? ? 'C:\chef' : '/var/chef' + Chef::Config.stub(:cache_path).and_return(default_cache_path) + end + it "should return a Chef::Role object from JSON" do File.should_receive(:exists?).with(File.join(Chef::Config[:role_path], 'lolcat.json')).exactly(1).times.and_return(true) IO.should_receive(:read).with(File.join(Chef::Config[:role_path], 'lolcat.json')).and_return('{"name": "ceiling_cat", "json_class": "Chef::Role" }') @@ -325,4 +330,3 @@ EOR end end - diff --git a/spec/unit/run_lock_spec.rb b/spec/unit/run_lock_spec.rb index 9738f76650..80140dfcce 100644 --- a/spec/unit/run_lock_spec.rb +++ b/spec/unit/run_lock_spec.rb @@ -20,10 +20,12 @@ require 'chef/client' describe Chef::RunLock do + default_cache_path = windows? ? 'C:\chef' : '/var/chef' default_pid_location = windows? ? 'C:\chef\cache\chef-client-running.pid' : '/var/chef/cache/chef-client-running.pid' describe "when first created" do it "locates the lockfile in the file cache path by default" do + Chef::Config.stub(:cache_path).and_return(default_cache_path) run_lock = Chef::RunLock.new(Chef::Config.lockfile) run_lock.runlock_file.should == default_pid_location end |