node.run_state 与 ruby 文件 chef 中的全局变量之间的区别

difference between node.run_state vs global varibale in a ruby file chef

想知道全局变量与 node.run_state

之间的区别和推荐使用方法

test.rb

dbpassword=''


ruby_block "load_databag_secret" do
  block do
    secret_key = Chef::EncryptedDataBagItem.load_secret("/home/test/db_key")
        db_keys = Chef::EncryptedDataBagItem.load("mydatabag", "mydatabagitem", secret_key) 
    end
    dbpassword=db_keys['DB_PASSWORD']
node.run_state['password']=db_keys['DB_PASSWORD']
      end
    end

execute "Enable on hosts" do

  command lazy { "echo #{node.run_state['password']} > /home/app/db.txt" }
end

    template "/config/properties" do
            source "properties.erb"
            variables(lazy {
                         :db_password => { node.run_state['password'] },

                      })

或使用 node.run_state['password'] 代替此 .rb 文件中的全局变量

现在执行命令工作正常,我能够在回显文件 db.txt 上看到密码,而当我在模板变量中使用 lazy 时,它在模板中输出为空值 db_password。

所以有几个问题,首先你拥有的不是全局变量,它是局部变量。 Ruby 中的全局变量以 $ 开头。其次,您不能像 Ruby 那样(或者,实际上,在大多数语言中)从封闭范围分配给局部变量。该赋值只是创建第二个 dbpassword 作用域为块的局部变量。但是,您可以使用突变而不是变量赋值(例如 dbpassword << whatever)。第三,你不能像那样在变量散列的深处使用 lazy,它必须在顶层。第四,如果您在该示例中仅使用您曾经喜欢的值,则可以直接回避所有这些:

template "/config/properties" do
  source "properties.erb"
  variables lazy { 
    secret_key = Chef::EncryptedDataBagItem.load_secret("/home/test/db_key")
    db_keys = Chef::EncryptedDataBagItem.load("mydatabag", "mydatabagitem", secret_key)
    {db_password: db_keys['DB_PASSWORD']}
  }
end

只是为了完整性,以防其他人通过 Google 找到它,与真正的全局变量最大的区别是单元测试,运行 状态与收敛相关,因此单个单元测试不会看到彼此的价值观总是很好(当然你可以在你的代码中解决这个问题)。