summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanielsdeleo <dan@opscode.com>2014-02-18 15:56:16 -0800
committerdanielsdeleo <dan@opscode.com>2014-02-20 12:30:43 -0800
commit50847457ab95ca651c75c13a45734b25e2129eea (patch)
tree3a0d980ffa2245d5e15fe9e325b1e8dd5b617763
parent332d840e79d562a33f5c7f06ade3968786415ec3 (diff)
downloadchef-50847457ab95ca651c75c13a45734b25e2129eea.tar.gz
Add permanent run list modification option to Chef::Client
-rw-r--r--lib/chef/client.rb26
-rw-r--r--lib/chef/node.rb2
-rw-r--r--spec/unit/client_spec.rb36
3 files changed, 50 insertions, 14 deletions
diff --git a/lib/chef/client.rb b/lib/chef/client.rb
index 64582bea6f..aa03f043c2 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -55,6 +55,16 @@ class Chef
class Client
include Chef::Mixin::PathSanity
+ # IO stream that will be used as 'STDOUT' for formatters. Formatters are
+ # configured during `initialize`, so this provides a convenience for
+ # setting alternative IO stream during tests.
+ STDOUT_FD = STDOUT
+
+ # IO stream that will be used as 'STDERR' for formatters. Formatters are
+ # configured during `initialize`, so this provides a convenience for
+ # setting alternative IO stream during tests.
+ STDERR_FD = STDERR
+
# Clears all notifications for client run status events.
# Primarily for testing purposes.
def self.clear_notifications
@@ -129,15 +139,13 @@ class Chef
attr_accessor :rest
attr_accessor :runner
- #--
- # TODO: timh/cw: 5-19-2010: json_attribs should be moved to RunContext?
attr_reader :json_attribs
attr_reader :run_status
attr_reader :events
# Creates a new Chef::Client.
def initialize(json_attribs=nil, args={})
- @json_attribs = json_attribs
+ @json_attribs = json_attribs || {}
@node = nil
@run_status = nil
@runner = nil
@@ -149,20 +157,16 @@ class Chef
@events = EventDispatch::Dispatcher.new(*event_handlers)
@override_runlist = args.delete(:override_runlist)
@specific_recipes = args.delete(:specific_recipes)
- end
- def stdout
- STDOUT
- end
-
- def stderr
- STDERR
+ if new_runlist = args.delete(:runlist)
+ @json_attribs["run_list"] = new_runlist
+ end
end
def configure_formatters
formatters_for_run.map do |formatter_name, output_path|
if output_path.nil?
- Chef::Formatters.new(formatter_name, stdout, stderr)
+ Chef::Formatters.new(formatter_name, STDOUT_FD, STDERR_FD)
else
io = File.open(output_path, "a+")
io.sync = true
diff --git a/lib/chef/node.rb b/lib/chef/node.rb
index 69e5e05b01..a7fc033080 100644
--- a/lib/chef/node.rb
+++ b/lib/chef/node.rb
@@ -312,7 +312,7 @@ class Chef
if attrs.key?("recipes") || attrs.key?("run_list")
raise Chef::Exceptions::AmbiguousRunlistSpecification, "please set the node's run list using the 'run_list' attribute only."
end
- Chef::Log.info("Setting the run_list to #{new_run_list.inspect} from JSON")
+ Chef::Log.info("Setting the run_list to #{new_run_list.inspect} from CLI options")
run_list(new_run_list)
end
attrs
diff --git a/spec/unit/client_spec.rb b/spec/unit/client_spec.rb
index 657351e67b..e4143d7653 100644
--- a/spec/unit/client_spec.rb
+++ b/spec/unit/client_spec.rb
@@ -269,8 +269,8 @@ describe Chef::Client do
before do
Chef::Config[:client_fork] = enable_fork
- Chef::Client.any_instance.stub(:stdout).and_return(stdout)
- Chef::Client.any_instance.stub(:stderr).and_return(stderr)
+ stub_const("Chef::Client::STDOUT_FD", stdout)
+ stub_const("Chef::Client::STDERR_FD", stderr)
stub_for_register
stub_for_node_load
@@ -356,6 +356,38 @@ describe Chef::Client do
end
end
+ describe "when a permanent run list is passed as an option" do
+
+ include_examples "a successful client run" do
+
+ let(:new_runlist) { "recipe[new_run_list_recipe]" }
+ let(:client_opts) { {:runlist => new_runlist} }
+
+ def stub_for_sync_cookbooks
+ # --Client#setup_run_context
+ # ---Client#sync_cookbooks -- downloads the list of cookbooks to sync
+ #
+ Chef::CookbookSynchronizer.any_instance.should_receive(:sync_cookbooks)
+ Chef::REST.should_receive(:new).with(Chef::Config[:chef_server_url]).and_return(http_cookbook_sync)
+ http_cookbook_sync.should_receive(:post).
+ with("environments/_default/cookbook_versions", {:run_list => ["new_run_list_recipe"]}).
+ and_return({})
+ end
+
+ before do
+ # Client will try to compile and run the new_run_list_recipe, but we
+ # do not create a fixture for this.
+ Chef::RunContext::CookbookCompiler.any_instance.should_receive(:compile)
+ end
+
+ it "sets the new run list on the node" do
+ client.run
+ node.run_list.should == Chef::RunList.new(new_runlist)
+ end
+
+ end
+ end
+
end