微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Chef-将模板erb与数组配合使用

如何解决Chef-将模板erb与数组配合使用

在尝试使其正常工作时遇到问题。不确定我去哪儿了,但我猜想这可能与未声明的“小组”有关。

这是我的代码

属性文件

default['dynamic']['config']['queueGroup'] = [
    {
        'groupName' => 'group1','queueNameRegex' => 'temp.x','showIndividualStats' => 'false',},{
        'groupName' => 'group2','queueNameRegex' => 'temp.y',]

ERB模板:

queueGroups:
 <% @node['dynamic']['config']['queueGroup'].each do |group| %>
  <%= "" %>
  <% @group.each do |key,value| %>
    <%if key == "groupName" %>
     - groupName:<%= value %>
    <% else %>
      <%= "#{key}=#{value}" %>
    <% end %>
  <% end %>
<% end %>

食谱:

template '/tmp/temp.config' do
  source 'config.yml.erb'
  owner 'test'
  group 'test'
  mode '0644'
  variables(
    rmq_host: node['fqdn'],rmq_port: node['dynamic']['config']['rmq_port'],rmq_usessl: node['dynamic']['config']['rmq_usessl'],rmq_username: node['dynamic']['config']['rmq_username'],rmq_password: node['dynamic']['config']['rmq_password'],rmq_display_name: node['fqdn'],rmq_socket_timeout: node['dynamic']['config']['rmq_socket_timeout'],rmq_connect_timeout: node['dynamic']['config']['rmq_connect_timeout'],rmq_metric_prefix: node['dynamic']['config']['rmq_metric_prefix']
  )
  action :create
end

当我尝试运行配方以创建模板时出现以下错误

Running handlers:
[2020-10-15T23:02:31+11:00] ERROR: Running exception handlers
Running handlers complete
[2020-10-15T23:02:31+11:00] ERROR: Exception handlers complete
Chef Infra Client Failed. 5 resources updated in 07 seconds
[2020-10-15T23:02:31+11:00] FATAL: Stacktrace dumped to /tmp/cookbooks/london/.chef/local-mode-cache/cache/chef-stacktrace.out
[2020-10-15T23:02:31+11:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2020-10-15T23:02:31+11:00] FATAL: Chef::Mixin::Template::TemplateError: undefined method `each' for nil:NilClass

下面是Stacktrace输出

Generated at 2020-10-15 23:02:31 +1100
Chef::Mixin::Template::TemplateError:

Chef::Mixin::Template::TemplateError (undefined method `each' for nil:NilClass) on line #30:

 28:  <<% @node['dynamic']['config']['queueGroup'].each do |group| %>
 29:   <%= "" %>
 30:   <% @group.each do |key,value| %>
 31:     <%if key == "groupName" %>
 32:      - groupName:<%= value %>

  /tmp/cookbooks/default/.chef/local-mode-cache/cache/cookbooks/test/templates/default/temp.config.erb:30:in `block (2 levels) in evaluate'
  /tmp/cookbooks/default/.chef/local-mode-cache/cache/cookbooks/test/templates/default/temp.config.erb:28:in `each'
  /tmp/cookbooks/default/.chef/local-mode-cache/cache/cookbooks/test/templates/default/temp.config.erb:28:in `block in evaluate'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/erubis-2.7.0/lib/erubis/evaluator.rb:74:in `instance_eval'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/erubis-2.7.0/lib/erubis/evaluator.rb:74:in `evaluate'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/mixin/template.rb:161:in `_render_template'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/mixin/template.rb:146:in `render_template'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider/template/content.rb:76:in `file_for_provider'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/file_content_management/content_base.rb:42:in `tempfile'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider/file.rb:455:in `tempfile'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider/file.rb:329:in `do_generate_content'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider/file.rb:141:in `action_create'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider.rb:189:in `run_action'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource.rb:586:in `run_action'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:74:in `run_action'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:108:in `block in run_all_actions'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:108:in `each'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:108:in `run_all_actions'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:132:in `block in converge'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/resource_list.rb:96:in `block in execute_each_resource'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/stepable_iterator.rb:115:in `call_iterator_block'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/stepable_iterator.rb:86:in `step'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/stepable_iterator.rb:104:in `iterate'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/stepable_iterator.rb:55:in `each_with_index'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/resource_list.rb:94:in `execute_each_resource'
  /opt/chef/embedded/lib/ruby/2.6.0/forwardable.rb:230:in `execute_each_resource'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:130:in `converge'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:703:in `block in converge'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:698:in `catch'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:698:in `converge'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:722:in `converge_and_save'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:288:in `run'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application.rb:320:in `run_with_graceful_exit_option'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application.rb:296:in `block in run_chef_client'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/local_mode.rb:42:in `with_server_connectivity'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application.rb:279:in `run_chef_client'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application/base.rb:330:in `run_application'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application.rb:69:in `run'
  /opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-bin-15.8.23/bin/chef-client:25:in `<top (required)>'
  /bin/chef-client:177:in `load'
  /bin/chef-client:177:in `<main>'


/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/mixin/template.rb:163:in `rescue in _render_template'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/mixin/template.rb:158:in `_render_template'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/mixin/template.rb:146:in `render_template'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider/template/content.rb:76:in `file_for_provider'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/file_content_management/content_base.rb:42:in `tempfile'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider/file.rb:455:in `tempfile'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider/file.rb:329:in `do_generate_content'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider/file.rb:141:in `action_create'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider.rb:189:in `run_action'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource.rb:586:in `run_action'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:74:in `run_action'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:108:in `block in run_all_actions'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:108:in `each'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:108:in `run_all_actions'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:132:in `block in converge'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/resource_list.rb:96:in `block in execute_each_resource'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/stepable_iterator.rb:115:in `call_iterator_block'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/stepable_iterator.rb:86:in `step'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/stepable_iterator.rb:104:in `iterate'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/stepable_iterator.rb:55:in `each_with_index'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/resource_list.rb:94:in `execute_each_resource'
/opt/chef/embedded/lib/ruby/2.6.0/forwardable.rb:230:in `execute_each_resource'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:130:in `converge'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:703:in `block in converge'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:698:in `catch'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:698:in `converge'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:722:in `converge_and_save'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:288:in `run'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application.rb:320:in `run_with_graceful_exit_option'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application.rb:296:in `block in run_chef_client'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/local_mode.rb:42:in `with_server_connectivity'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application.rb:279:in `run_chef_client'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application/base.rb:330:in `run_application'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application.rb:69:in `run'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-bin-15.8.23/bin/chef-client:25:in `<top (required)>'
/bin/chef-client:177:in `load'
/bin/chef-client:177:in `<main>'

>>>> Caused by NoMethodError: undefined method `each' for nil:NilClass
/tmp/cookbooks/default/.chef/local-mode-cache/cache/cookbooks/test/templates/default/temp.config.erb:30:in `block (2 levels) in evaluate'
/tmp/cookbooks/default/.chef/local-mode-cache/cache/cookbooks/test/templates/default/temp.config.erb:28:in `each'
/tmp/cookbooks/default/.chef/local-mode-cache/cache/cookbooks/test/templates/default/temp.config.erb:28:in `block in evaluate'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/erubis-2.7.0/lib/erubis/evaluator.rb:74:in `instance_eval'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/erubis-2.7.0/lib/erubis/evaluator.rb:74:in `evaluate'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/mixin/template.rb:161:in `_render_template'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/mixin/template.rb:146:in `render_template'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider/template/content.rb:76:in `file_for_provider'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/file_content_management/content_base.rb:42:in `tempfile'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider/file.rb:455:in `tempfile'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider/file.rb:329:in `do_generate_content'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider/file.rb:141:in `action_create'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/provider.rb:189:in `run_action'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource.rb:586:in `run_action'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:74:in `run_action'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:108:in `block in run_all_actions'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:108:in `each'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:108:in `run_all_actions'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:132:in `block in converge'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/resource_list.rb:96:in `block in execute_each_resource'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/stepable_iterator.rb:115:in `call_iterator_block'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/stepable_iterator.rb:86:in `step'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/stepable_iterator.rb:104:in `iterate'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/stepable_iterator.rb:55:in `each_with_index'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/resource_collection/resource_list.rb:94:in `execute_each_resource'
/opt/chef/embedded/lib/ruby/2.6.0/forwardable.rb:230:in `execute_each_resource'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/runner.rb:130:in `converge'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:703:in `block in converge'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:698:in `catch'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:698:in `converge'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:722:in `converge_and_save'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/client.rb:288:in `run'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application.rb:320:in `run_with_graceful_exit_option'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application.rb:296:in `block in run_chef_client'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/local_mode.rb:42:in `with_server_connectivity'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application.rb:279:in `run_chef_client'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application/base.rb:330:in `run_application'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.8.23/lib/chef/application.rb:69:in `run'
/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-bin-15.8.23/bin/chef-client:25:in `<top (required)>'
/bin/chef-client:177:in `load'
/bin/chef-client:177:in `<main>'

希望有人可以迅速提供帮助。预先谢谢你!

解决方法

在模板中,您指的是@group(它是一个实例变量),而不是group(由each方法设置的局部变量。因为该实例变量不是定义,则在第30行调用nil时假定为each

在模板中,通常仅将通过variables属性传递的数据称为实例变量。在您的示例中,您可以请参阅@ rmq_host,因为您已明确将其传递。

由于其他变量,尤其是循环的块参数,它们仅是局部变量,因此不带前导@字符。

要修复模板,请确保引用正确的变量:

queueGroups:
 <% node['dynamic']['config']['queueGroup'].each do |group| %>
  <%= "" %>
  <% group.each do |key,value| %>
    <%if key == "groupName" %>
     - groupName:<%= value %>
    <% else %>
      <%= "#{key}=#{value}" %>
    <% end %>
  <% end %>
<% end %>
,

读取模板中的变量时会出现一个小错误。当您需要引用node属性或模板变量时,不需要@。由于存在前缀,属性和变量将获得nil值。

仅在variables()资源的template内部传递的变量需要加@前缀。

因此,在进行了这些修改之后,我们将获得一个模板temp.config.j2,如下所示:

queueGroups:
 <% node['dynamic']['config']['queueGroup'].each do |group| %>
  <%= "" %>
  <% group.each do |key,value| %>
    <%if key == "groupName" %>
     - groupName:<%= value %>
    <% else %>
      <%= "#{key}=#{value}" %>
    <% end %>
  <% end %>
<% end %>

请注意,在节点属性之前未使用@,在group中未使用group.each

或者您可以将['dynamic']['config']['queueGroup']作为模板中的变量传递。

template '/tmp/temp.config' do
  # rest of the declarations
  variables(
    dynamic_config_queuegroup: node['dynamic']['config']['queueGroup']
    # other variables
  )

然后在模板中使用它,例如:

queueGroups:
 <% @dynamic_config_queuegroup.each do |group| %>
  <%= "" %>
  <% group.each do |key,value| %>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。