summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2016-04-18 11:48:11 -0700
committerLamont Granquist <lamont@scriptkiddie.org>2016-11-16 10:37:04 -0800
commitf0f89d3e3330bfa084d5d6b6d1b95fc72120e582 (patch)
treed8b9c14557f48be4f41232ef84e9ee589d732b50
parenta17be0f1c1d073f0619328d6a0971bbebf845e6a (diff)
downloadchef-f0f89d3e3330bfa084d5d6b6d1b95fc72120e582.tar.gz
add global and per-resource toggles for resource cloning behavior
let us turn on and off resource cloning
-rw-r--r--chef-config/lib/chef-config/config.rb3
-rw-r--r--lib/chef/mixin/notifying_block.rb3
-rw-r--r--lib/chef/provider.rb11
-rw-r--r--lib/chef/resource_builder.rb4
-rw-r--r--lib/chef/run_context.rb8
-rw-r--r--spec/unit/recipe_spec.rb32
6 files changed, 59 insertions, 2 deletions
diff --git a/chef-config/lib/chef-config/config.rb b/chef-config/lib/chef-config/config.rb
index c9c2ca77df..d66be1a749 100644
--- a/chef-config/lib/chef-config/config.rb
+++ b/chef-config/lib/chef-config/config.rb
@@ -1053,6 +1053,9 @@ module ChefConfig
default :rubygems_url, "https://rubygems.org"
+ # For Chef-12 this is still the default, in Chef-13 the default will be false
+ default :resource_cloning, true
+
# If installed via an omnibus installer, this gives the path to the
# "embedded" directory which contains all of the software packaged with
# omnibus. This is used to locate the cacert.pem file on windows.
diff --git a/lib/chef/mixin/notifying_block.rb b/lib/chef/mixin/notifying_block.rb
index 2d6a82f493..3ebb79ee7e 100644
--- a/lib/chef/mixin/notifying_block.rb
+++ b/lib/chef/mixin/notifying_block.rb
@@ -37,6 +37,9 @@ class Chef
parent_context ||= @run_context
sub_run_context = parent_context.create_child
+ # inhert the resource_cloning setting from our parent context
+ sub_run_context.resource_cloning = parent_context.resource_cloning
+
begin
outer_run_context = @run_context
@run_context = sub_run_context
diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb
index 40c31e4371..c2031712ec 100644
--- a/lib/chef/provider.rb
+++ b/lib/chef/provider.rb
@@ -342,6 +342,15 @@ class Chef
include InlineResources
end
+ # allow users to control enabling/disabling resource cloning per-resource
+ class << self
+ attr_accessor :resource_cloning
+
+ def resource_cloning(val)
+ @resource_cloning = val
+ end
+ end
+
# Chef::Provider::InlineResources
# Implementation of inline resource convergence for providers. See
# Provider.use_inline_resources for a longer explanation.
@@ -358,6 +367,8 @@ class Chef
def compile_and_converge_action(&block)
old_run_context = run_context
@run_context = run_context.create_child
+ # use_inline_resources gets the setting from the class instance variable
+ @run_context.resource_cloning = self.class.resource_cloning
return_value = instance_eval(&block)
Chef::Runner.new(run_context).converge
return_value
diff --git a/lib/chef/resource_builder.rb b/lib/chef/resource_builder.rb
index 78b2fcd4d1..607e78358a 100644
--- a/lib/chef/resource_builder.rb
+++ b/lib/chef/resource_builder.rb
@@ -56,7 +56,7 @@ class Chef
# This behavior is very counter-intuitive and should be removed.
# See CHEF-3694, https://tickets.opscode.com/browse/CHEF-3694
# Moved to this location to resolve CHEF-5052, https://tickets.opscode.com/browse/CHEF-5052
- if prior_resource
+ if prior_resource && run_context.resource_cloning
resource.load_from(prior_resource)
end
@@ -80,7 +80,7 @@ class Chef
end
# emit a cloned resource warning if it is warranted
- if prior_resource
+ if prior_resource && run_context.resource_cloning
if is_trivial_resource?(prior_resource) && identicalish_resources?(prior_resource, resource)
emit_harmless_cloning_debug
else
diff --git a/lib/chef/run_context.rb b/lib/chef/run_context.rb
index aa6280e5be..511b64ed02 100644
--- a/lib/chef/run_context.rb
+++ b/lib/chef/run_context.rb
@@ -110,6 +110,11 @@ class Chef
#
attr_reader :audits
+ # Toggle to enable/disable resource cloning
+ #
+ # @return [Boolean] True if resource cloning is enabled for this run_context
+ attr_accessor :resource_cloning
+
#
# Notification handling
#
@@ -192,6 +197,7 @@ class Chef
#
def initialize_child_state
@audits = {}
+ @resource_cloning = Chef::Config[:resource_cloning]
@resource_collection = Chef::ResourceCollection.new(self)
@before_notification_collection = Hash.new { |h, k| h[k] = [] }
@immediate_notification_collection = Hash.new { |h, k| h[k] = [] }
@@ -651,6 +657,8 @@ ERROR_MESSAGE
delayed_notification_collection
delayed_notification_collection=
delayed_notifications
+ resource_cloning
+ resource_cloning=
immediate_notification_collection
immediate_notification_collection=
immediate_notifications
diff --git a/spec/unit/recipe_spec.rb b/spec/unit/recipe_spec.rb
index eea1a41998..e1e3e0ad72 100644
--- a/spec/unit/recipe_spec.rb
+++ b/spec/unit/recipe_spec.rb
@@ -193,6 +193,38 @@ describe Chef::Recipe do
end
end
+ describe "when resource cloning is disabled" do
+ def not_expect_warning
+ expect(Chef::Log).not_to receive(:warn).with(/3694/)
+ expect(Chef::Log).not_to receive(:warn).with(/Previous/)
+ expect(Chef::Log).not_to receive(:warn).with(/Current/)
+ end
+
+ before do
+ Chef::Config[:resource_cloning] = false
+ end
+
+ it "should emit a 3694 warning when attributes change" do
+ recipe.zen_master "klopp" do
+ something "bvb"
+ end
+ not_expect_warning
+ recipe.zen_master "klopp" do
+ something "vbv"
+ end
+ end
+
+ it "should not copy attributes from a prior resource" do
+ recipe.zen_master "klopp" do
+ something "bvb"
+ end
+ not_expect_warning
+ recipe.zen_master "klopp"
+ expect(run_context.resource_collection.first.something).to eql("bvb")
+ expect(run_context.resource_collection[1].something).to be nil
+ end
+ end
+
describe "when cloning resources" do
def expect_warning
expect(Chef).to receive(:deprecated).with(:resource_cloning, /^Cloning resource attributes for zen_master\[klopp\]/)