假设我在名为motd
的食谱中有一个Polcyfile.rb:
name 'motd'
default_source :chef_repo, "../"
include_policy "Policyfile", path: "../environment"
run_list 'motd'
和recipes/default.rb
:
file '/etc/motd' do
content node['message']
end
我还有另一本名为environment
的食谱,其中有一个Policyfile.rb:
name 'environment'
default_source :chef_repo, "../"
run_list 'environment'
它有一个空的recipes/default.rb
和attributes/default.rb
,带有:
default['message'] = 'i am a message'
我在chef install Policyfile.rb
目录中运行environment
以生成锁定文件。当我从kitchen converge
目录运行motd
,然后从kitchen login
运行时,我将预期的输出输出到控制台:
This system is built by the Bento project by Chef Software
More information can be found at https://github.com/chef/bento
i am a message
现在我去更新environment/attributes/default.rb
为
default['message'] = 'i am updated'
I DO NOT对chef update Policyfile.rb
运行environment
,然后从kitchen converge
重新运行motd
。我的期望是kitchen login
不会反映我的更新,因为Policyfile.lock.json
中的motd
尚未针对包含的revision_id
策略更新其environment
。但是令我惊讶的是,我的确在控制台中看到了更新的消息。我确实看到Policyfile.lock.json
具有新的根revision_id
,并且cookbook_locks->environment->identifier
已更改。但是,我仍然认为,在这种情况下,如果我的依赖项Policyfile.rb中的菜谱已更改并且不进行计算以匹配其Policyfile.lock.json revision_id
的哈希,那么我仍然应该看到旧的输出或这里应该还有其他警告。
我想我只是想在这里更全面地理解这个概念。一方面,revision_id
的根motd
发生了变化,所以从某种意义上讲,我实现了幂等。但是另一方面,revision_id
依赖项的environment
及其组件菜谱不匹配。有人可以解释为什么这有意义吗?
revision_id
不能冻结依赖性。无论是运行列表中的食谱还是依赖项,都没有关系。仅食谱版本用于锁定。
假设您已经有一个锁定文件,例如您的environment
食谱版本和食谱集的路径。
[...]
"cookbook_locks": {
"environment": {
[...]
"source": "../environment"
}
}
[...]
"solution_dependencies": {
"Policyfile': [
["motd", "= 1.2.3"],
["environment", "= 2.7.8"]
]
}
[...]
然后,并且仅当您在../environment/metadata.rb
中更改了菜谱的版本时,您会收到错误消息,指出未找到该菜谱的特定版本。在这种情况下,您必须重新生成锁定文件。
对菜谱的任何其他更改均不会触发任何错误。这是预期的行为。想象一下,如果您必须为所做的每次更改重新生成锁定文件,那将是很多开销。
将策略文件中的revision_id
视为策略文件的版本。由于没有对策略文件向后兼容的概念,因此不需要使用语义版本控制,在这种情况下,一个长而唯一的,不是随机生成的字符串作为版本就足够了。这就是chef show-policy
向您显示在特定策略组中应用的策略文件的修订版本,以表明此版本已部署到该组的原因。