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'
和a
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'
我在
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
for
environment
并从
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.json
revision_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的不变性没有任何关系,我认为这就是这个问题的意义所在