summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Kantrowitz <noah@coderanger.net>2016-08-02 18:29:01 -0700
committerGitHub <noreply@github.com>2016-08-02 18:29:01 -0700
commit6f06e987db0c60dfa7fe583d84a3daf2f5b7a82b (patch)
treef72ba3567714df813f70c824134a18dde4f00238
parent767a45530b373bbd4818b93ab1efe5cd3c7da5ed (diff)
parent4da6604eae4c38fadfabe2052c22f234ae9b6300 (diff)
downloadchef-6f06e987db0c60dfa7fe583d84a3daf2f5b7a82b.tar.gz
Merge pull request #5045 from coderanger/configoption
First pass on --config-option handling.
-rw-r--r--Gemfile.lock6
-rw-r--r--chef.gemspec2
-rw-r--r--lib/chef/application.rb16
-rw-r--r--lib/chef/application/client.rb8
-rw-r--r--lib/chef/application/knife.rb8
-rw-r--r--lib/chef/application/solo.rb8
-rw-r--r--spec/unit/application/client_spec.rb35
7 files changed, 79 insertions, 4 deletions
diff --git a/Gemfile.lock b/Gemfile.lock
index 33bdcfb214..b500337e95 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -28,7 +28,7 @@ PATH
iniparse (~> 1.4)
mixlib-archive (>= 0.2.0)
mixlib-authentication (~> 1.4)
- mixlib-cli (~> 1.4, < 1.7)
+ mixlib-cli (~> 1.7)
mixlib-log (~> 1.3)
mixlib-shellout (~> 2.0)
net-sftp (~> 2.1, >= 2.1.2)
@@ -57,7 +57,7 @@ PATH
iniparse (~> 1.4)
mixlib-archive (>= 0.2.0)
mixlib-authentication (~> 1.4)
- mixlib-cli (~> 1.4, < 1.7)
+ mixlib-cli (~> 1.7)
mixlib-log (~> 1.3)
mixlib-shellout (~> 2.0)
net-sftp (~> 2.1, >= 2.1.2)
@@ -224,7 +224,7 @@ GEM
mixlib-log
mixlib-authentication (1.4.1)
mixlib-log
- mixlib-cli (1.6.0)
+ mixlib-cli (1.7.0)
mixlib-config (2.2.1)
mixlib-install (1.1.0)
artifactory
diff --git a/chef.gemspec b/chef.gemspec
index 14b31ca23e..920a269de0 100644
--- a/chef.gemspec
+++ b/chef.gemspec
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
s.add_dependency "chef-config", "= #{Chef::VERSION}"
- s.add_dependency "mixlib-cli", "~> 1.4", "< 1.7"
+ s.add_dependency "mixlib-cli", "~> 1.7"
s.add_dependency "mixlib-log", "~> 1.3"
s.add_dependency "mixlib-authentication", "~> 1.4"
s.add_dependency "mixlib-shellout", "~> 2.0"
diff --git a/lib/chef/application.rb b/lib/chef/application.rb
index 6c2fc8b11b..c377ffdb36 100644
--- a/lib/chef/application.rb
+++ b/lib/chef/application.rb
@@ -28,6 +28,7 @@ require "mixlib/cli"
require "tmpdir"
require "rbconfig"
require "chef/application/exit_code"
+require "yaml"
require "resolv"
# on linux, we replace the glibc resolver with the ruby resolv library, which
# supports reloading.
@@ -112,7 +113,22 @@ class Chef
config_content = config_fetcher.read_config
apply_config(config_content, config[:config_file])
end
+ extra_config_options = config.delete(:config_option)
Chef::Config.merge!(config)
+ if extra_config_options
+ extra_parsed_options = extra_config_options.inject({}) do |memo, option|
+ # Sanity check value.
+ Chef::Application.fatal!("Unparsable config option #{option.inspect}") if option.empty? || !option.include?("=")
+ # Split including whitespace if someone does truly odd like
+ # --config-option "foo = bar"
+ key, value = option.split(/\s*=\s*/, 2)
+ # Call to_sym because Chef::Config expects only symbol keys. Also
+ # runs a simple parse on the string for some common types.
+ memo[key.to_sym] = YAML.safe_load(value)
+ memo
+ end
+ Chef::Config.merge!(extra_parsed_options)
+ end
end
def set_specific_recipes
diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb
index 2a2f70c3a1..71bb300971 100644
--- a/lib/chef/application/client.rb
+++ b/lib/chef/application/client.rb
@@ -41,6 +41,14 @@ class Chef::Application::Client < Chef::Application
:long => "--config CONFIG",
:description => "The configuration file to use"
+ option :config_option,
+ :long => "--config-option OPTION=VALUE",
+ :description => "Override a single configuration option",
+ :proc => lambda { |option, existing|
+ (existing ||= []) << option
+ existing
+ }
+
option :formatter,
:short => "-F FORMATTER",
:long => "--format FORMATTER",
diff --git a/lib/chef/application/knife.rb b/lib/chef/application/knife.rb
index 34598574dd..c80d0245f1 100644
--- a/lib/chef/application/knife.rb
+++ b/lib/chef/application/knife.rb
@@ -33,6 +33,14 @@ class Chef::Application::Knife < Chef::Application
:description => "The configuration file to use",
:proc => lambda { |path| File.expand_path(path, Dir.pwd) }
+ option :config_option,
+ :long => "--config-option OPTION=VALUE",
+ :description => "Override a single configuration option",
+ :proc => lambda { |option, existing|
+ (existing ||= []) << option
+ existing
+ }
+
verbosity_level = 0
option :verbosity,
:short => "-V",
diff --git a/lib/chef/application/solo.rb b/lib/chef/application/solo.rb
index a7c4038f4c..8bf381a975 100644
--- a/lib/chef/application/solo.rb
+++ b/lib/chef/application/solo.rb
@@ -41,6 +41,14 @@ class Chef::Application::Solo < Chef::Application
:default => Chef::Config.platform_specific_path("/etc/chef/solo.rb"),
:description => "The configuration file to use"
+ option :config_option,
+ :long => "--config-option OPTION=VALUE",
+ :description => "Override a single configuration option",
+ :proc => lambda { |option, existing|
+ (existing ||= []) << option
+ existing
+ }
+
option :formatter,
:short => "-F FORMATTER",
:long => "--format FORMATTER",
diff --git a/spec/unit/application/client_spec.rb b/spec/unit/application/client_spec.rb
index 6765ca93ae..30fc58b84c 100644
--- a/spec/unit/application/client_spec.rb
+++ b/spec/unit/application/client_spec.rb
@@ -74,6 +74,8 @@ describe Chef::Application::Client, "reconfigure" do
end
before do
+ Chef::Config.reset
+
allow(Kernel).to receive(:trap).and_return(:ok)
allow(::File).to receive(:read).and_call_original
allow(::File).to receive(:read).with(Chef::Config.platform_specific_path("/etc/chef/client.rb")).and_return("")
@@ -141,6 +143,39 @@ describe Chef::Application::Client, "reconfigure" do
:daemonize => true
end
end
+
+ describe "--config-option" do
+ context "with a single value" do
+ it_behaves_like "sets the configuration", "--config-option chef_server_url=http://example",
+ :chef_server_url => "http://example"
+ end
+
+ context "with two values" do
+ it_behaves_like "sets the configuration", "--config-option chef_server_url=http://example --config-option policy_name=web",
+ :chef_server_url => "http://example", :policy_name => "web"
+ end
+
+ context "with a boolean value" do
+ it_behaves_like "sets the configuration", "--config-option minimal_ohai=true",
+ :minimal_ohai => true
+ end
+
+ context "with an empty value" do
+ it "should terminate with message" do
+ expect(Chef::Application).to receive(:fatal!).with('Unparsable config option ""').and_raise("so ded")
+ ARGV.replace(["--config-option", ""])
+ expect { app.reconfigure }.to raise_error "so ded"
+ end
+ end
+
+ context "with an invalid value" do
+ it "should terminate with message" do
+ expect(Chef::Application).to receive(:fatal!).with('Unparsable config option "asdf"').and_raise("so ded")
+ ARGV.replace(["--config-option", "asdf"])
+ expect { app.reconfigure }.to raise_error "so ded"
+ end
+ end
+ end
end
describe "when configured to not fork the client process" do