Chef infra Chef Policyfile.rb`include_policy`not';不能保证策略依赖的不变性
假设我在一本名叫Chef infra Chef Policyfile.rb`include_policy`not';不能保证策略依赖的不变性,chef-infra,test-kitchen,chef-policyfile,Chef Infra,Test Kitchen,Chef Policyfile,假设我在一本名叫motd的食谱中有一个Polcyfile.rb: name 'motd' default_source :chef_repo, "../" include_policy "Policyfile", path: "../environment" run_list 'motd' 和arecipes/default.rb: file '/etc/motd' do content node['message'] end 我有另一本叫《环境》(env
motd
的食谱中有一个Polcyfile.rb:
name 'motd'
default_source :chef_repo, "../"
include_policy "Policyfile", path: "../environment"
run_list 'motd'
和arecipes/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'
我在environment
dir中运行chef install Policyfile.rb
,生成锁文件。当我从motd
dir运行kitchen converge
,然后从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不运行chef update policy file.rb
forenvironment
并从motd
再次运行kitchen converge
。我希望kitchen login
不会反映我的更新,因为motd
中的Policyfile.lock.json
没有更新其revision\u id
中包含的环境
策略。但令我惊讶的是,我确实在控制台中看到了更新的消息。我确实看到Policyfile.lock.json
有一个新的根revision\u id
,并且cookbook\u locks->environment->identifier
已经更改。但是,我仍然认为,在这种情况下,如果我的dependency Policyfile.rb中的cookbooks发生了更改,并且没有进行计算以匹配其Policyfile.lock.jsonrevision_id
的哈希,那么我仍然应该看到旧的输出,或者这里应该有一些其他警告
我想我只是想更全面地理解这里的概念。一方面,
motd
的根revision\u id
发生了变化,因此我在某种意义上实现了幂等性。但另一方面,环境
依赖项的修订id
与其组件食谱不匹配。有人能解释为什么这是有意义的吗 revision\u id
不是冻结依赖关系的东西。不管它是运行列表中的一本烹饪书还是一个依赖项。只有cookbook版本用于锁定
假设您已经有一个锁文件,例如您的环境
cookbook版本和cookbook集合的路径
[...]
"cookbook_locks": {
"environment": {
[...]
"source": "../environment"
}
}
[...]
"solution_dependencies": {
"Policyfile': [
["motd", "= 1.2.3"],
["environment", "= 2.7.8"]
]
}
[...]
然后,如果且仅当您在。/environment/metadata.rb
中更改了cookbook的版本,您将收到错误,说明找不到特定版本的cookbook。在这种情况下,必须重新生成锁文件
对食谱的任何其他更改都不会触发任何错误。这是预期的行为。想象一下,如果您必须为每次更改重新生成锁文件,这将是一个很大的开销
将policyfile中的
revision\u id
视为policyfile的一个版本。由于policyfiles没有向后兼容的概念,因此不需要使用语义版本控制,在这种情况下,一个长的、唯一的、不随机生成的字符串作为版本就足够了。这就是为什么chef show policy
将向您显示应用于特定策略组的策略文件的修订版,以显示此版本已部署到此组。似乎在chef install
与test kitchen
交互的方式中存在错误或可能存在功能。chef安装
所做的只是根据版本号进行验证,如果您在没有使用chef更新
重新生成的情况下更新了cookbook的版本,则会出现异常:
Error: Failed to install cookbooks from lockfile
Reason: (CookbookOmnifetch::CookbookValidationFailure) The cookbook downloaded for Cookbook 'xxxxxxx' = 1.2.3 {:path=>"."} did not satisfy the constraint.
如果您修改了cookbook,test kitchen将运行chef install
,并将cookbook文件同步到您正在构建的虚拟实例,并将针对它们运行chef client,这意味着任何本地修改都将自动拾取,而无需应用chef update
这不是生产设置中的情况,因为您需要使用chef push
将烹饪书上载到cookbook_工件库,该库由cookbook的sha进行版本控制。由于客户机基于锁文件中的sha拉下cookbook_工件,因此在部署期间将失败。由于test-kichen
没有使用chef-push
它没有您在部署中看到的不变性特性
可以说这是一个测试厨房功能,否则测试厨房需要在默认情况下每次都切换到始终运行chef update
,或者在运行之间强制用户手动运行chef update
。但是,保持锁文件反映生产,这样工作流就可以在烹饪书上迭代,并且只有在推送时才重新生成锁文件,这可能是一个工作流特性。如果有人认为这实际上是一个有害的bug,您可以针对test kitchen或chef cli提出一个问题,以便将其修复(但您需要讨论引人注目的工作流功能,而不是哲学)。虽然测试厨房不是一成不变的,但它与生产环境中policfile的不变性没有任何关系,我认为这就是这个问题的意义所在