在厨师的同一属性文件中的其他属性中使用属性值
Using attribute values in other attributes within the same attributes file in chef
注意:我这里的例子是为了显示我的问题的上下文,而不是真实世界的例子。
我的 attributes/default.rb
文件中有以下示例:
default[:php] = {
version: '7.3',
repository: 'ondrej/php',
extensions: [
"php7.3",
"php7.3-common",
"php7.3-gd",
"php7.3-mysql",
"php7.3-curl",
"php7.3-intl",
"php7.3-xsl",
"php7.3-mbstring",
"php7.3-zip",
"php7.3-bcmath",
"php7.3-iconv",
"php7.3-soap",
"php7.3-fpm",
"libapache2-mod-php7.3"
],
options: {
:timezone => 'America/Los Angeles',
:memory_limit => '2G',
:max_execution_time => 1800,
:zlib_output_compression => 'On',
:session_save_path => '/var/lib/sessions'
}
}
接下来,我将其传递给这样的模板:
template '/home/vagrant/php_test.txt' do
source node['url'] % {version: node['version']}
source 'php_test.txt.erb'
owner 'vagrant'
group 'vagrant'
mode '0755'
variables(
php: node[:php]
)
end
然后我在模板中引用这些值,如下所示:
PHP Version : <%= @php[:version] %>
PHP Repository : <%= @php[:repository] %>
PHP Extension List:
<% @php[:extensions].each do |extension| %>
<%= "#{extension}" %>
<% end %>
PHP Options List
<% @php[:options].each do |option, value| %>
<%= "#{option}: #{value}" %>
<% end %>
这将生成以下文本文件:
PHP Version : 7.3
PHP Repository : ondrej/php
PHP Extension List:
php7.3
libapache2-mod-php7.3
php7.3-common
php7.3-gd
php7.3-mysql
php7.3-curl
php7.3-intl
php7.3-xsl
php7.3-mbstring
php7.3-zip
php7.3-bcmath
php7.3-iconv
php7.3-soap
php7.3-fpm
PHP Options List
timezone: America/Los Angeles
memory_limit: 2G
max_execution_time: 1800
zlib_output_compression: On
session_save_path: /var/lib/sessions
一切正常;然而,我内心的 DRY-ist 看到了所有那些 7.3
并说,"Hey, why don't you just reference the value of version
within the value of each extension in the list?" 所以,我在我的 attributes/default.rb
文件中尝试这个:
...
extensions: [
"php#{node[:php][:version]}",
"php#{node[:php][:version]}-common",
"php#{node[:php][:version]}-gd",
"php#{node[:php][:version]}-mysql",
"php#{node[:php][:version]}-curl",
"php#{node[:php][:version]}-intl",
"php#{node[:php][:version]}-xsl",
"php#{node[:php][:version]}-mbstring",
"php#{node[:php][:version]}-zip",
"php#{node[:php][:version]}-bcmath",
"php#{node[:php][:version]}-iconv",
"php#{node[:php][:version]}-soap",
"php#{node[:php][:version]}-fpm",
"libapache2-mod-#{node[:php][:version]}"
]
...
这有(至少)两个问题。首先,它没有达到我的预期。当我遍历模板中的数组时,每个值都打印为字符串而不是插值。其次,它打破了这里提到的厨师最佳实践:https://github.com/pulseenergy/chef-style-guide#attributes
那么,在另一个群体中使用一个属性值的最佳方式是什么?
在思考这个问题时,我想到了两个方案:
- 按此处所示使用延迟插值:
https://coderanger.net/derived-attributes/
我的问题是我不太明白建议的概念是如何工作的,因为我的 ruby 技能没有达到标准。
- 存储没有
php-
后缀的扩展,然后在配方中循环它们并将 php
、版本字符串和扩展连接成每个扩展的单个值。将每个存储在一个新数组中,该数组传递给模板。
还有其他方法可以实现吗?可能通过强制 "php{node[:php][:version]}"
属性插入模板?
我不了解 Chef,但阅读最佳实践页面,通过延迟插值派生属性是这里的正确方法。它应该相当简单:
extensions: [
"php%{version}",
"php%{version}-common",
"php%{version}-gd",
# ...
]
稍后,当您渲染它时:
<% @php[:extensions].each do |extension| %>
<%= extension % @php %>
<% end %>
这有点不明显,但它有效,因为 string % hash
将使用 hash
中的键替换字符串中的任何命名占位符。不作为命名占位符存在的哈希值将被忽略。
"test: %{bang}" % {baz: "bin", bang: "bar"}
=> "test: bar"
由于您的 @php
变量有一个 :version
键,如果该字符串包含占位符 %{version}
,它将在呈现时被替换到每个扩展字符串的值中。 =19=]
你也可以更明确地做到这一点:
# Create a hash with the one key:
<%= extension % {version: @php[:version]} %>
# Or, just create a hash by slicing out just the attribute you care about
<%= extension % @php.slice(:version) %>
注意:我这里的例子是为了显示我的问题的上下文,而不是真实世界的例子。
我的 attributes/default.rb
文件中有以下示例:
default[:php] = {
version: '7.3',
repository: 'ondrej/php',
extensions: [
"php7.3",
"php7.3-common",
"php7.3-gd",
"php7.3-mysql",
"php7.3-curl",
"php7.3-intl",
"php7.3-xsl",
"php7.3-mbstring",
"php7.3-zip",
"php7.3-bcmath",
"php7.3-iconv",
"php7.3-soap",
"php7.3-fpm",
"libapache2-mod-php7.3"
],
options: {
:timezone => 'America/Los Angeles',
:memory_limit => '2G',
:max_execution_time => 1800,
:zlib_output_compression => 'On',
:session_save_path => '/var/lib/sessions'
}
}
接下来,我将其传递给这样的模板:
template '/home/vagrant/php_test.txt' do
source node['url'] % {version: node['version']}
source 'php_test.txt.erb'
owner 'vagrant'
group 'vagrant'
mode '0755'
variables(
php: node[:php]
)
end
然后我在模板中引用这些值,如下所示:
PHP Version : <%= @php[:version] %>
PHP Repository : <%= @php[:repository] %>
PHP Extension List:
<% @php[:extensions].each do |extension| %>
<%= "#{extension}" %>
<% end %>
PHP Options List
<% @php[:options].each do |option, value| %>
<%= "#{option}: #{value}" %>
<% end %>
这将生成以下文本文件:
PHP Version : 7.3
PHP Repository : ondrej/php
PHP Extension List:
php7.3
libapache2-mod-php7.3
php7.3-common
php7.3-gd
php7.3-mysql
php7.3-curl
php7.3-intl
php7.3-xsl
php7.3-mbstring
php7.3-zip
php7.3-bcmath
php7.3-iconv
php7.3-soap
php7.3-fpm
PHP Options List
timezone: America/Los Angeles
memory_limit: 2G
max_execution_time: 1800
zlib_output_compression: On
session_save_path: /var/lib/sessions
一切正常;然而,我内心的 DRY-ist 看到了所有那些 7.3
并说,"Hey, why don't you just reference the value of version
within the value of each extension in the list?" 所以,我在我的 attributes/default.rb
文件中尝试这个:
...
extensions: [
"php#{node[:php][:version]}",
"php#{node[:php][:version]}-common",
"php#{node[:php][:version]}-gd",
"php#{node[:php][:version]}-mysql",
"php#{node[:php][:version]}-curl",
"php#{node[:php][:version]}-intl",
"php#{node[:php][:version]}-xsl",
"php#{node[:php][:version]}-mbstring",
"php#{node[:php][:version]}-zip",
"php#{node[:php][:version]}-bcmath",
"php#{node[:php][:version]}-iconv",
"php#{node[:php][:version]}-soap",
"php#{node[:php][:version]}-fpm",
"libapache2-mod-#{node[:php][:version]}"
]
...
这有(至少)两个问题。首先,它没有达到我的预期。当我遍历模板中的数组时,每个值都打印为字符串而不是插值。其次,它打破了这里提到的厨师最佳实践:https://github.com/pulseenergy/chef-style-guide#attributes
那么,在另一个群体中使用一个属性值的最佳方式是什么?
在思考这个问题时,我想到了两个方案:
- 按此处所示使用延迟插值: https://coderanger.net/derived-attributes/
我的问题是我不太明白建议的概念是如何工作的,因为我的 ruby 技能没有达到标准。
- 存储没有
php-
后缀的扩展,然后在配方中循环它们并将php
、版本字符串和扩展连接成每个扩展的单个值。将每个存储在一个新数组中,该数组传递给模板。
还有其他方法可以实现吗?可能通过强制 "php{node[:php][:version]}"
属性插入模板?
我不了解 Chef,但阅读最佳实践页面,通过延迟插值派生属性是这里的正确方法。它应该相当简单:
extensions: [
"php%{version}",
"php%{version}-common",
"php%{version}-gd",
# ...
]
稍后,当您渲染它时:
<% @php[:extensions].each do |extension| %>
<%= extension % @php %>
<% end %>
这有点不明显,但它有效,因为 string % hash
将使用 hash
中的键替换字符串中的任何命名占位符。不作为命名占位符存在的哈希值将被忽略。
"test: %{bang}" % {baz: "bin", bang: "bar"}
=> "test: bar"
由于您的 @php
变量有一个 :version
键,如果该字符串包含占位符 %{version}
,它将在呈现时被替换到每个扩展字符串的值中。 =19=]
你也可以更明确地做到这一点:
# Create a hash with the one key:
<%= extension % {version: @php[:version]} %>
# Or, just create a hash by slicing out just the attribute you care about
<%= extension % @php.slice(:version) %>