【问题标题】:How to store array in node object chef?如何在节点对象厨师中存储数组?
【发布时间】:2019-08-01 07:26:43
【问题描述】:

我正在 Chef 的 ruby​​_block 中读取文件。我将每一行存储在一个数组中。我希望它们可以在我的厨师食谱中的任何地方访问,所以我做了一些研究,发现我可以使用节点对象。

问题是每当我使用节点对象时,它只存储最后一行而不是每一行。

这是我的代码。有什么建议吗?

ruby_block "name" do
  block do
    CSV.foreach('/tmp/users.txt') do |row|
    node['username']=row
    end
  end
  action :run # see actions section below
end

好的,现在这是我的代码。

ruby_block 'name' do
  block do
    CSV.foreach('/tmp/users.txt'){ |row| node.run_state['username123'] |= [row] }
  end
end 

directory "/sftp/#{node.run_state['username123']}/incoming" do
  action :create
  recursive true
end

我的 chef-run 输出结果是。

directory[/sftp//incoming] action create 
- create new directory /sftp//incoming

【问题讨论】:

    标签: ruby chef-infra


    【解决方案1】:

    查看新答案(不想将任何人与 cmets 混淆)

    两个选择。如果你真的想使用节点,你需要使用一个数组,而你不是。

    ruby_block 'name' do
      block do
        CSV.foreach('/tmp/users.txt'){ |row| node['username'] |= [row] }
      end
    end
    

    但是,除非您希望将该信息存储在服务器上的节点对象中,否则我建议您将其实际存储在 run_state 中

    ruby_block 'name' do
      block do
        CSV.foreach('/tmp/users.txt'){ |row| node.run_state['username'] |= [row] }
      end
    end
    

    这仍然可以让您的其余食谱可以访问它,但它会将其排除在节点对象之外,节点对象将在您运行结束时发送到厨师服务器。

    【讨论】:

    • 您好,该文件有一些内容,但我的节点对象为空。我不确定发生了什么。有什么推荐的吗?
    • 你试过我发布的代码了吗?您还可以在 ruby​​ 块内添加 Chef::Log.warn 消息,以确保您正确解析文件。
    • 是的,我使用了您的代码。这就是我的代码的样子。 ruby_block 'name' do block do CSV.foreach('/tmp/users.txt'){ |row| node.run_state['username123'] |= [row] } end end directory "/sftp/#{node['username123']}/incoming" do action :create recursive true end 这是我的输出。我不确定我在做什么错。 directory[/sftp//incoming] action create - create new directory /sftp//incoming
    • 两件事,首先,请将新代码放在问题中,而不是评论。在 cmets 中读取代码几乎是不可能的。其次,run_state 和 node 是不同的动物。要访问 run_state,您需要执行 node.run_state['name'],而不是 node['name']。如果您使用新代码更新问题,我会相应地更新我的答案。
    • 我已经更新了这个问题。非常感谢您对此的帮助。我知道我在做一些愚蠢的事情,但无法弄清楚
    【解决方案2】:

    好的,所以您的问题是由于 Chef 的两阶段性质造成的。您在“编译”阶段声明您的目录,但您尝试使用 ruby_block 内部的数据来执行此操作,直到第二阶段才会执行。如果您的 CSV 文件不是由厨师放置的,您可以这样做:

    # notice this is not in a ruby block
    CSV.foreach('/tmp/users.txt'){ |row| node.run_state['username123'] |= [row] }
    
    node.run_state['username123'].each do |next_file|
      directory "/sftp/next_file/incoming" do
        action :create
        recursive true
      end
    end
    

    如果 CSV 文件是由 Chef 放置的,您需要在 CSV 解析运行之前强制将其放置在那里。您可能能够做到这一点:

    cookbook_file 'mycsv file' do
      ...
    end.run_action(:create)
    

    在您解析 CSV 之前的某个时间点。如果这不是一个选择(出于多种原因中的任何一个),那么您需要变得更漂亮。此时,您可能最好创建一个 LWRP。

    【讨论】:

    • 非常感谢。我已经在使用你提到的方法了。我没有将它们存储在节点对象中,而是使用 ruby​​ 数组。我正在使用模板文件来创建 csv 文件。我唯一缺少的是 .run_action(:create) 因为我无法在第一次厨师运行时解析文件。那行得通
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    相关资源
    最近更新 更多