如何使用 Puppet 为非默认 Ruby 安装 gem?

如何使用 Puppet 为非默认 Ruby 安装 gem?

RedHat/CentOS-6 附带的 ruby​​ 版本为 1.8.7,对于许多应用程序来说太旧了。虽然可以使用自定义 RPM 对其进行更新,但我的同事们对此持保留态度,希望使用rh-ruby22可用的软件包SCL 回购

这样就安装了 ruby​​-2.2,这很好,但在 下/opt/rh/rh-ruby22。我现在需要安装几个 gem,显然我想使用 Puppet:

package {'example':
  ensure   => '0.25',
  provider => 'gem'
}

不幸的是,需要调用 gem-provider/usr/bin/gem而不是/opt/rh/rh-ruby22/root/usr/bin/gem那个。还有其他方法吗?谢谢!

答案1

包裹资源,特别是宝石 提供者,现在支持使用command属性。您的特定示例现在得到如下支持:

package {'example':
  ensure   => '0.25',
  provider => 'gem',
  command  => '/opt/rh/rh-ruby22/root/usr/bin/gem'
}

答案2

好吧,“简单”的方法是实现自己的包提供者。幸运的是,你可以从现有的 gem 提供者继承所有内容,而只覆盖 gem 命令本身。

因为 SCL 的 rh-ruby22 太弱智了,你甚至无法直接调用它的rubygem——无需LD_LIBRARY_PATH先设置——我们在 中为它们创建包装器/usr/bin/usr/bin/gem2例如,设置库路径(和PATH),然后使用其自己的参数exec设置 real /opt/rh/rh-ruby22/root/usr/bin/gem"$@")。

我的新提供商使用gem2包装脚本来完成其工作。

gem2.rb我创建了包含modules/SOMEMODULE/lib/puppet/provider/package/以下内容的文件(使用 Puppet-3.8.7 测试):

require 'puppet/provider/package'

Puppet::Type.type(:package).provide File.basename(__FILE__, ".rb"),
    :parent => :gem, :source => :gem do
        desc "Ruby Gem support using #{@name}-executable"

        commands :gemcmd => @name.to_s
end

虽然我希望我的实现能够允许将 gem-command 指定为 puppet-manifest 中的参数,但如果不完全重写现有的 gem-provider,就无法做到这一点。我的方法更简单,而且同样高效。

作为奖励,将文件复制到其他名称(例如gem19.rb)将自动创建新的提供程序 - 只要确保gem19它在 中即可$PATH

您将保存此文件的模块可以任何需要新提供程序的机器所使用的模块。

相关内容