summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2021-05-04 17:55:01 -0700
committerLamont Granquist <lamont@scriptkiddie.org>2021-05-04 18:09:38 -0700
commitfce4270147d788820f7b8902ea38f7332f7b7554 (patch)
tree25e28a92579ed08d5c4fe0f70b034563a89b4b8a
parenta8aab2afc90d0b404e109d31db0b9e8b18c3adbf (diff)
downloadchef-fce4270147d788820f7b8902ea38f7332f7b7554.tar.gz
Fix edit_resource usage in unified_mode
This makes edit_resource "atomic" so that in unified_mode the block is played against the resource being built before it is added to the resource collection and unified_mode fires the resource. Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
-rw-r--r--lib/chef/dsl/declare_resource.rb15
-rw-r--r--lib/chef/resource_builder.rb10
-rw-r--r--spec/integration/recipes/unified_mode_spec.rb70
3 files changed, 83 insertions, 12 deletions
diff --git a/lib/chef/dsl/declare_resource.rb b/lib/chef/dsl/declare_resource.rb
index 8053098085..df0ee0b719 100644
--- a/lib/chef/dsl/declare_resource.rb
+++ b/lib/chef/dsl/declare_resource.rb
@@ -156,15 +156,7 @@ class Chef
def edit_resource(type, name, created_at: nil, run_context: self.run_context, &resource_attrs_block)
edit_resource!(type, name, created_at: created_at, run_context: run_context, &resource_attrs_block)
rescue Chef::Exceptions::ResourceNotFound
- resource = declare_resource(type, name, created_at: created_at, run_context: run_context)
- if resource_attrs_block
- if defined?(new_resource)
- resource.instance_exec(new_resource, &resource_attrs_block)
- else
- resource.instance_exec(&resource_attrs_block)
- end
- end
- resource
+ declare_resource(type, name, created_at: created_at, run_context: run_context, &resource_attrs_block)
end
# Find existing resources by searching the list of existing resources. Possible
@@ -306,6 +298,8 @@ class Chef
enclosing_provider ||= self if is_a?(Chef::Provider)
+ nr = new_resource if defined?(new_resource)
+
Chef::ResourceBuilder.new(
type: type,
name: name,
@@ -314,7 +308,8 @@ class Chef
run_context: run_context,
cookbook_name: cookbook_name,
recipe_name: recipe_name,
- enclosing_provider: enclosing_provider
+ enclosing_provider: enclosing_provider,
+ new_resource: nr
).build(&resource_attrs_block)
end
diff --git a/lib/chef/resource_builder.rb b/lib/chef/resource_builder.rb
index 9f2cd657f9..13dc39ad2a 100644
--- a/lib/chef/resource_builder.rb
+++ b/lib/chef/resource_builder.rb
@@ -29,9 +29,10 @@ class Chef
attr_reader :recipe_name
attr_reader :enclosing_provider
attr_reader :resource
+ attr_reader :new_resource
# FIXME (ruby-2.1 syntax): most of these are mandatory
- def initialize(type: nil, name: nil, created_at: nil, params: nil, run_context: nil, cookbook_name: nil, recipe_name: nil, enclosing_provider: nil)
+ def initialize(type: nil, name: nil, created_at: nil, params: nil, run_context: nil, cookbook_name: nil, recipe_name: nil, enclosing_provider: nil, new_resource: nil)
@type = type
@name = name
@created_at = created_at
@@ -40,6 +41,7 @@ class Chef
@cookbook_name = cookbook_name
@recipe_name = recipe_name
@enclosing_provider = enclosing_provider
+ @new_resource = new_resource
end
def build(&block)
@@ -64,7 +66,11 @@ class Chef
if block_given?
resource.resource_initializing = true
begin
- resource.instance_eval(&block)
+ if new_resource.nil?
+ resource.instance_exec(&block)
+ else
+ resource.instance_exec(new_resource, &block)
+ end
ensure
resource.resource_initializing = false
end
diff --git a/spec/integration/recipes/unified_mode_spec.rb b/spec/integration/recipes/unified_mode_spec.rb
index 38ee52511d..d79d534490 100644
--- a/spec/integration/recipes/unified_mode_spec.rb
+++ b/spec/integration/recipes/unified_mode_spec.rb
@@ -874,4 +874,74 @@ describe "Unified Mode" do
result.error!
end
end
+
+ when_the_repository "has a resource that uses edit_resource to create a subresource" do
+ before do
+ directory "cookbooks/x" do
+ file "recipes/default.rb", <<~EOM
+ my_resource "doit"
+ EOM
+
+ file "resources/my_resource.rb", <<~EOM
+ unified_mode true
+ provides :my_resource
+
+ action :doit do
+ edit_resource(:log, "name") do
+ message "GOOD"
+ level :warn
+ end
+ end
+ EOM
+ end
+ end
+
+ it "recipes should still have a compile/converge mode" do
+ file "config/client.rb", <<~EOM
+ local_mode true
+ cookbook_path "#{path_to("cookbooks")}"
+ log_level :warn
+ EOM
+
+ result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" --no-color -F doc -o 'x::default'", cwd: chef_dir)
+ # in recipe mode we should still run normally with a compile/converge mode
+ expect(result.stdout).to include("GOOD")
+ result.error!
+ end
+ end
+
+ when_the_repository "has a resource that uses find_resource to create a subresource" do
+ before do
+ directory "cookbooks/x" do
+ file "recipes/default.rb", <<~EOM
+ my_resource "doit"
+ EOM
+
+ file "resources/my_resource.rb", <<~EOM
+ unified_mode true
+ provides :my_resource
+
+ action :doit do
+ find_resource(:log, "name") do
+ message "GOOD"
+ level :warn
+ end
+ end
+ EOM
+ end
+ end
+
+ it "recipes should still have a compile/converge mode" do
+ file "config/client.rb", <<~EOM
+ local_mode true
+ cookbook_path "#{path_to("cookbooks")}"
+ log_level :warn
+ EOM
+
+ result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" --no-color -F doc -o 'x::default'", cwd: chef_dir)
+ # in recipe mode we should still run normally with a compile/converge mode
+ expect(result.stdout).to include("GOOD")
+ result.error!
+ end
+ end
end