鉴于以下配方:
ruby_block "block1" do
block do
puts "in block1"
end
action :create
end
remote_file "/tmp/foo" do
puts "in remote_file"
source "https://yahoo.com"
end
Run Code Online (Sandbox Code Playgroud)
我希望 ruby_block 首先运行(因为它首先出现)然后是 remote_file。
我想使用 ruby_block 来确定要下载的 remote_file 的 URL,因此顺序很重要。
如果不是我的 puts() 语句,我会假设这些语句按预期顺序运行,因为日志说:
==> default: [2014-06-12T17:49:19+00:00] INFO: ruby_block[block1] called
==> default: [2014-06-12T17:49:19+00:00] INFO: remote_file[/tmp/foo] created file /tmp/foo
==> default: [2014-06-12T17:49:20+00:00] INFO: remote_file[/tmp/foo] updated file contents /tmp/foo
Run Code Online (Sandbox Code Playgroud)
但除此之外,我的 puts() 语句如下:
==> default: in remote_file
==> default: in block1
Run Code Online (Sandbox Code Playgroud)
如果您认为资源按预期顺序运行,请考虑以下方法:
ruby_block "block1" do
block do
node.default['test'] = {}
node.default['test']['foo'] ='https://google.com'
puts "in block1"
end
action :create
end
remote_file "/tmp/foo" do
puts "in remote_file"
source node.default['test']['foo']
end
Run Code Online (Sandbox Code Playgroud)
这个失败如下:
==> default: [2014-06-12T17:55:38+00:00] ERROR: {} is not a valid `source` parameter for remote_file. `source` must be an absolute URI or an array of URIs.
==> default: [2014-06-12T17:55:38+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
Run Code Online (Sandbox Code Playgroud)
字符串“in block1”没有出现在输出中,所以 ruby_block 从未运行过。
所以问题是,如何强制 ruby_block 运行,并先运行?
zts*_*zts 15
好问题 - 您的两个示例都按照我的预期工作,但原因并不是很明显。
正如 StephenKing 在他的回复中所写的那样,首先要理解的是配方被编译(以产生一组资源),然后资源被聚合(以影响您的系统的变化)。这两个阶段通常是交错的——在 Chef 完成所有食谱的编译之前,您的一些资源可能会聚合。Erik Hollensbe 在他的文章“The Chef Resource Run Queue”中详细介绍了这一点。
这是您的第一个示例:
ruby_block "block1" do
block do
puts "in block1"
end
action :create
end
remote_file "/tmp/foo" do
puts "in remote_file"
source "https://yahoo.com"
end
Run Code Online (Sandbox Code Playgroud)
这些是 Chef 在处理该示例时将执行的步骤。
ruby_block[block1]
添加到资源集合中。块的内容(第一条puts
语句)还没有运行 - 它被保存以在此资源收敛时运行。remote_file[/tmp/foo/]
“ https://yahoo.com ”的资源被添加到资源集合中。在编译这个声明的过程中,puts
将执行第二条语句——这有打印“in remote_file”的副作用,但它不会影响放入资源集合中的资源。ruby_block[block1]
,Chef 在块中运行 ruby 代码 - 打印“in block1”。运行完块后,它会记录一条消息,说明该资源已被调用。remote_file[/tmp/foo]
。同样,它会记录与该活动相关联的一条(或两条)消息。这应该产生以下输出序列:
到你的第二个例子:
ruby_block "block1" do
block do
node.default['test'] = {}
node.default['test']['foo'] ='https://google.com'
puts "in block1"
end
action :create
end
remote_file "/tmp/foo" do
puts "in remote_file"
source node.default['test']['foo']
end
Run Code Online (Sandbox Code Playgroud)
与第一个示例一样,我们不希望在编译 ruby_block 时打印任何内容 - 整个“块”被保存,并且在该资源收敛之前其内容不会运行。
我们看到的第一个输出是“in remote_file”,因为该puts
语句在 Chef 编译 remote_file 资源时执行。在下一行,我们将source
参数设置为 的值node.default['test']['foo']
,显然是{}
。这不是 的有效值source
,因此 Chef 运行在该点终止 - 在ruby_block
永远运行中的代码之前。
因此,这个配方的预期输出是:
source
参数无效而导致的错误希望这能帮助您了解您所看到的行为,但我们仍有问题需要解决。
尽管您问“我如何强制 ruby_block 首先运行?”,但您对 StephenKing 的评论表明这并不是您真正想要的 - 如果您真的希望该块首先运行,您可以将其直接放入您的配方代码中。或者,您可以使用.run_action() 方法强制资源在编译后立即收敛 - 但您说在 ruby_block 有用之前还有更多资源需要收敛。
正如我们在上面看到的,资源不是“运行”的,它们首先“编译”然后“聚合”。考虑到这一点,您需要的是remote_file
资源使用一些在编译时未知但在收敛时已知的数据。换句话说,类似于ruby_block
- 一段代码中的“块”参数,直到稍后才会运行。像这样的东西:
remote_file "/tmp/foo" do
puts "in remote_file"
# this syntax isn't valid...
source do
node.default['test']['foo']
end
end
Run Code Online (Sandbox Code Playgroud)
幸运的是,确实存在这样的东西——它叫做惰性属性评估。使用该功能,您的第二个示例将如下所示:
ruby_block "block1" do
block do
node.default['test'] = {}
node.default['test']['foo'] = 'https://google.com'
puts "in block1"
end
action :create
end
remote_file "/tmp/foo" do
puts "in remote_file"
source lazy { node['test']['foo'] }
end
Run Code Online (Sandbox Code Playgroud)
这个食谱的预期输出是什么?
Chef 有一个编译阶段和一个运行阶段。我假设内部的代码ruby_block
在编译阶段不会执行,因为它位于block
语句内部(然后将在运行阶段执行)。puts
然而,块内部位于remote_file
资源定义内的“属性级别”,它实际上由厨师执行(事实上,据我所知,这source node.default...
是一个函数调用)。
所以如果我做对了,你想做的事情可以用下面的代码来完成:
node.default['test']['foo'] ='https://google.com'
remote_file "/tmp/foo" do
source node['test']['foo']
end
Run Code Online (Sandbox Code Playgroud)
如果通过设置属性node.default
不起作用,请使用node.set
.
还要提一下,我不是通过 读取属性node.default[]
,而是直接通过 读取属性node[]
。否则Chef 的属性优先级特征就没有意义。
归档时间: |
|
查看次数: |
10082 次 |
最近记录: |