summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaire McQuin <mcquin@users.noreply.github.com>2014-05-29 16:50:19 -0700
committerClaire McQuin <mcquin@users.noreply.github.com>2014-05-29 16:50:19 -0700
commita6b19c08da6365e883d38d0ed202068df16301ab (patch)
treef062813b74e892fe5e4359ded2c9c2618b546a94
parent901479d9e4d42f186ede7baf5fa964c4dfa8eb26 (diff)
parent0e8208ff64e228cbf2b2dda679756b3e83cf9823 (diff)
downloadchef-a6b19c08da6365e883d38d0ed202068df16301ab.tar.gz
Merge pull request #1442 from opscode/CHEF-5259
Put cache at HOME/.chef if /var/chef can't be accessed.
-rw-r--r--CHANGELOG.md1
-rw-r--r--lib/chef/config.rb22
-rw-r--r--spec/integration/knife/chef_repo_path_spec.rb3
-rw-r--r--spec/integration/knife/deps_spec.rb3
-rw-r--r--spec/integration/knife/list_spec.rb3
-rw-r--r--spec/integration/knife/raw_spec.rb3
-rw-r--r--spec/integration/knife/redirection_spec.rb3
-rw-r--r--spec/integration/knife/show_spec.rb3
-rw-r--r--spec/support/shared/context/config.rb21
-rw-r--r--spec/unit/client_spec.rb1
-rw-r--r--spec/unit/config_spec.rb78
-rw-r--r--spec/unit/role_spec.rb6
-rw-r--r--spec/unit/run_lock_spec.rb2
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