Chef:从文件中读取变量并在一个聚合中使用它

Chef: Read variable from file and use it in one converge

我有以下代码,它下载一个文件,然后将文件的内容读入一个变量。使用该变量,它执行一个命令。此配方不会收敛,因为 /root/foo 在编译阶段不存在。

我可以通过多个聚合和

来解决这个问题

if File.exist

但我想用一个收敛来完成。有什么想法吗?

execute 'download_joiner' do
  command "aws s3 cp s3://bucket/foo /root/foo"
  not_if { ::File.exist?('/root/foo') }
end

password = ::File.read('/root/foo').chomp

execute 'join_domain' do
  command "net ads join -U joiner%#{password}"
end

您可以在编译时使用 run_action 下载文件,并将第二部分包装在将在 运行 时执行的条件块中。

execute 'download_joiner' do
  command "aws s3 cp s3://bucket/foo /root/foo"
  not_if { ::File.exist?('/root/foo') }
end.run_action(:run)

if File.exist?('/root/foo')
  password = ::File.read('/root/foo').chomp

  execute 'join_domain' do
    command "net ads join -U joiner%#{password}"
  end
end

你应该从第二个命令读取文件,这样读取也会在收敛期间发生:

execute 'download_joiner' do
  command "aws s3 cp s3://bucket/foo /root/foo"
  not_if { ::File.exist?('/root/foo') }
end

execute 'join_domain' do
  command "net ads join -U joiner%`cat /root/foo`"
end

请注意,如果密码包含有趣的字符,您和我的方法都会失效。如果 net 允许您在标准输入或环境变量上提供密码,我会这样做。

正确的解决方案是使用惰性 属性:

execute 'download_joiner' do
  command "aws s3 cp s3://bucket/foo /root/foo"
  creates '/root/foo'
  sensitive true
end


execute 'join_domain' do
  command lazy {
    password = IO.read('/root/foo').strip
    "net ads join -U joiner%#{password}"
  }
  sensitive true
end

这会将文件读取延迟到写入之后。我还包含了 sensitive 属性 所以密码不会显示。