在Chef配方中使用变量

时间:2014-05-08 19:42:42

标签: variables chef recipe

我使用chef-cookbook-hostname cookbook来设置节点的主机名。我不希望我的主机名在属性文件中被硬编码(默认[' 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

4 个答案:

答案 0 :(得分:13)

问题的根源在于您在ruby_block的范围内设置变量fqdn并且正在尝试在编译阶段引用该变量。 ruby_block资源允许在收敛阶段运行ruby代码。

鉴于您似乎正在使用fqdn来设置资源集,看起来好像您可以从ruby代码周围删除ruby块。 e.g。

fqdn = // logic to get fqdn

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

答案 1 :(得分:7)

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

  

使用node.run_state在Chef-client运行期间存储瞬态数据。该数据可以在资源之间传递,然后在执行阶段进行评估。 run_state是一个空哈希,在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

答案 2 :(得分:0)

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

这是我的代码:: file.rb

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

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

<强> copy.rb

filename = node.run_state [:script_1] 把“名字是#{filename}”

答案 3 :(得分:0)

我使用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

我希望它会有所帮助。