首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何动态地将散列数组对象传递给主厨ERB模板资源

如何动态地将散列数组对象传递给主厨ERB模板资源
EN

Stack Overflow用户
提问于 2022-05-25 00:51:14
回答 1查看 105关注 0票数 1

尝试使用模板资源在Chef中使用数组作为源配置多个yum。有些回购包含或排除了参数。有些是针对镜子的,大多数是针对单一的基准线。简而言之,repos定义在参数上不是完全相同的。下面是我的Chef属性文件中回购定义的一个示例。

代码语言:javascript
复制
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。请记住,这是我在食谱中正在做的事情的缩写。除了使用这些数组项的模板之外,我还调用其他资源。但是对于repo文件模板资源,我想要除这两项之外的所有内容。到目前为止,我还无法以动态的方式完成这一任务(比如在提要模板中,除了这两个值之外的所有内容)。如果所有的回购都有完全相同的参数,这不会是一个问题,但他们没有。

为了开始故障排除,我只是尝试从数组中传递所有参数,如下所示:

代码语言:javascript
复制
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

然后,在我的模板文件中,我尝试如下:

代码语言:javascript
复制
# This file was generated by Chef
# Do NOT modify this file by hand.
[<%= @repoid %>]
<%  @repo_config.each do |key, value| -%>
<%= key %>=<%= value %>
<% end -%>

但以下几个方面都失败了:

代码语言:javascript
复制
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

在更低的输出中,我看到:

代码语言:javascript
复制
           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

因此,Chef似乎无法遍历提供给模板的repo_config变量。显然是被视为字符串对象??

这甚至可以做到吗?我的搜索都没有找到解决方案,我有限的大脑现在已经被烧焦了。

EN

回答 1

Stack Overflow用户

发布于 2022-05-25 04:43:13

这似乎是由于在为模板分配变量时使用了"#{...}"。当我尝试使用您的代码时,我得到了错误:

代码语言:javascript
复制
undefined method `each' for #<String:0x0000000004ed6238>

从您的错误中也可以看到,repo_config是一个字符串。注意消息中的"{

代码语言:javascript
复制
"{\"baseurl\"=>\"https://rpm.mydomain.lan/repos/chef-stable\", ...

而哈希看起来则是:

代码语言:javascript
复制
{"baseurl"=>"https://rpm.ecmc.lan/repos/chef-stable", ...

变量分配不需要使用"#{...}"。下面分配的变量似乎将散列强制转换为字符串,这就是为什么.each方法不能工作的原因。

代码语言:javascript
复制
    variables(repoid: "#{reponame}",
              repo_config: "#{config}")

考虑到这一点,下面的资源声明应该工作得很好:

代码语言:javascript
复制
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

您甚至可以考虑使用资源库资源。它可以管理您的YUM存储库,而不必编写模板。一个简单的例子,没有所有的属性:

代码语言:javascript
复制
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

唯一的考虑是需要对布尔人的属性进行调整,例如:

代码语言:javascript
复制
  'name': 'Extra Packages for Enterprise Linux 7 - $basearch',
  'enabled': true,
  'gpgcheck': true,
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72370911

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档