summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJay Mundrawala <jdmundrawala@gmail.com>2016-02-04 17:36:41 -0800
committerJay Mundrawala <jdmundrawala@gmail.com>2016-02-24 21:24:14 -0800
commit9cfe82b9af36c92457598f857cba5671a1e24ef2 (patch)
tree3835f3023a32e83a69558b7f35b8329dfdbc2161
parentd0f2106071bf6cd8caf41555fe1a1784b3aff1fa (diff)
downloadchef-9cfe82b9af36c92457598f857cba5671a1e24ef2.tar.gz
Make chef-client read client.d
client.d/*.rb will be read in sorted order. All directories will be ignored.
-rw-r--r--lib/chef/application/client.rb29
-rw-r--r--spec/data/client.d_00/01-bar.rb1
-rw-r--r--spec/data/client.d_02/foo.rb/foo.txt1
-rw-r--r--spec/unit/application/client_spec.rb51
4 files changed, 82 insertions, 0 deletions
diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb
index 9ec553fb8a..c9a381a045 100644
--- a/lib/chef/application/client.rb
+++ b/lib/chef/application/client.rb
@@ -372,7 +372,12 @@ class Chef::Application::Client < Chef::Application
config[:config_file] = Chef::Config.platform_specific_path("/etc/chef/client.rb")
end
end
+
+ # Load the client.rb configuration
super
+
+ # Load all config files in client.d
+ load_config_d_directory
end
def configure_logging
@@ -503,4 +508,28 @@ class Chef::Application::Client < Chef::Application
end
end
end
+
+ def load_config_d_directory
+ list_config_d_files.sort.each do |conf|
+ if File.file?(conf)
+ load_config_d_file(conf)
+ end
+ end
+ end
+
+ def load_config_d_file(f)
+ config_fetcher = Chef::ConfigFetcher.new(conf)
+ config_fetcher.read_local_config.tap do |config_content|
+ apply_config(config_content, conf)
+ end
+ end
+
+ def list_config_d_files
+ if Chef::Config[:client_d_dir]
+ Dir.glob(File.join(Chef::Util::PathHelper.escape_glob(
+ Chef::Config[:client_d_dir]), "*.rb"))
+ else
+ []
+ end
+ end
end
diff --git a/spec/data/client.d_00/01-bar.rb b/spec/data/client.d_00/01-bar.rb
new file mode 100644
index 0000000000..73f91386bc
--- /dev/null
+++ b/spec/data/client.d_00/01-bar.rb
@@ -0,0 +1 @@
+# 01-bar.rb
diff --git a/spec/data/client.d_02/foo.rb/foo.txt b/spec/data/client.d_02/foo.rb/foo.txt
new file mode 100644
index 0000000000..d724c93bef
--- /dev/null
+++ b/spec/data/client.d_02/foo.rb/foo.txt
@@ -0,0 +1 @@
+# foo.txt
diff --git a/spec/unit/application/client_spec.rb b/spec/unit/application/client_spec.rb
index ff6f460c13..7476e1dc73 100644
--- a/spec/unit/application/client_spec.rb
+++ b/spec/unit/application/client_spec.rb
@@ -257,6 +257,57 @@ Enable chef-client interval runs by setting `:client_fork = true` in your config
expect { app.reconfigure }.to raise_error(Chef::Exceptions::PIDFileLockfileMatch)
end
end
+
+ describe "client.d" do
+ before do
+ Chef::Config[:client_d_dir] = client_d_dir
+ end
+
+ context "when client_d_dir is set to nil" do
+ let(:client_d_dir) { nil }
+
+ it "does not raise an exception" do
+ expect { app.reconfigure }.not_to raise_error
+ end
+ end
+
+ context "when client_d_dir is set to a directory with configuration" do
+ # We're not going to mock out globbing the directory. We want to
+ # make sure that we are correctly globbing.
+ let(:client_d_dir) { Chef::Util::PathHelper.cleanpath(
+ File.join(File.dirname(__FILE__), "../../data/client.d_00")) }
+
+ it "loads the configuration in order" do
+ expect(app).to receive(:load_config_d_file).with("#{client_d_dir}/00-foo.rb").ordered
+ expect(app).to receive(:load_config_d_file).with("#{client_d_dir}/01-bar.rb").ordered
+ app.reconfigure
+ end
+ end
+
+ context "when client_d_dir is set to a directory without configuration" do
+ let(:client_d_dir) { Chef::Util::PathHelper.cleanpath(
+ File.join(File.dirname(__FILE__), "../../data/client.d_01")) }
+
+ # client.d_01 has a nested folder with a rb file that if
+ # executed, would raise an exception. If it is executed,
+ # it means we are loading configs that are deeply nested
+ # inside of client.d. For example, client.d/foo/bar.rb
+ # should not run, but client.d/foo.rb should.
+ it "does not raise an exception" do
+ expect { app.reconfigure }.not_to raise_error
+ end
+ end
+
+ context "when client_d_dir is set to a directory containing a directory named foo.rb" do
+ # foo.rb as a directory should be ignored
+ let(:client_d_dir) { Chef::Util::PathHelper.cleanpath(
+ File.join(File.dirname(__FILE__), "../../data/client.d_02")) }
+
+ it "does not raise an exception" do
+ expect { app.reconfigure }.not_to raise_error
+ end
+ end
+ end
end
describe Chef::Application::Client, "setup_application" do