假设我有一些Chef代码,例如:

require 'mixlib/shellout'
yum_package 'somepackage'
myvar =  Mixlib::ShellOut.new('/bin/somecommand').run_command.stdout.strip


/bin/somecommand尚不存在的地方,因为它是由somepackage安装的。出于这个原因,这将在配方编译时失败,但显然会在收敛时起作用,前提是成功安装了软件包(并且如果安装失败,则显然配方无论如何都会失败)。如果将软件包安装为运行列表中的先前配方,这也将失败,因为它们都是预先编译在一起的。如何在食谱或运行列表自行安装的厨师食谱中包含内容?

评论

这种事情在CFEngine中不是问题

没有对myvar用法的深入了解,就没有真正的答案,通常我会避免在编译时使用外部命令的代码评估,除非非常有必要定义其他资源。简而言之,我会做一个ruby_block'set myvar'{node.run_state ['myvar'] = Mixlib :: ShellOut。[...]}

@Tensibai node.run_state正是我想要的-谢谢。做出答案,我会接受的!

那将不得不等到明天:)太难在电话上写出正确答案了

#1 楼

我会使用node.run_state在运行中存储一个瞬态变量,并在ruby_block中对其进行定义,以便它在收敛时发生,就像这样:

yum_package 'somepackage'

ruby_block 'set myvar' do
  block do
    node.run_state['my_var'] = Mixlib::ShellOut.new('/bin/somecommand').run_command.stdout.strip
  end
end


到目前为止我知道不需要'mixlib / shellout'。

#2 楼

具体细节取决于确切的用例。如果该值仅用作另一个资源的属性,则应使用lazy帮助器方法。如果不需要输出,则可以使用execute资源。在某些更复杂的情况下,您可以使用ruby_block资源或编写自己的自定义资源。