如何动态馈送哈希数组对象到厨师ERB模板资源
尝试使用模板资源使用数组作为厨师的来源来配置多个YUM存储库。一些存储库具有包括或排除参数。有些是针对镜子大多数瞄准单个碱基的目标。简而言之,回购定义在参数方面并非相同。这是我厨师属性文件中回购定义的示例。
default['ecmc_yum_repo']['server']['repos']['chef-stable'] = {
'baseurl': 'https://rpm.ecmc.lan/repos/chef-stable',
'name': 'Chef Repo',
'enabled': '0',
'gpgcheck': '1',
'gpgkey': 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CHEF',
'gpgkeysource': 'https://packages.chef.io/chef.asc',
'gpgkeyversion': 'gpg-pubkey-83ef826a-4a690bb4',
'includepkgs': 'chef-workstation',
}
default['yum_repo']['server']['repos']['epel'] = {
'name': 'Extra Packages for Enterprise Linux 7 - $basearch',
'enabled': '1',
'gpgcheck': '1',
'gpgkey': 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7',
'gpgkeysource': 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7',
'gpgkeyversion': 'gpg-pubkey-352c64e5-52ae6884',
'metalink': 'https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=x86_64',
}
default['yum_repo']['server']['repos']['teams'] = {
'baseurl': 'https://packages.microsoft.com/yumrepos/ms-teams',
'name': 'Microsoft Teams Repo',
'enabled': '0',
'exclude': 'teams-insiders*',
'gpgcheck': '1',
'gpgkey': 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-MICROSOFT',
'gpgkeysource': 'https://packages.microsoft.com/keys/microsoft.asc',
'gpgkeyversion': 'gpg-pubkey-be1229cf-5631588c',
}
在我的厨师食谱中,当我循环浏览阵列时,我想将阵列中的所有项目馈送到我的模板资源中,这些物品将创建YUM回购文件,除了GPGKeySource和GPGKeyversion。请记住,这缩短了我在食谱中所做的事情。除了使用这些数组项目的模板外,我还会调用其他资源。但是对于回购文件模板资源,我除了这两个项目外都需要所有。到目前为止,我一直无法以动态的方式实现这一目标(就像在模板中一样,除了这两个值以外的所有内容)。如果所有存储库都具有完全相同的参数,那将不是问题,但事实并非如此。
要开始故障排除,我只是尝试将所有参数传递到阵列中的所有参数如下:
node['yum_repo']['server']['repos'].each do |reponame, config|
# Create repositories
template "/etc/yum.repos.d/#{reponame}.repo" do
source 'repofile.repo.erb'
owner 'root'
group 'root'
mode '0644'
variables(repoid: "#{reponame}",
repo_config: "#{config}")
action :create
end
end
我的模板文件中,我尝试以下操作:
# This file was generated by Chef
# Do NOT modify this file by hand.
[<%= @repoid %>]
<% @repo_config.each do |key, value| -%>
<%= key %>=<%= value %>
<% end -%>
将失败。
Error executing action `create` on resource 'template[/etc/yum.repos.d/chef-stable.repo]'
Chef::Mixin::Template::TemplateError
------------------------------------
undefined method `each' for "{\"baseurl\"=>\"https://rpm.mydomain.lan/repos/chef-stable\", \"name\"=>\"Chef Repo\", \"enabled\"=>\"0\", \"gpgcheck\"=>\"1\", \"gpgkey\"=>\"file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CHEF\", \"gpgkeysource\"=>\"https://packages.chef.io/chef.asc\", \"gpgkeyversion\"=>\"gpg-pubkey-83ef826a-4a690bb4\", \"includepkgs\"=>\"chef-workstation\"}":String
这
Compiled Resource:
------------------
# Declared in /tmp/kitchen/cache/cookbooks/yum_repo/recipes/repo-non-amazon.rb:43:in `block in from_file'
template("/etc/yum.repos.d/chef-stable.repo") do
action [:create]
default_guard_interpreter :default
source "repofile.repo.erb"
declared_type :template
cookbook_name "yum_repo"
recipe_name "repo-non-amazon"
owner "root"
group "root"
mode "0644"
variables {:repoid=>"chef-stable", :repo_config=>"{\"baseurl\"=>\"https://rpm.mydomain.lan/repos/chef-stable\", \"name\"=>\"Chef Repo\", \"enabled\"=>\"0\", \"gpgcheck\"=>\"1\", \"gpgkey\"=>\"file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CHEF\", \"gpgkeysource\"=>\"https://packages.chef.io/chef.asc\", \"gpgkeyversion\"=>\"gpg-pubkey-83ef826a-4a690bb4\", \"includepkgs\"=>\"chef-workstation\"}"}
path "/etc/yum.repos.d/chef-stable.repo"
end
Template Context:
-----------------
on line #4
2: # Do NOT modify this file by hand.
3: [<%= @repoid %>]
4: <% @repo_config.each do |key, value| -%>
5: <%= key %>=<%= value %>
6: <% end -%>
System Info:
------------
chef_version=17.1.35
platform=amazon
platform_version=2
ruby=ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [x86_64-linux]
program_name=/opt/chef/bin/chef-client
executable=/opt/chef/bin/chef-client
Running handlers:
[2022-05-24T14:57:42-05:00] ERROR: Running exception handlers
Running handlers complete
[2022-05-24T14:57:42-05:00] ERROR: Exception handlers complete
Chef Infra Client failed. 0 resources updated in 06 seconds
[2022-05-24T14:57:42-05:00] FATAL: Stacktrace dumped to /tmp/kitchen/cache/chef-stacktrace.out
[2022-05-24T14:57:42-05:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2022-05-24T14:57:42-05:00] FATAL: Chef::Mixin::Template::TemplateError: undefined method `each' for "{\"baseurl\"=>\"https://rpm.mydomain.lan/repos/chef-stable\", \"name\"=>\"Chef Repo\", \"enabled\"=>\"0\", \"gpgcheck\"=>\"1\", \"gpgkey\"=>\"file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CHEF\", \"gpgkeysource\"=>\"https://packages.chef.io/chef.asc\", \"gpgkeyversion\"=>\"gpg-pubkey-83ef826a-4a690bb4\", \"includepkgs\"=>\"chef-workstation\"}":String
在 通过馈送到模板的repo_config变量进行迭代。显然被视为字符串对象?
这甚至可以完成吗?我的搜索都没有产生解决方案,而我有限的大脑现在已经油炸了。
Trying to configure multiple yum repos using an array as the source in Chef using the Template resource. Some repos have includpkgs or exclude parameters. Some are targeting mirrors most target a single baseurl. In short, the repos definitions are not identical parameter-wise. Here's an example of the repo definitions in my Chef attributes file.
default['ecmc_yum_repo']['server']['repos']['chef-stable'] = {
'baseurl': 'https://rpm.ecmc.lan/repos/chef-stable',
'name': 'Chef Repo',
'enabled': '0',
'gpgcheck': '1',
'gpgkey': 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CHEF',
'gpgkeysource': 'https://packages.chef.io/chef.asc',
'gpgkeyversion': 'gpg-pubkey-83ef826a-4a690bb4',
'includepkgs': 'chef-workstation',
}
default['yum_repo']['server']['repos']['epel'] = {
'name': 'Extra Packages for Enterprise Linux 7 - $basearch',
'enabled': '1',
'gpgcheck': '1',
'gpgkey': 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7',
'gpgkeysource': 'https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7',
'gpgkeyversion': 'gpg-pubkey-352c64e5-52ae6884',
'metalink': 'https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=x86_64',
}
default['yum_repo']['server']['repos']['teams'] = {
'baseurl': 'https://packages.microsoft.com/yumrepos/ms-teams',
'name': 'Microsoft Teams Repo',
'enabled': '0',
'exclude': 'teams-insiders*',
'gpgcheck': '1',
'gpgkey': 'file:///etc/pki/rpm-gpg/RPM-GPG-KEY-MICROSOFT',
'gpgkeysource': 'https://packages.microsoft.com/keys/microsoft.asc',
'gpgkeyversion': 'gpg-pubkey-be1229cf-5631588c',
}
In my Chef recipe, as I loop through the arrays, I would like to feed all the items in the array to the my template resource that will create the yum repo file EXCEPT for the gpgkeysource and gpgkeyversion. Keep in mind this is shortened view of what I'm doing in the recipe. I'm calling other resources besides template that use those array items. But for the repo file template resource, I want all but those two items. So far I've been unable to accomplish this in a dynamic fashion (as in feed the template everything but these two values). If all the repos had the exact same parameters it wouldn't be a problem,but they don't.
To start troubleshooting I'm simply trying to pass all the parameters from the arrays as follows:
node['yum_repo']['server']['repos'].each do |reponame, config|
# Create repositories
template "/etc/yum.repos.d/#{reponame}.repo" do
source 'repofile.repo.erb'
owner 'root'
group 'root'
mode '0644'
variables(repoid: "#{reponame}",
repo_config: "#{config}")
action :create
end
end
In my template file, I then attempt the following:
# This file was generated by Chef
# Do NOT modify this file by hand.
[<%= @repoid %>]
<% @repo_config.each do |key, value| -%>
<%= key %>=<%= value %>
<% end -%>
This fails with:
Error executing action `create` on resource 'template[/etc/yum.repos.d/chef-stable.repo]'
Chef::Mixin::Template::TemplateError
------------------------------------
undefined method `each' for "{\"baseurl\"=>\"https://rpm.mydomain.lan/repos/chef-stable\", \"name\"=>\"Chef Repo\", \"enabled\"=>\"0\", \"gpgcheck\"=>\"1\", \"gpgkey\"=>\"file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CHEF\", \"gpgkeysource\"=>\"https://packages.chef.io/chef.asc\", \"gpgkeyversion\"=>\"gpg-pubkey-83ef826a-4a690bb4\", \"includepkgs\"=>\"chef-workstation\"}":String
Farther down in the output I see:
Compiled Resource:
------------------
# Declared in /tmp/kitchen/cache/cookbooks/yum_repo/recipes/repo-non-amazon.rb:43:in `block in from_file'
template("/etc/yum.repos.d/chef-stable.repo") do
action [:create]
default_guard_interpreter :default
source "repofile.repo.erb"
declared_type :template
cookbook_name "yum_repo"
recipe_name "repo-non-amazon"
owner "root"
group "root"
mode "0644"
variables {:repoid=>"chef-stable", :repo_config=>"{\"baseurl\"=>\"https://rpm.mydomain.lan/repos/chef-stable\", \"name\"=>\"Chef Repo\", \"enabled\"=>\"0\", \"gpgcheck\"=>\"1\", \"gpgkey\"=>\"file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CHEF\", \"gpgkeysource\"=>\"https://packages.chef.io/chef.asc\", \"gpgkeyversion\"=>\"gpg-pubkey-83ef826a-4a690bb4\", \"includepkgs\"=>\"chef-workstation\"}"}
path "/etc/yum.repos.d/chef-stable.repo"
end
Template Context:
-----------------
on line #4
2: # Do NOT modify this file by hand.
3: [<%= @repoid %>]
4: <% @repo_config.each do |key, value| -%>
5: <%= key %>=<%= value %>
6: <% end -%>
System Info:
------------
chef_version=17.1.35
platform=amazon
platform_version=2
ruby=ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [x86_64-linux]
program_name=/opt/chef/bin/chef-client
executable=/opt/chef/bin/chef-client
Running handlers:
[2022-05-24T14:57:42-05:00] ERROR: Running exception handlers
Running handlers complete
[2022-05-24T14:57:42-05:00] ERROR: Exception handlers complete
Chef Infra Client failed. 0 resources updated in 06 seconds
[2022-05-24T14:57:42-05:00] FATAL: Stacktrace dumped to /tmp/kitchen/cache/chef-stacktrace.out
[2022-05-24T14:57:42-05:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2022-05-24T14:57:42-05:00] FATAL: Chef::Mixin::Template::TemplateError: undefined method `each' for "{\"baseurl\"=>\"https://rpm.mydomain.lan/repos/chef-stable\", \"name\"=>\"Chef Repo\", \"enabled\"=>\"0\", \"gpgcheck\"=>\"1\", \"gpgkey\"=>\"file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CHEF\", \"gpgkeysource\"=>\"https://packages.chef.io/chef.asc\", \"gpgkeyversion\"=>\"gpg-pubkey-83ef826a-4a690bb4\", \"includepkgs\"=>\"chef-workstation\"}":String
So it seems Chef is not able to iterate through the repo_config variable that is fed to the template. Apparently is being seen as a String object??
Can this even be accomplished? None of my searches has yielded a solution and my limited brain is fried by now.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这似乎是由于模板变量分配期间使用
“#{...}”
。当我尝试使用您的代码时,我会发现错误:也从您的错误中,我们可以看到
repo_config
是字符串。 在消息中。注意
“ {
请 以下似乎已将哈希人施加到一个字符串中,这就是为什么
。
方法不起作用,以下资源声明应效果很好:
您甚至可以考虑使用<<<< href =“ https://docs.chef.io/resources/yum_repository/” rel =“ nofollow noreferrer”> yum_repository Resource 它可以管理您的Yum reposoritories。所有属性:
唯一考虑的是,需要针对以下布尔来调整属性:
This seems to be due to the use of
"#{...}"
during the variable assignment for template. When I tried with your code, I get the error:From your error also, we can see that the
repo_config
is a string. Note the"{
in the message.Whereas a Hash would look like:
The use of
"#{...}"
is not required for variable assignment. Variable assigned as below seems to have coerced the hash into a string, and that's why the.each
method doesn't work.With this in mind, the below resource declaration should work fine:
You could even consider using the yum_repository resource. It can manage your YUM repositories without having to write templates. A simple example, without all of the properties:
Only consideration is that the attributes need to be adjusted for booleans such as: