diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2016-04-08 15:11:30 -0700 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2016-04-11 13:25:02 -0700 |
commit | 9ed7d6a880749090403ee6d78d5592a4fa212343 (patch) | |
tree | e0c9e5300ea2c49d2da97009b9c04277a7d4e10d | |
parent | 224aaaef042659021eb65c9eeddd9cdb1417eb59 (diff) | |
download | chef-9ed7d6a880749090403ee6d78d5592a4fa212343.tar.gz |
add notifying_block and subcontext_block to chef
-rw-r--r-- | lib/chef/dsl/core.rb | 12 | ||||
-rw-r--r-- | lib/chef/mixin/notifying_block.rb | 54 | ||||
-rw-r--r-- | spec/integration/recipes/notifying_block_spec.rb | 111 |
3 files changed, 172 insertions, 5 deletions
diff --git a/lib/chef/dsl/core.rb b/lib/chef/dsl/core.rb index 7f7edbfbda..c2dbea7628 100644 --- a/lib/chef/dsl/core.rb +++ b/lib/chef/dsl/core.rb @@ -17,15 +17,16 @@ # limitations under the License. # -require "chef/mixin/shell_out" -require "chef/mixin/powershell_out" require "chef/dsl/declare_resource" +require "chef/mixin/notifying_block" +require "chef/mixin/powershell_out" +require "chef/mixin/shell_out" class Chef module DSL # This is the "Core DSL" with various bits of Sugar that are mixed into core providers as well # as user LWRPs. This module deliberately does not mixin the Resources or Defintions DSL bits - # so that cookbooks are not injeting random things into the samespace of core providers. + # so that cookbooks are not injeting random things into the namespace of core providers. # # - If you are writing cookbooks: you have come to the wrong place, please inject things into # Chef::DSL::Recipe instead. @@ -34,9 +35,10 @@ class Chef # into here. # module Core - include Chef::Mixin::ShellOut - include Chef::Mixin::PowershellOut include Chef::DSL::DeclareResource + include Chef::Mixin::NotifyingBlock + include Chef::Mixin::PowershellOut + include Chef::Mixin::ShellOut end end end diff --git a/lib/chef/mixin/notifying_block.rb b/lib/chef/mixin/notifying_block.rb new file mode 100644 index 0000000000..9ac1b79bb8 --- /dev/null +++ b/lib/chef/mixin/notifying_block.rb @@ -0,0 +1,54 @@ +#-- +# Author:: Lamont Granquist <lamont@chef.io> +# Copyright:: Copyright 2010-2016, Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +class Chef + module Mixin + module NotifyingBlock + + def notifying_block(&block) + begin + subcontext = subcontext_block(&block) + Chef::Runner.new(subcontext).converge + ensure + new_resource.updated_by_last_action( + subcontext && subcontext.resource_collection.any?(&:updated?) + ) if respond_to?(:new_resource) + end + end + + def subcontext_block(parent_context = nil, &block) + parent_context ||= @run_context + sub_run_context = parent_context.create_child + + begin + outer_run_context = @run_context + @run_context = sub_run_context + instance_eval(&block) + ensure + @run_context = outer_run_context + end + + sub_run_context + end + + def global_resource_collection + Chef.run_context.resource_collection + end + + end + end +end diff --git a/spec/integration/recipes/notifying_block_spec.rb b/spec/integration/recipes/notifying_block_spec.rb new file mode 100644 index 0000000000..6a1287c7b1 --- /dev/null +++ b/spec/integration/recipes/notifying_block_spec.rb @@ -0,0 +1,111 @@ +# +# Author:: John Keiser (<jkeiser@chef.io>) +# Copyright:: Copyright 2013-2016, Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require "support/shared/integration/integration_helper" +require "chef/mixin/shell_out" + +describe "notifying_block" do + include IntegrationSupport + include Chef::Mixin::ShellOut + + let(:chef_dir) { File.expand_path("../../../../bin", __FILE__) } + let(:chef_client) { "ruby '#{chef_dir}/chef-client' --minimal-ohai" } + + when_the_repository "notifying_block test one" do + before do + directory "cookbooks/x" do + file "recipes/default.rb", <<-EOM + notifying_block do + log "gamma" do + action :nothing + end + log "alpha" do + notifies :write, "log[gamma]", :delayed + end + log "beta" do + notifies :write, "log[gamma]", :delayed + end + end + log "delta" + EOM + end + file "config/client.rb", <<-EOM + local_mode true + cookbook_path "#{path_to('cookbooks')}" + log_level :warn + EOM + end + + # implicitly tests - + # 1. notifying block opens up a subcontext + # 2. delayed notifications are de-dup'd in the subcontext + # 3. delayed notifications (to resources inside the subcontext) are run at the end of the subcontext + it "should run alpha, beta, gamma, and delta in that order" do + result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" --no-color -F doc -o 'x::default'", :cwd => chef_dir) + expect(result.stdout).to match(/\* log\[alpha\] action write\s+\* log\[beta\] action write\s+\* log\[gamma\] action write\s+Converging 1 resources\s+\* log\[delta\] action write/) + result.error! + end + end + + when_the_repository "notifying_block test two" do + before do + directory "cookbooks/x" do + file "resources/nb_test.rb", <<-EOM + default_action :run + provides :nb_test + resource_name :nb_test + + action :run do + notifying_block do + log "foo" do + notifies :write, 'log[bar]', :delayed + end + end + end + EOM + file "recipes/default.rb", <<-EOM + log "bar" do + action :nothing + end + log "baz" do + action :nothing + end + + nb_test "testing" do + notifies :write, 'log[baz]', :delayed + end + + log "quux" + EOM + end + file "config/client.rb", <<-EOM + local_mode true + cookbook_path "#{path_to('cookbooks')}" + log_level :warn + EOM + end + + # implicitly tests - + # 1. notifying block will correctly update wrapping new_resource updated_by_last_action status + # 2. delayed notifications from a subcontext inside a resource will notify resources in their outer run_context + it "should run foo, quux, bar, and baz in that order" do + result = shell_out("#{chef_client} -c \"#{path_to('config/client.rb')}\" --no-color -F doc -o 'x::default'", :cwd => chef_dir) + expect(result.stdout).to match(/\* log\[foo\] action write\s+\* log\[quux\] action write\s+\* log\[bar\] action write\s+\* log\[baz\] action write/) + result.error! + end + end +end |