1

假设我在一本名为 Polcyfile.rb 的食谱中有一个motd

    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

我有另一本名为environmentPolicyfile.rb 的食谱:

name 'environment'
default_source :chef_repo, "../"
run_list 'environment'

它有一个空的recipes/default.rbattributes/default.rb

default['message'] = 'i am a message'

chef install Policyfile.rbenvironmentdir 中运行以生成锁定文件。当我kitchen convergemotddir 然后运行时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'

不会再从. chef update Policyfile.rb_ environment_ 我的期望是这不会反映我的更新,因为尚未更新其包含的政策。但令我惊讶的是,我确实在控制台中看到了更新的消息。我确实看到它有一个新的根并且已经改变了。但是,我仍然认为,在这种情况下,如果我的依赖 Policyfile.rb 中的食谱发生了变化并且不计算以匹配其 Policyfile.lock.json 的哈希,那么我仍然应该看到旧的输出或者应该有这里有某种其他警告。kitchen convergemotdkitchen loginPolicyfile.lock.jsonmotdrevision_idenvironmentPolicyfile.lock.jsonrevision_idcookbook_locks->environment->identifierrevision_id

我想我只是想更全面地理解这里的概念。一方面,根revision_idmotd改变了,所以我在某种意义上实现了幂等性。但另一方面,revision_idforenvironment依赖项及其组件说明书不匹配。有人可以解释为什么这是有道理的吗?

4

2 回答 2

1

chef installtest-kitchen. _ 所做chef install的只是根据版本号进行验证,如果您更新说明书的版本而不使用 a 重新生成,chef update那么您将得到一个异常:

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.

如果您修改食谱,test-kitchen 将运行chef install并将食谱文件同步到您正在构建的虚拟实例并将针对它们运行 chef-client,这意味着任何本地修改都会自动获取而无需chef update应用。

这不是它在生产设置中发生的方式,因为您需要使用chef push将食谱上传到由食谱的 sha 版本控制的 cookbook_artifacts 存储库。由于客户端根据锁定文件中的 sha 拉下 cookbook_artifact,这将在部署期间失败。由于test-kichen不使用chef push它,它没有您在部署中看到的不变性功能。

可以说这是一个测试厨房功能,否则测试厨房需要切换到chef update默认情况下每次都运行,或者强制用户在两次运行chef update之间手动运行。但是保持锁定文件反映生产,以便工作流在食谱上迭代并且仅在需要推送时重新生成锁定文件可能是工作流功能。如果有人认为这是一个实际上有害的错误,您可以针对 test-kitchen 或 chef-cli 打开一个问题以修复它(但您需要争论引人注目的工作流程功能,而不是哲学)。虽然 test-kitchen 不是不可变的方式与生产环境中策略文件的不可变性没有任何关系,但我认为这就是这个问题的意义所在。

于 2020-09-04T19:34:17.370 回答
0

revision_id不是冻结依赖的东西。它是运行列表中的说明书还是依赖项都没有关系。只有食谱版本用于锁定。

假设您已经有一个锁定文件,例如您的environment食谱版本和食谱集的路径。

[...]
"cookbook_locks": {
  "environment": {
    [...]
    "source": "../environment"
  }
}
[...]
"solution_dependencies": {
  "Policyfile': [
    ["motd", "= 1.2.3"],
    ["environment", "= 2.7.8"]
  ]
}
[...]

然后,当且仅当您更改食谱的版本时,../environment/metadata.rb您才会收到错误消息,指出未找到该食谱的特定版本。在这种情况下,您必须重新生成锁定文件。

对食谱的任何其他更改都不会触发任何错误。这是预期的行为。想象一下,如果您必须为所做的每一项更改重新生成锁定文件,那将是很多开销。

revision_idin policyfile 视为 policyfile 的一个版本。由于没有策略文件的向后兼容性这样的概念,因此不需要使用语义版本控制,并且在这种情况下,一个长的唯一性不是随机生成的字符串作为版本就足够了。这就是为什么chef show-policy会向您显示应用于特定策略组的策略文件的修订,以表明该版本已部署到该组。

于 2020-05-11T19:32:22.907 回答