Chef 自定义资源属性

Chef custom resource properties

我使用以下方法创建了一本食谱:

chef generate cookbook demo
chef generate attribute default
chef generate resource package

recipes\default.rb:

demo_package 'Demo'

resources\package.rb:

property :resource_prop1, String
property :resource_prop2, String

default_action :install

load_current_value do
  puts
  puts "the current value before change for 'test_prop1': #{resource_prop1}"
  puts "the current value before change for 'test_prop2': #{resource_prop2}"
  resource_prop1 = node['demo_resource']['test_prop1']
  resource_prop2 = node['demo_resource']['test_prop2']
  puts "the current value after change for 'test_prop1': #{resource_prop1}"
  puts "the current value after change for 'test_prop2': #{resource_prop2}"
end

action :install do
    puts "the current value after load properties for 'test_prop1': #{new_resource.resource_prop1}"
    puts "the current value after load properties for 'test_prop2': #{new_resource.resource_prop2}"
end

attributes\default.rb:

default['demo_resource'] = {}
default['demo_resource']['test_prop1'] = 'test value 1'
default['demo_resource']['test_prop2'] = 'test value 2'

我希望输出看起来像这样:

the current value before change for 'test_prop1':
the current value before change for 'test_prop2':
the current value after change for 'test_prop1': test value 1
the current value after change for 'test_prop2': test value 2
the current value after load properties for 'test_prop1': test value 1
the current value after load properties for 'test_prop2': test value 2

但我实际上得到了:

the current value before change for 'test_prop1':
the current value before change for 'test_prop2':
the current value after change for 'test_prop1': test value 1
the current value after change for 'test_prop2': test value 2
the current value after load properties for 'test_prop1': 
the current value after load properties for 'test_prop2':

我正在尝试找出从操作块中引用资源属性的正确方法。 我做错了什么?


更新

我尝试更改此行:

puts "the current value after load properties for 'test_prop1': #{new_resource.resource_prop1}"

进入这个:

puts "the current value after load properties for 'test_prop1': #{resource_prop1}"

但是我得到了这个错误:

NameError undefined local variable or method `resource_prop1' for #<#Class:0x0000000007b51178>:0x00000000084b3680> Did you mean?  resources

更新 2

我能够通过如下修改 local_current_value 块来解决此问题:

load_current_value do |package|
  puts
  puts "the current value before change for 'test_prop1': #{package.resource_prop1}"
  puts "the current value before change for 'test_prop2': #{package.resource_prop2}"
  package.resource_prop1 = node['demo_resource']['test_prop1']
  package.resource_prop2 = node['demo_resource']['test_prop2']
  puts "the current value after change for 'test_prop1': #{package.resource_prop1}"
  puts "the current value after change for 'test_prop2': #{package.resource_prop2}"
end

请参阅 custom resources,在您的情况下应该类似于

new_resource.resource_prop1

自定义资源中有 2 个对象:current_resourcenew_resource。当您在配方中使用自定义资源时,您创建了 new_resource

demo_package 'Demo' do
  resource_prop1 'foo'
  resource_prop2 'bar'
end

load_current_value 中,您应该正在加载资源的当前状态。例如,如果您要创建一个具有某些路径和所有者的文件,那么在 load_current_resource 中您应该获取该文件及其当前所有者,以便稍后检查资源是否已更改。在您当前的方法中,您实际上分配了 current_resource.resource_prop1current_resource.prop2.

并且由于new_resourcecurrent_resource是不同的对象,您在load_current_resource中设置的值不会从current_resource传递到new_resource

如果您需要操作块中的加载值,请使用 current_resource:

action :install do
    puts "the current value after load properties for 'test_prop1': #{current_resource.resource_prop1}"
    puts "the current value after load properties for 'test_prop2': #{current_resource.resource_prop2}"
end

更新 2 的答案

当你传递一个参数给load_corrent_resource时,这个参数实际上引用了new_resource。这有时很有用,if

  1. 您需要 new_resource 中的一些值来计算 current_resource 的值。
  2. 您需要计算并分配 new_resource 的一些值。

有个约定叫这个参数desired,像这样:

load_current_value do |desired|
  # will assign current_resource.resource_prop1 = calculate_value(new_resource.resource_prop1)
  resource_prop1 calculate_value(desired.resource_prop1)
  [...]
  # will assign new_resource.resource_prop2
  desired.resource_prop2 some_calculation
end