【问题标题】:How can a chef LW resource attribute default value refer to another attribute?厨师 LW 资源属性默认值如何引用另一个属性?
【发布时间】:2014-07-24 10:12:33
【问题描述】:

我正在尝试将一个资源属性的默认值设置为另一个属性的值。

我正在为我正在构建的 tomcat 食谱定义一个包含以下定义的资源。我想拥有可以独立设置的“名称”和“服务名称”属性。当未设置服务名称时,我希望它默认为“名称”提供的任何内容。

以下不符合我的预期:

attribute :name,         :kind_of => String, :required => true, :name_attribute => true
attribute :service_name, :kind_of => String, :default => :name

注意第二行末尾的“:default => :name”。当我在配方中的新块中引用我的资源时

my_tomcat "install tomcat" do
  name "foo_bar"
end

属性值被赋值为

 name = "foo_bar"
 service_name = "name"

这不是我所期望的。除非明确设置,否则我希望 service_name 为“foo_bar”。

我试过了

attribute :service_name, :kind_of => String, :default => new_resource.name
attribute :service_name, :kind_of => String, :default => @new_resource.name

但那些不能编译。

有没有办法做我想做的事?

【问题讨论】:

    标签: ruby chef-infra lwrp


    【解决方案1】:

    由于这些是类级别的方法,您需要使用lazy 属性:

    attribute :service_name, kind_of: String, default: lazy { |r| r.name }
    

    另外值得注意的是:

    attribute :name, kind_of: String, required: true, name_attribute: true
    

    完全是多余的。这是默认的...

    【讨论】:

    • 谢谢。刚试了一下,编译失败:“undefined method `lazy'”。然而,这让我发现在这种情况下,语法只是“name”而不是“:name”或“new_resource.name”。然而,仅使用“名称”会导致延迟评估问题。我是否需要将其转换为动态分配以使“懒惰”在这里变得可以接受?
    • 不确定。也许您使用的是旧版本的 Chef? docs.opscode.com/resource_common.html#lazy-attribute-evaluation
    • 厨师 11.12。我可以在资源中使用“lazy”作为资源的一部分(类似于示例),但不能按照您建议的方式默认使用:子句。但是,根据您的帮助,我想我使用动态访问器方法找到了答案。我会在下面发布。
    • @sethvargo 正如上面的评论员所说,当我尝试它时,这对我来说完全失败了。我以为它说lazy 是未定义的,但现在它可以工作了,如果我提供一个块参数,它就会完全按照需要工作:... :default => lazy {|r| "blah #{r.name}" }。对不起!我试图撤回反对票,但它说除非编辑答案,否则我不能。
    • r 是运行上下文对象吗?
    【解决方案2】:

    我无法使用 Seth 的“惰性”评估,但能够通过创建动态访问器方法进行模拟。

    另一个帖子很有用:How to implement a dynamic attribute default in chef LWRP definition

    首先,我的资源定义文件中的定义:

    attribute :service_name,        :kind_of => String, default: nil
    

    接下来,同一个资源定义文件底部的访问器块:

    def service_name( arg=nil )
      if arg.nil? and @service_name.nil?
        set_or_return( :service_name, @name, :kind_of => String)
      else
        set_or_return( :service_name, arg, :kind_of => String )
      end
    end
    

    第一次在我的提供程序代码中使用它时,它有效地设置了“service_name”的值。

    这适用于所有的组合

    resource "title" do
      # name defaults to "title"
      # service_name defaults to "title"
    end
    resource "title" do
      name "my_name"
      # service_name defaults to "my_name"
    end
    resource "title" do
      name "my_name"
      service_name "my_service_name"
    end
    

    再次感谢您的帮助。我希望其他人将来会发现这很有用。

    丰富

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-31
      • 2012-12-19
      相关资源
      最近更新 更多