Open cpjones01 opened 7 years ago
Running into what seems like the same issue trying to use a template.
The source attributes are
default['sso']['hostname'] = 'www.example.org'
default['sso']['openam']['server_port'] = 8080
and the derived attribute is written in the cookbook's attributes file as
default['sso']['openam']['web']['uri'] = lazy 'http://%{sso.hostname}:%{sso.openam.server_port}'
Chef error output (truncated for brevity):
================================================================================
Error executing action `create` on resource 'template[/opt/tomcat/conf/openam_config.properties]'
================================================================================
Chef::Mixin::Template::TemplateError
------------------------------------
can't modify frozen PoiseDerived::LazyAttribute
Resource Declaration:
---------------------
# In /tmp/kitchen/cache/cookbooks/sso/recipes/opensso.rb
9: template "#{node['sso']['tomcat']['path']}/conf/openam_config.properties" do
...
13: variables(
...
22: uri: node['sso']['openam']['web']['uri']
23: )
24: sensitive false
25: end
26:
Compiled Resource:
------------------
# Declared in /tmp/kitchen/cache/cookbooks/sso/recipes/opensso.rb:9:in `from_file'
template("/opt/tomcat/conf/openam_config.properties") do
action [:create]
default_guard_interpreter :default
source "openam_config.properties.erb"
variables {
...
:uri=>#<PoiseDerived::LazyAttribute @value="http://%{sso.hostname}:%{sso.openam.server_port}">
}
declared_type :template
cookbook_name "sso"
recipe_name "opensso"
...
path "/opt/tomcat/conf/openam_config.properties"
verifications []
end
Template Context:
-----------------
on line #21
19: SERVER_HOST = <%= @hostname %>
20: SERVER_PORT = <%= @http_port %>
21: SERVER_URI = <%= @uri -%>/openam/config/wizard/wizard.htm
22: SERVER_URL = <%= @uri %>
23:
System Info:
------------
chef_version=13.1.31
platform=centos
platform_version=6.6
ruby=ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
program_name=chef-client worker: ppid=8928;start=17:10:26;
executable=/opt/chef/bin/chef-client
Got the same error. To reproduce:
# test_parent_cookbook/attributes/default.rb
default['test_child_cookbook']['work_dir'] = 'C:\WORK'
# test_parent_cookbook/recipes/default.rb
include_recipe 'test_child_cookbook'
# test_child_cookbook/attributes/default.rb
default['test_child_cookbook']['work_dir'] = 'C:\TMP'
default['test_child_cookbook']['home'] = lazy "%{test_child_cookbook.work_dir}\\somefoldername"
# test_child_cookbook/recipes/default.rb
puts "HOME dir is: #{node['test_child_cookbook']['home']}"
Error:
================================================================================
Recipe Compile Error in /tmp/kitchen/cache/cookbooks/test_parent_cookbook/recipes/default.rb
================================================================================
RuntimeError
------------
can't modify frozen PoiseDerived::LazyAttribute
Cookbook Trace:
---------------
/tmp/kitchen/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/lazy_attribute.rb:111:in `_evaluate'
/tmp/kitchen/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/lazy_attribute.rb:77:in `to_s'
/tmp/kitchen/cache/cookbooks/test_child_cookbook/recipes/default.rb:7:in `from_file'
/tmp/kitchen/cache/cookbooks/test_parent_cookbook/recipes/default.rb:7:in `from_file'
Relevant File Content:
----------------------
/tmp/kitchen/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/lazy_attribute.rb:
104: private
105:
106: # Evaluate the lazy attribute.
107: #
108: # @return [Object]
109: def _evaluate
110: return @evaluate_cache if defined?(@evaluate_cache)
111>> @evaluate_cache = if @value.is_a?(Proc)
112: # Block mode, just run the block.
113: @node.instance_eval(&@value).to_s
114: else
115: # String mode, parse the template string and fill it in.
116: format_keys = @value.scan(FORMAT_STRING_REGEXP).inject({}) do |memo, (key)|
117: # Keys must be symbols because Ruby.
118: memo[key.to_sym] = key.split(/\./).inject(@node) {|n, k| n.nil? ? n : n[k] }
119: memo
120: end
System Info:
------------
chef_version=13.6.0
platform=centos
platform_version=7.3.1611
ruby=ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]
program_name=chef-client worker: ppid=4089;start=18:22:08;
executable=/opt/chef/bin/chef-client
I’m running into the same issue, I think, on Chef 14.2.0:
Relevant code:
# attributes/default.rb
default['ds_maps']['app_dir'] = '/opt/maps'
default['ds_maps']['config_dir'] = lazy '%{ds_maps.app_dir}/config'
default['ds_maps']['config_file'] = lazy "%{ds_maps.config_dir}/local-#{node.chef_environment}.json"
# recipes/default.rb
git node['ds_maps']['app_dir'] do
# [snip]
notifies :create, "file[#{node['ds_maps']['config_file']}]", :immediately
Error output:
================================================================================
Recipe Compile Error in /tmp/kitchen/cache/cookbooks/ds_maps/recipes/default.rb
================================================================================
FrozenError
-----------
can't modify frozen PoiseDerived::LazyAttribute
Cookbook Trace:
---------------
/tmp/kitchen/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/lazy_attribute.rb:111:in `_evaluate'
/tmp/kitchen/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/lazy_attribute.rb:77:in `to_s'
/tmp/kitchen/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/lazy_attribute.rb:121:in `%'
/tmp/kitchen/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/lazy_attribute.rb:121:in `_evaluate'
/tmp/kitchen/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/lazy_attribute.rb:77:in `to_s'
/tmp/kitchen/cache/cookbooks/ds_maps/recipes/default.rb:55:in `block in from_file'
/tmp/kitchen/cache/cookbooks/ds_maps/recipes/default.rb:50:in `from_file'
Relevant File Content:
----------------------
/tmp/kitchen/cache/cookbooks/poise-derived/files/halite_gem/poise_derived/lazy_attribute.rb:
104: private
105:
106: # Evaluate the lazy attribute.
107: #
108: # @return [Object]
109: def _evaluate
110: return @evaluate_cache if defined?(@evaluate_cache)
111>> @evaluate_cache = if @value.is_a?(Proc)
112: # Block mode, just run the block.
113: @node.instance_eval(&@value).to_s
114: else
115: # String mode, parse the template string and fill it in.
116: format_keys = @value.scan(FORMAT_STRING_REGEXP).inject({}) do |memo, (key)|
117: # Keys must be symbols because Ruby.
118: memo[key.to_sym] = key.split(/\./).inject(@node) {|n, k| n.nil? ? n : n[k] }
119: memo
120: end
Additional information:
-----------------------
Ruby objects are often frozen to prevent further modifications
when they would negatively impact the process (e.g. values inside
Ruby's ENV class) or to prevent polluting other objects when default
values are passed by reference to many instances of an object (e.g.
the empty Array as a Chef resource default, passed by reference
to every instance of the resource).
Chef uses Object#freeze to ensure the default values of properties
inside Chef resources are not modified, so that when a new instance
of a Chef resource is created, and Object#dup copies values by
reference, the new resource is not receiving a default value that
has been by a previous instance of that resource.
Instead of modifying an object that contains a default value for all
instances of a Chef resource, create a new object and assign it to
the resource's parameter, e.g.:
fruit_basket = resource(:fruit_basket, 'default')
# BAD: modifies 'contents' object for all new fruit_basket instances
fruit_basket.contents << 'apple'
# GOOD: allocates new array only owned by this fruit_basket instance
fruit_basket.contents %w(apple)
System Info:
------------
chef_version=14.2.0
platform=ubuntu
platform_version=16.04
ruby=ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
program_name=/opt/chef/bin/chef-client
executable=/opt/chef/bin/chef-client
Running handlers:
[2018-06-27T13:48:54+00:00] ERROR: Running exception handlers
Running handlers complete
[2018-06-27T13:48:54+00:00] ERROR: Exception handlers complete
Chef Client failed. 5 resources updated in 27 seconds
[2018-06-27T13:48:54+00:00] FATAL: Stacktrace dumped to /tmp/kitchen/cache/chef-stacktrace.out
[2018-06-27T13:48:54+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2018-06-27T13:48:54+00:00] FATAL: FrozenError: can't modify frozen PoiseDerived::LazyAttribute
By the way, as of ba76bc8, at least, this appears to be fixed. @coderanger, any chance of shipping a new version?
I would be really nice to get a release. Currently we host local version of this cookbook.
By the way, as of ba76bc8, at least, this appears to be fixed. @coderanger, any chance of shipping a new version?
I am not sure but it seems still an issue:
node3
node3
node3 Running handlers:
node3 [2019-05-14T03:40:36+00:00] ERROR: Running exception handlers
node3 Running handlers complete
node3 [2019-05-14T03:40:36+00:00] ERROR: Exception handlers complete
node3 Chef Client failed. 11 resources updated in 09 seconds
node3 [2019-05-14T03:40:36+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
node3 [2019-05-14T03:40:36+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
node3 [2019-05-14T03:40:36+00:00] FATAL: FrozenError: can't modify frozen PoiseDerived::LazyAttribute
[vagrant@node2 lamp_stack]$ chef-client --version
Chef: 14.8.12
In fact, I have copies this file https://github.com/poise/poise-derived/blob/ba76bc88d61183f450b1bf8b10625920d2ff99e5/lib/poise_derived/core_ext/deep_merge.rb i.e.
[vagrant@node2 poise-derived]$ pwd
/home/vagrant/chef-repo/cookbooks/poise-derived
[vagrant@node2 poise-derived]$ ls ./files/halite_gem/poise_derived/core_ext/deep_merge.rb
./files/halite_gem/poise_derived/core_ext/deep_merge.rb
and updated it as well but as you see, still not fix the issue at least on 14.8.12. Although, the result of the string in my defaults.rb used is correct which is using yum_repository and it provides the correct string results.
Using lazy attribute with Chef 13.2.20 causes recipe compilation errors, e.g.
Attribute code for repro: