AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 633378
Accepted
Slashterix
Slashterix
Asked: 2014-10-04 08:34:12 +0800 CST2014-10-04 08:34:12 +0800 CST 2014-10-04 08:34:12 +0800 CST

厨师的执行顺序

  • 772

我有一些基于搜索设置节点属性的代码。然后我想在模板中使用这些属性。看来模板是在我计算出值的代码之前编译的。所以需要运行 2 次 chef-client 才能达到我想要的状态

if !node['foo']
  search(:node, "recipes:bla").each do |bla|
    if bla['bla'] > node['foo']
      node['foo'] = bla['bla']
    end
  end
end

template "/tm/foo" do
  source "foo"
end

我已经尝试将此代码放在模板之前和之后的配方中,以及属性文件中。我认为没有search动作,否则我可以尝试使用 .run_action() 。

有什么方法node['foo']可以设置要设置的值,以便在模板中使用它?

编辑:澄清

cook_a/attributes/default.rb

default['cook_a']['val_1'] = node['someval']

cook_a/recipes/default.rb

template "/etc/cook_a.conf" do
  source "cook_a.conf.erb"
end

cook_a/templates/default/cook_a.conf.erb

some_var = <% node['cook_a']['val_1'] %>

现在在另一本食谱中,我将覆盖该值

coob_b/recipes/default.rb

node.set['someval'] = "foo"
include "cook_a"

但是现在更改为时已晚,因此模板在第一次运行期间node['cook_a']['val_1']写入原始值。node['someval']在第二次运行期间,我得到了正确的值。

我不愿意设置node['cook_a']['val_1'],因为该名称可能会更改,并且我正在尝试从 cook_a 的细节中抽象出来。

chef
  • 1 1 个回答
  • 1515 Views

1 个回答

  • Voted
  1. Best Answer
    Mike Fiedler
    2014-10-05T16:03:38+08:002014-10-05T16:03:38+08:00

    这有点难以理解,由于过度使用bla,并且缺少模板使用的内容。

    假设模板中包含类似于以下内容的语句:

    somevalue = <%= node['foo'] %>
    

    并且您没有node['foo']在模板中获得覆盖的值(这似乎是需要的bla['bla']?)我有几种方法可以解决这个问题。

    1. node['foo']当试图替换没有属性优先级的配方中的值时,Chef 实际上应该警告您。

      Chef::Exceptions::ImmutableAttributeModification: Node attributes are read-only
      when you do not specify which precedence level to set. To set an attribute use
      code like `node.default["key"] = "value"'
      

      因此,在您的配方中,您可以更改该方法以node.default['foo'] = ...在显式属性级别设置结果。

    2. 将 node 属性扩展为 Ruby 变量,并将其显式传递给模板,以防止覆盖和编译时间与渲染时间冲突。

      这看起来像这样:

      if !node['foo']
        search(:node, "recipes:bla").each do |bla|
          if bla['bla'] > node['foo']
            node_foo = bla['bla']
          end
        end
      end
      
      template "/tmp/foo" do
        source "foo"
        variables(
          node_foo: node_foo || node['foo']
        )
      end
      

      模板将变为:

      somevalue = <%= @node_foo %>
      

      还有其他编写条件逻辑的方法,但总的来说,这意味着我们在配方中扩展节点属性,并且只将我们想要的变量传递给模板,而不是更多的节点属性。

    最后,我与这个秘诀有关的一点是,搜索的条件是node['foo']返回一个 nil 值,然后在赋值块中使用相同的已知 nil 值作为比较。我认为这并没有多大作用,好像进入块一样,它总是为零,因此比较没有多大作用。

    编辑:

    问题后澄清,如前所述,我相信您遇到了编译时间与渲染时间属性评估的“鸡和蛋”问题。

    在第二次运行期间检索到正确值的唯一原因是由于将node.set属性保存在 Chef 服务器上的节点对象本身中的操作,这意味着在属性中设置任何内容或稍后在任何地方覆盖都无关紧要,因为节点属性通常会赢得这些,因为它是最明确的。

    请注意如何设置以及如何删除它们 - 如果滥用它们可能会导致混乱。阅读Attribute Precedence。

    关于你的属性。

    属性文件是按照依赖关系和词法排序的顺序加载的,所以cook_b总是在cook_a之后被评估,你最好把它node.set作为一个属性移动到cook_b的attributes/default.rb override,并确保属性文件正确加载命令。

    您可能还想尝试在呈现模板时强制属性进行惰性评估,如下所示:

    cook_a/recipes/default.rb

    template "/etc/cook_a.conf" do
      source "cook_a.conf.erb"
      variables lazy {
        { some_var: node['cook_a']['val_1'] }
      }
    end
    

    cook_a/templates/default/cook_a.conf.erb

    some_var = <%= @some_var %>
    

    更多关于惰性属性评估的信息。

    • 1

相关问题

  • 如何开始使用 Chef?

  • 调用 chef-solo 的惯用方式?

  • centos 5.3上的厨师错误

  • 哪种方式是使用 Chef 安装软件包的最“优雅”方式?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve