以通用方式从变量配置提供者

Configure providers from variables, in a generic way

如何创建一个配方,以通用方式使用对象实例中的字段来填充其属性?

例如,考虑以下食谱:

component = $auth_docker
docker_image component.name do
    registry component.registry
    tag component.tag
    action :pull
end

当你有 50 多个像这样的食谱时,维护它们真的会让人不知所措。

在 Python 中,我可能会实施一个看起来有点像这样的解决方案:

docker_image = DockerImage(**$auth_docker)

或者,我会创建某种辅助函数来为我构建它:

def generate_docker_image_lwrp(attributes):
    lwrp = DockerImage()
    lwrp.registry = attributes.registry
    lwrp.tag = attributes.tag
    return lwrp

目标是减少对配方的维护。例如,今天早上我想在所有拉出图像的食谱上添加 Chef 的 "retries" 属性。我不得不编辑所有这些——我不想那样。我应该能够 a) 将属性添加到堆栈的 JSON b) 编辑 Ruby 包装器 class 以便它的实例(即:$auth_docker)获取 "retries" 字段,然后 c) 将 retries 属性添加到 lwrp-generator。由于所有食谱都将使用相同的生成器,因此根本不需要编辑食谱。

是否可以使用 Chef,以 'notifies' 仍然有效的方式?

引用 Documentation

A definition is code that is reused across recipes, similar to a compile-time macro. A definition is created using arbitrary code wrapped around built-in chef-client resources—file, execute, template, and so on—by declaring those resources into the definition as if they were declared in a recipe. A definition is then used in one (or more) recipes as if it were a resource.

Though a definition behaves like a resource, some key differences exist. A definition:

Is not a resource or a lightweight resource Is defined from within the /definitions directory of a cookbook Is loaded before resources during the chef-client run; this ensures the definition is available to all of the resources that may need it May not notify resources in the resource collection because a definition is loaded before the resource collection itself is created; however, a resource in a definition may notify a resource that exists within the same definition Automatically supports why-run mode, unlike lightweight resources Use a defintion when repeating patterns exist across resources and/or when a simple, direct approach is desired. There is no limit to the number of resources that may be included in a definition: use as many built-in chef-client resources as necessary.

即:您可以在专门用于此目的的库说明书中为此创建一个定义。

docker_library/defintions/default.rb

define :my_docker_image, :component => nil do
  component = params[:component]
  docker_image component.name do
    registry component.registry
    tag component.tag
    action :pull
  end
end 

在你的食谱中(需要有一个取决于 metadata.rb 中的 docker_library 食谱):

my_component = $auth_docker
my_docker_image my_component.name do 
  component my_component
end

logrotate cookbook

中提供了更完整的定义示例