【问题标题】:Chef install series of pre-packaged gems厨师安装系列预打包的gem
【发布时间】:2014-01-02 09:24:02
【问题描述】:

我正在尝试安装我的食谱所需的一系列 gem,但我不想在我的生产机器上安装开发工具(即 gcc、gcc-c++、ruby-devel。有关更多上下文,请参阅 this),因此,我将相关的 gem 文件作为资源包含在我的食谱中。

我正在使用此代码

node["chef_gems"].each do |pkg, attrs|
  gem_file = "#{pkg}-#{attrs["version"]}.gem"
  dest_gem_file = "#{Chef::Config['file_cache_path']}/#{gem_file}"
  cookbook_file "#{dest_gem_file}" do
      source "gems/#{gem_file}"
  end
  if File.exist?("#{dest_gem_file}")
    chef_gem pkg do
      source "#{dest_gem_file}"
      action :install
    end
  end
end

我遇到的问题

  1. 目前这需要两次厨师运行,因为 File.exist?检查但没有它,它无法编译,因为该文件在编译阶段不存在。有没有更简单的方法来做到这一点?
  2. 其中一些 gem 具有依赖关系,因此排序问题似乎默认为字母顺序。我即将通过排序排序键(丑陋)执行命令,想知道是否有更好的方法。
  3. 退后一步,这似乎过于复杂。是否有更简单的策略来实现安装 gem 及其依赖项的目标,而无需在生产服务器上安装开发工具。

这是没有 File.exist 的原始错误?检查

Starting Chef Client, version 11.4.0
resolving cookbooks for run list: ["cis-rhel", "ec2-hostname-rhel", "chef-client", "cassandra"]
Synchronizing Cookbooks:
<REDACTED>
Compiling Cookbooks...
[2013-10-16T18:45:01-04:00] WARN: Cloning resource attributes for user[<REDACTED>] from prior resource (CHEF-3694)
<REDACTED>
[2013-10-16T18:45:01-04:00] WARN: Current  user[cassandra]: /var/chef/cache/cookbooks/cassandra/recipes/user.rb:23:in `from_file'
Recipe: cassandra::packages
  * chef_gem[cassandra-cql] action install
================================================================================
Error executing action `install` on resource 'chef_gem[cassandra-cql]'
================================================================================


Gem::Exception
--------------
Cannot load gem at [/var/chef/cache/cassandra-cql-1.1.4.gem] in /


Cookbook Trace:
---------------
/var/chef/cache/cookbooks/cassandra/recipes/packages.rb:36:in `block in from_file'
/var/chef/cache/cookbooks/cassandra/recipes/packages.rb:29:in `each'
/var/chef/cache/cookbooks/cassandra/recipes/packages.rb:29:in `from_file'
/var/chef/cache/cookbooks/cassandra/recipes/default.rb:23:in `from_file'


Resource Declaration:
---------------------
# In /var/chef/cache/cookbooks/cassandra/recipes/packages.rb

 36:     chef_gem pkg do
 37:       source "#{dest_gem_file}"
 38:       action :install
 39:     end
 40: #  end



Compiled Resource:
------------------
# Declared in /var/chef/cache/cookbooks/cassandra/recipes/packages.rb:36:in `block in from_file'

chef_gem("cassandra-cql") do
  provider Chef::Provider::Package::Rubygems
  action [:install]
  retries 0
  retry_delay 2
  package_name "cassandra-cql"
  source "/var/chef/cache/cassandra-cql-1.1.4.gem"
  cookbook_name "cassandra"
  recipe_name "packages"
end




================================================================================
Recipe Compile Error in /var/chef/cache/cookbooks/cassandra/recipes/default.rb
================================================================================


Gem::Exception
--------------
chef_gem[cassandra-cql] (cassandra::packages line 36) had an error: Gem::Exception: Cannot load gem at [/var/chef/cache/cassandra-cql-1.1.4.gem] in /


