【问题标题】:Using a variable inside a Chef recipe在 Chef 食谱中使用变量
【发布时间】:2014-06-26 09:30:38
【问题描述】:

我正在使用 chef-cookbook-hostname 食谱来设置节点的主机名。我不希望我的主机名在属性文件中被硬编码(默认 ['set_fqdn'])。

相反,主机名将从 VM 定义 XML 文件中读取。我想出了以下默认配方,但显然变量 fqdn 没有给出值。是否知道为什么会发生这种情况或更好地完成我的任务?

ruby_block "Find-VM-Hostname" do
   block do
     require 'rexml/document'
     require 'net/http'
     url = 'http://chef-workstation/services.xml'
     file = Net::HTTP.get_response(URI.parse(url)).body
     doc = REXML::Document.new(file)
     REXML::XPath.each(doc, "service_parameters/parameter") do |element|
     if element.attributes["name"].include?"Hostname"
        fqdn = element.attributes["value"]  #this statement does not give value to fqdn
     end
     end
    end
    action :nothing
end
if fqdn
  fqdn = fqdn.sub('*', node.name)
  fqdn =~ /^([^.]+)/
  hostname = Regexp.last_match[1]

  case node['platform']
   when 'freebsd'
    directory '/etc/rc.conf.d' do
      mode '0755'
    end

    file '/etc/rc.conf.d/hostname' do
      content "hostname=#{fqdn}\n"
      mode '0644'
      notifies :reload, 'ohai[reload]'
     end
   else
    file '/etc/hostname' do
       content "#{hostname}\n"
       mode '0644'
       notifies :reload, 'ohai[reload]', :immediately
    end
   end

【问题讨论】:

    标签: variables chef-infra recipe


    【解决方案1】:

    这里问题的根源是您将变量 fqdn 设置在 ruby​​_block 的范围内,并试图在编译阶段引用该变量。 ruby_block 资源允许在收敛阶段运行 ruby​​ 代码。

    鉴于您似乎使用 fqdn 来设置资源集,看起来您可以从 ruby​​ 代码周围删除 ruby​​ 块。例如

    fqdn = // logic to get fqdn
    
    file '/tmp/file' do
      content "fqdn=#{fqdn}"
    end
    

    【讨论】:

    • 它解决了问题并且效果很好!感谢您的快速回复。
    【解决方案2】:

    我在 Chef 文档中找到了这个。我遇到了类似的问题。我要试试node.run_state。此信息位于本页底部https://docs.chef.io/recipes.html

    在 chef-client 运行期间使用 node.run_state 存储临时数据。该数据可以在资源之间传递,然后在执行阶段进行评估。 run_state 是一个空 Hash,总是在 chef-client 运行结束时被丢弃。

    例如,以下配方将安装 Apache Web 服务器,随机选择 PHP 或 Perl 作为脚本语言,然后安装该脚本语言:

    package "httpd" do
      action :install
    end
    
    ruby_block "randomly_choose_language" do
      block do
        if Random.rand > 0.5
          node.run_state['scripting_language'] = 'php'
        else
          node.run_state['scripting_language'] = 'perl'
        end
      end
    end
    
    package "scripting_language" do
      package_name lazy { node.run_state['scripting_language'] }
      action :install
    end
    

    【讨论】:

    • 我已经尝试过类似的方法(在 run_state 中分配一个变量并在模板中检索它)并且 node.run_state 命令总是在包调用中返回一个空值,所以这并不普遍看起来。
    • 有run_state,忘了懒惰。谢谢!
    【解决方案3】:

    请点击此链接 http://lists.opscode.com/sympa/arc/chef/2015-03/msg00266.html 您可以使用 node.run_state[:variables] 将一个变量解析为另一个配方

    这是我的代码:: 文件.rb

    node.run_state[:script_1] = "foo" include_recipe 'provision::copy'

    并在其他 copy.rb 文件中放入以下代码::

    copy.rb

    文件名 = node.run_state[:script_1] puts "名字是#{filename}"

    【讨论】:

      【解决方案4】:

      我出于同样的目的使用了node.run_state['variable'],并且成功地做到了。请在下面找到基本示例代码。

      ruby_block "resource_name" do
         block do
           node.run_state['port_value'] = 1432
         end
      end
      
      ruby_block "resource_name2" do
         block do
            num = node.run_state['variable']
         end
      end
      

      我希望它会有所帮助。

      【讨论】:

      • 要在配方中获取 run_state 的值而不是用于赋值,请使用#{node.run_state['variable']}
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-31
      • 2015-10-24
      相关资源
      最近更新 更多