5

我希望能够定义一个轻量级资源,比如说 3 个参数,其中两个是基本/基本参数,第三个是这两个参数的组合。我还想提供自定义第三个参数的可能性。例如:

如何修改以下代码以实现full_name属性的上述行为:

资源定义:

actions :install

attribute :name, :kind_of => String, :name_attribute => true
attribute :version, :kind_of => String
attribute :full_name, :kind_of => String

提供者定义:

action :install do
    Chef::Log.info "#{new_resource.full_name}"
end

我想看到不同资源指令的不同输出,例如:

resource "abc" do
    version "1.0.1"
end

将导致abc-1.0.1,但是:

resource "def" do
    version "0.1.3"
    full_name "completely_irrelevant"
end

将导致completely_irrelevant.

是否有可能在资源定义中定义这种行为(可能通过default参数),或者我只能在提供者定义中做到这一点?如果第二个为真,那么我可以将计算值存储在new_resource对象的full_name属性中(该类似乎错过了full_name=方法定义)还是必须将其存储在局部变量中?

更新

感谢 Draco 的提示,我意识到我可以在资源文件中创建一个访问器方法,并full_name在请求时即时计算值。我更喜欢更清洁的解决方案,但它比在行动实施中计算要好得多。

厨师版 厨师:10.16.4

4

3 回答 3

3

在构造函数中设置@full_name,类似于在 wiki < 0.10.10 中提供默认操作,如wiki 中所写,不起作用,因为此时尚未设置 @version。

def initialize( name, run_context=nil )
  super
  @full_name ||= "%s-%s" % [name, version]
end

所以我们必须通过添加覆盖资源中的 full_name 方法

def full_name( arg=nil )
  if arg.nil? and @full_name.nil?
    "%s-%s" % [name, version]
  else
    set_or_return( :full_name, arg, :kind_of => String )
  end
end

进入资源定义。这样可行。经测试。

于 2013-01-05T14:27:07.257 回答
1
attribute :full_name, :kind_of => String, default => lazy {|r| "#{r.name}-#{r.version}" }
于 2015-12-11T10:25:54.637 回答
0

经过一段时间的斗争后,我发现它可以干净地工作。

attribute :eman, String, default: lazy {|r| r.name.reverse }

对我来说缺少的部分是|r|惰性块的参数。

https://docs.chef.io/resource_common.html#lazy-evaluation

于 2018-07-24T20:58:54.690 回答