Cookbook Trace:
---------------
  /var/chef/cache/cookbooks/cassandra/recipes/packages.rb:36:in `block in from_file'
  /var/chef/cache/cookbooks/cassandra/recipes/packages.rb:29:in `each'
  /var/chef/cache/cookbooks/cassandra/recipes/packages.rb:29:in `from_file'
  /var/chef/cache/cookbooks/cassandra/recipes/default.rb:23:in `from_file'


Relevant File Content:
----------------------
/var/chef/cache/cookbooks/cassandra/recipes/packages.rb:

 29:  node["cassandra"]["chef_gems"].each do |pkg, attrs|
 30:    gem_file = "#{pkg}-#{attrs["version"]}.gem"
 31:    dest_gem_file = "#{Chef::Config['file_cache_path']}/#{gem_file}"
 32:    cookbook_file "#{dest_gem_file}" do
 33:        source "gems/#{gem_file}"
 34:    end
 35:  #  if File.exist?("#{dest_gem_file}")
 36>>     chef_gem pkg do
 37:        source "#{dest_gem_file}"
 38:        action :install
 39:      end
 40:  #  end
 41:  end
 42:  
 43:  # Some distributed packages of Cassandra start the service in their
 44:  # postinstall; keep them all equal and a restart can be done after the configs
 45:  # are written on the first run. Added difficulty: they also come with init



[2013-10-16T18:45:01-04:00] ERROR: Running exception handlers
[2013-10-16T18:45:02-04:00] FATAL: Saving node information to /var/chef/cache/failed-run-data.json
[2013-10-16T18:45:02-04:00] ERROR: Exception handlers complete
Chef Client failed. 0 resources updated
[2013-10-16T18:45:02-04:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
[2013-10-16T18:45:02-04:00] FATAL: Gem::Exception: chef_gem[cassandra-cql] (cassandra::packages line 36) had an error: Gem::Exception: Cannot load gem at [/var/chef/cache/cassandra-cql-1.1.4.gem] in /

【问题讨论】:

  • 请不要忘记将答案标记为正确! :)

标签: chef-infra chef-recipe


【解决方案1】:
  1. 您可以而且应该跳过 if File.exist?("#{dest_gem_file}") 段,因为之前的资源总是会创建文件或引发异常。
  2. 如果可以的话,使用可以处理依赖关系的包管理器安装这些可能是一个更好的选择。
  3. 如果使用 rubygems 包管理器因为它需要编译包的本地扩展而无法执行此操作,您可以考虑打包已编译的版本并使用系统包管理器来安装它们。

【讨论】:

  • re: 1. 我想但是当我尝试时我得到一个食谱编译错误我相信是因为两个阶段的厨师处理(即它试图编译食谱并因为文件没有'尚不存在,因此永远不会进入创建它的执行阶段)。添加 if 是“修复”的,但仍然需要两个厨师运行。如果您认为我遗漏了什么并且前面的解释没有意义,我可以发布该错误的详细信息。
  • 不,我的错误 - chef_gem 在配方编译阶段之前/期间安装 gem,以便可以立即在配方中使用它们。这仅在您打算使用厨师食谱中的宝石时才有用,否则您应该使用 gem_package 资源(不需要 File.exist? 检查)。
  • 我只需要在配方中使用这些,并期望您描述的行为,但它以我描述的方式失败,让我恢复到该状态(需要一点时间)并回发错误,也许我误读了那里的原因
  • 我已经用没有 File.exist 的情况下出现的错误更新了原始帖子?查看。 AFAICT,由于错误消息和目标系统上尚不存在该文件,因此在编译阶段发生这种情况。所以,由于我在配方中确实需要 gem,我想我必须使用 chef_gem 而不是 gem_package 这就是为什么这会失败,因为正如你所说,它试图在编译阶段安装?
  • 是的,要使用配方中的 gem,您必须使用 chef_gem,但这意味着它在第一次运行时无法安装,因为之前已安装 chef_gems运行其他资源(即在编译阶段。因此,如果您想使用 chef 分发 gem(而不是从存储库中托管它们),您将不得不运行 chef 两次并不幸地检查文件是否存在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
  • 1970-01-01
  • 1970-01-01
  • 2019-08-03
  • 1970-01-01
相关资源
最近更新 更多