如何动态馈送哈希数组对象到厨师ERB模板资源

发布于 2025-01-31 19:27:13 字数 5653 浏览 2 评论 0原文

尝试使用模板资源使用数组作为厨师的来源来配置多个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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

穿越时光隧道 2025-02-07 19:27:14

这似乎是由于模板变量分配期间使用“#{...}”。当我尝试使用您的代码时,我会发现错误:

undefined method `each' for #<String:0x0000000004ed6238>

也从您的错误中,我们可以看到repo_config是字符串。 在消息中。

"{\"baseurl\"=>\"https://rpm.mydomain.lan/repos/chef-stable\", ...

注意“ {

{"baseurl"=>"https://rpm.ecmc.lan/repos/chef-stable", ...

请 以下似乎已将哈希人施加到一个字符串中,这就是为什么方法不起作用

    variables(repoid: "#{reponame}",
              repo_config: "#{config}")

,以下资源声明应效果很好:

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

您甚至可以考虑使用<<<< href =“ https://docs.chef.io/resources/yum_repository/” rel =“ nofollow noreferrer”> yum_repository Resource 它可以管理您的Yum reposoritories。所有属性:

node['yum_repo']['server']['repos'].each do |reponame, repoconfig|
  yum_repository reponame do
    baseurl repoconfig['baseurl']
    description repoconfig['name']
    enabled repoconfig['enabled']
    metalink repoconfig['metalink']
    action :create
  end
end

唯一考虑的是,需要针对以下布尔来调整属性:

  'name': 'Extra Packages for Enterprise Linux 7 - $basearch',
  'enabled': true,
  'gpgcheck': true,

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:

undefined method `each' for #<String:0x0000000004ed6238>

From your error also, we can see that the repo_config is a string. Note the "{ in the message.

"{\"baseurl\"=>\"https://rpm.mydomain.lan/repos/chef-stable\", ...

Whereas a Hash would look like:

{"baseurl"=>"https://rpm.ecmc.lan/repos/chef-stable", ...

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.

    variables(repoid: "#{reponame}",
              repo_config: "#{config}")

With this in mind, the below resource declaration should work fine:

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

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:

node['yum_repo']['server']['repos'].each do |reponame, repoconfig|
  yum_repository reponame do
    baseurl repoconfig['baseurl']
    description repoconfig['name']
    enabled repoconfig['enabled']
    metalink repoconfig['metalink']
    action :create
  end
end

Only consideration is that the attributes need to be adjusted for booleans such as:

  'name': 'Extra Packages for Enterprise Linux 7 - $basearch',
  'enabled': true,
  'gpgcheck': true,
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文