在 Chef 中设置 "utility" 资源的最佳方式是什么
What's the best way to set up "utility" resources in Chef
一些背景
- 我正在使用 Vagrant 和 chef-zero;厨师服务器不是我的一部分
等式
- 我有两个角色:
base
和infrastructure
,还有两个
食谱:apt
和 php
。 base
角色的目的是进行一些基本的供应和包管理,并从 github 克隆存储库等。apt
食谱有一个食谱,update_upgrade.rb
运行 是一个 execute
资源,可以有效地调用 apt update
、apt upgrade
、apt-get autoremove
等等
infrastructure
角色通过 php
说明书设置 PHP。稍后会包含更多内容,但它是我的需求的一个很好的例子。
php
食谱有两个食谱:add_repository.rb
和 install.rb
。 add_repository
配方 运行 是一个 execute
资源,用于将 ondrej/php
存储库添加到 apt
。 install
配方遍历软件包列表,以便从添加的存储库安装 php。这就是实用程序发挥作用的地方。
关键是,我需要 运行 apt update
在添加 PHP 存储库之后和安装它的软件包之前。实现此目标的最佳方法是什么?
我试过的
最初,我将我的 add_repository
和 install
资源组合成一个 install
食谱,并计划使用 include_recipe apt::update_upgrade
插入我的 apt
食谱的 execute
资源到该食谱中。然而,在搜索了 chef 文档和这篇方便的文章:Should I use include_recipe or add the recipe to run_list? 之后,似乎 include_recipe
并没有立即 运行 它所在的位置。上述文章中的建议是使用 运行 列表来指示食谱的精确执行,厨师文档确实建议食谱按照列出的顺序执行。
这导致我将 php 资源分解为 add_repository
和 install
,并为 infrastructure
使用以下角色 运行 列表:
"run_list": [
"recipe[php::add_repository]",
"recipe[apt::update_upgrade]",
"recipe[php::install]"
]
我的 php
食谱 metadata.rb
有 depends apt
,Chef 没有出错。但是,它也不会在 add_repository
之后触发 update_upgrade
配方。相反,install
配方在 add_repository
之后的 运行 秒会导致错误。
这一切让我假设角色 运行 列表也以类似于 include_recipe
的阶段执行。这准确吗?
我的结论
如果这些假设是准确的,那么用新存储库更新 apt 的唯一可靠方法似乎是将我的 execute
资源从我的 apt
食谱复制到我的 `[=156= 】 食谱。我内心的 DRY-ist 对此尖叫;因此,实用程序的问题 recipe/resource.
编辑
使用 apt
资源
正如原回答者所指出的,对于这个具体描述的用例是使用 apt_package
、apt_update
和 apt_repository
的组合。以下是我如何设置它以获得我想要的:
在上述apt
食谱中,我现在有两个食谱,install.rb
和update.rb
。关键配方是 update
:
apt_update 'update_packages' do
action :update
end
根据文档 (https://docs.chef.io/resource_apt_update.html),:update
操作将在 Chef Infra 客户端 运行 启动时更新 Apt 存储库。这对我很有用,因为我想在我的 VM 首次启动时更新我的 OS 包。
这是我的 base
角色的 运行 列表,它使用了 apt::update
配方:
"run_list": [
"recipe[apt::install]",
"recipe[apt::update]",
...
]
接下来,PHP。首先,我想添加 ondrej/php
存储库,然后遍历软件包列表并安装它们。最后,我想在安装新软件包后 运行 apt update
。
我做的第一件事是再次确保我的 php
食谱的 metadata.rb
有:
depends 'apt'
这将允许我重用我在 apt
食谱中定义的 apt_update['update_packages'] 资源。
我的 php
食谱中的 install.rb
食谱现在包含以下内容:
# Add PHP repository
apt_repository 'php7' do
uri "ppa:#{node[:infrastructure][:php][:repository][:name]}"
action :add # I know this is unnecessary, but I like to be explicit
end
# Install PHP
node[:infrastructure][:php][:extensions][:list].each do |package|
apt_package package do
action :install
notifies :update, 'apt_update[update_packages]', :delayed
end
end
由于我遍历了存储在属性中的包列表,所以在使用 :delayed
计时器安装所有 php 包后,我通知 apt_update[update_packages]
资源。
最后,这里是处理 PHP 说明书执行的 infrastructure
角色:
"run_list": [
"recipe[php::install]"
]
这个解释很好地处理了上面的用例,现在希望使用适当的 Chef 资源。但是,还有一些其他 Apt 操作未包含在资源中,并且可能仍需要一些特定的 execute
资源。考虑 this apt_cleanup cookbook 中的食谱,其中包括:
- 正在清理 apt-cache
- 清除已删除包中的剩余物
- 删除旧的未使用的内核(为了更干净的 /boot)
- 删除已删除的包拖入的依赖项
查看这些食谱,我看到了 execute
资源的集合,这意味着对于这些操作,execute
方法可能仍然是必要的。 (尽管在食谱中)。
最佳做法是将适当的厨师资源与 notification 结合使用。
因为您正在使用 apt
,请使用适当的 apt
资源,例如 apt_update
(to make sure apt repositories are up to date), apt_package
(to manipulate packages using apt, apt_repository
(to add apt respository) and try to avoid using execute
resource to do all of that - this will take advantage of chef idompotance (you might like reading Thinking Like a Chef)
每个厨师资源,可以通知and\or订阅通知。但如果你按顺序编写资源,你可能不需要使用它。
如果您的这些建议无法为您提供正确的方法,请post一个您遇到问题的相关片段,我会尽力帮助您。
更新
由于 apt 在更新过程中遇到很多失败,我会重试几次并定期更新。
apt_update 'update_packages' do
retries 3
action [:update, :periodic]
end
根据您使用的 chef-client 版本,apt
资源已捆绑到 chef 标准资源集合中,而不是使用 apt
cookbook。
因此您可能不需要在 metadata.rb
文件中指定对 apt
cookbook 的依赖。另外,请确保内置 apt
和 apt
食谱功能之间没有冲突。
如果您希望所有节点在启动时都有 apt_update
步骤,那么将使用 apt_update
的配方放在您的基本厨师角色中,并确保每个节点 运行 这个食谱(通过 运行 宁 base
角色)首先在节点 运行-列表中。
在使用 apt_repository
时,您没有为资源指定任何选项,例如 arch
和其他选项。确保这是你想要的。
当使用 apt_package
安装 php 软件包时,无需再次更新 apt 存储库。因此,无需在每次调用 apt_package
时通知 apt_update
。
一些背景
- 我正在使用 Vagrant 和 chef-zero;厨师服务器不是我的一部分 等式
- 我有两个角色:
base
和infrastructure
,还有两个 食谱:apt
和php
。base
角色的目的是进行一些基本的供应和包管理,并从 github 克隆存储库等。apt
食谱有一个食谱,update_upgrade.rb
运行 是一个execute
资源,可以有效地调用apt update
、apt upgrade
、apt-get autoremove
等等 infrastructure
角色通过php
说明书设置 PHP。稍后会包含更多内容,但它是我的需求的一个很好的例子。php
食谱有两个食谱:add_repository.rb
和install.rb
。add_repository
配方 运行 是一个execute
资源,用于将ondrej/php
存储库添加到apt
。install
配方遍历软件包列表,以便从添加的存储库安装 php。这就是实用程序发挥作用的地方。
关键是,我需要 运行 apt update
在添加 PHP 存储库之后和安装它的软件包之前。实现此目标的最佳方法是什么?
我试过的
最初,我将我的 add_repository
和 install
资源组合成一个 install
食谱,并计划使用 include_recipe apt::update_upgrade
插入我的 apt
食谱的 execute
资源到该食谱中。然而,在搜索了 chef 文档和这篇方便的文章:Should I use include_recipe or add the recipe to run_list? 之后,似乎 include_recipe
并没有立即 运行 它所在的位置。上述文章中的建议是使用 运行 列表来指示食谱的精确执行,厨师文档确实建议食谱按照列出的顺序执行。
这导致我将 php 资源分解为 add_repository
和 install
,并为 infrastructure
使用以下角色 运行 列表:
"run_list": [
"recipe[php::add_repository]",
"recipe[apt::update_upgrade]",
"recipe[php::install]"
]
我的 php
食谱 metadata.rb
有 depends apt
,Chef 没有出错。但是,它也不会在 add_repository
之后触发 update_upgrade
配方。相反,install
配方在 add_repository
之后的 运行 秒会导致错误。
这一切让我假设角色 运行 列表也以类似于 include_recipe
的阶段执行。这准确吗?
我的结论
如果这些假设是准确的,那么用新存储库更新 apt 的唯一可靠方法似乎是将我的 execute
资源从我的 apt
食谱复制到我的 `[=156= 】 食谱。我内心的 DRY-ist 对此尖叫;因此,实用程序的问题 recipe/resource.
编辑
使用 apt
资源
正如原回答者所指出的,对于这个具体描述的用例是使用 apt_package
、apt_update
和 apt_repository
的组合。以下是我如何设置它以获得我想要的:
在上述apt
食谱中,我现在有两个食谱,install.rb
和update.rb
。关键配方是 update
:
apt_update 'update_packages' do
action :update
end
根据文档 (https://docs.chef.io/resource_apt_update.html),:update
操作将在 Chef Infra 客户端 运行 启动时更新 Apt 存储库。这对我很有用,因为我想在我的 VM 首次启动时更新我的 OS 包。
这是我的 base
角色的 运行 列表,它使用了 apt::update
配方:
"run_list": [
"recipe[apt::install]",
"recipe[apt::update]",
...
]
接下来,PHP。首先,我想添加 ondrej/php
存储库,然后遍历软件包列表并安装它们。最后,我想在安装新软件包后 运行 apt update
。
我做的第一件事是再次确保我的 php
食谱的 metadata.rb
有:
depends 'apt'
这将允许我重用我在 apt
食谱中定义的 apt_update['update_packages'] 资源。
我的 php
食谱中的 install.rb
食谱现在包含以下内容:
# Add PHP repository
apt_repository 'php7' do
uri "ppa:#{node[:infrastructure][:php][:repository][:name]}"
action :add # I know this is unnecessary, but I like to be explicit
end
# Install PHP
node[:infrastructure][:php][:extensions][:list].each do |package|
apt_package package do
action :install
notifies :update, 'apt_update[update_packages]', :delayed
end
end
由于我遍历了存储在属性中的包列表,所以在使用 :delayed
计时器安装所有 php 包后,我通知 apt_update[update_packages]
资源。
最后,这里是处理 PHP 说明书执行的 infrastructure
角色:
"run_list": [
"recipe[php::install]"
]
这个解释很好地处理了上面的用例,现在希望使用适当的 Chef 资源。但是,还有一些其他 Apt 操作未包含在资源中,并且可能仍需要一些特定的 execute
资源。考虑 this apt_cleanup cookbook 中的食谱,其中包括:
- 正在清理 apt-cache
- 清除已删除包中的剩余物
- 删除旧的未使用的内核(为了更干净的 /boot)
- 删除已删除的包拖入的依赖项
查看这些食谱,我看到了 execute
资源的集合,这意味着对于这些操作,execute
方法可能仍然是必要的。 (尽管在食谱中)。
最佳做法是将适当的厨师资源与 notification 结合使用。
因为您正在使用 apt
,请使用适当的 apt
资源,例如 apt_update
(to make sure apt repositories are up to date), apt_package
(to manipulate packages using apt, apt_repository
(to add apt respository) and try to avoid using execute
resource to do all of that - this will take advantage of chef idompotance (you might like reading Thinking Like a Chef)
每个厨师资源,可以通知and\or订阅通知。但如果你按顺序编写资源,你可能不需要使用它。
如果您的这些建议无法为您提供正确的方法,请post一个您遇到问题的相关片段,我会尽力帮助您。
更新
由于 apt 在更新过程中遇到很多失败,我会重试几次并定期更新。
apt_update 'update_packages' do
retries 3
action [:update, :periodic]
end
根据您使用的 chef-client 版本,apt
资源已捆绑到 chef 标准资源集合中,而不是使用 apt
cookbook。
因此您可能不需要在 metadata.rb
文件中指定对 apt
cookbook 的依赖。另外,请确保内置 apt
和 apt
食谱功能之间没有冲突。
如果您希望所有节点在启动时都有 apt_update
步骤,那么将使用 apt_update
的配方放在您的基本厨师角色中,并确保每个节点 运行 这个食谱(通过 运行 宁 base
角色)首先在节点 运行-列表中。
在使用 apt_repository
时,您没有为资源指定任何选项,例如 arch
和其他选项。确保这是你想要的。
当使用 apt_package
安装 php 软件包时,无需再次更新 apt 存储库。因此,无需在每次调用 apt_package
时通知 apt_update
。