4

我正在调整 Apache 食谱以使用 2.4 Apache。Opscode 食谱目前失败,因为它正在生成带有 LockFile 关键字的 conf 文件,该关键字从 Apache 2.4 关键字列表中排除。

我想制定一个通用解决方案,并根据软件版本填充我的 conf 文件。为此,我必须找出已安装软件的版本。同样的问题已经困扰我大约一段时间了,但我一直在设法避免它。由于我一遍又一遍地处理它,我想问:

如何找出已安装软件包/软件的版本,如果说明书没有指定它,即安装最新的可用版本?

注意:请不要告诉我将命令传递给底层 shell。我想知道是否有更好的、更多的……Chefy 方式?也许与Ohai有关?

编辑:似乎我被误解了。我想知道是否有抽象平台层的解决方案(就像 Ohai 所做的那样),我会说类似gimme_version('apache')并获取已安装的 apache 版本。我想避免case node['platform_family'] when... when... when在内部使用特定于平台的代码进行编写。

4

2 回答 2

2

我创建了为我解决问题的 Ohai 插件。将以下代码放入 .rb 文件中,并将文件放入ohai/plugin/linux文件夹中。(无法提供绝对路径,因为它因平台和安装类型而异)

Ohai.plugin(:PackageVersion) do
  provides "package_version"

  depends "platform_family"

  collect_data do
    pckg_list = Hash.new
    case platform_family
      when 'debian'
        pckg_list = eval '{'+`dpkg-query -W -f='"${Package}"=> "${Version}", '`+'}'
      when 'rhel' || 'fedora'
        pckg_list = eval '{'+`rpm -qa --queryformat '"%{NAME}"=> "%{VERSION}", '`+'}'
      when 'arch'
        pckg_list = eval '{'+`package-query -Q -f '"%n"=> "%v", '`+'}'
      when 'gentoo'
        pckg_list = eval '{'+`equery list --format='"$name" => "$version", ' '*'`+'}'
      end                                                                                                    
    package_version Mash.new pckg_list
  end                                                                                                                   
end    

下次运行 Chef 时,包版本信息将在node["package_version"]["<package_name>"]eg中node["package_version"]["glibc"]。我让它适用于 5 个平台系列,但对于 Arch,您必须确保已package-query安装。

重要提示:在执行 Chef 配方之前加载/填充 Ohai。此解决方案不会自动更新 Ohai,因此如果您想访问新安装/升级包的数据,在当前 Chef 运行期间,您必须手动重新加载 Ohai。为此,请将以下块放置在包安装/升级块下的配方中,如下所示:

#example package instalation
package "whatever"

ohai "reload_ohai" do
  action :reload
end

感谢@markoconnor。该解决方案基于他指出的社区插件。那些不再在线。我将它们调整为与 Chef 11.0+ 一起使用,它们就在这里。

于 2015-08-29T02:10:05.060 回答
1

@Konzula 的答案的改进,避免使用 eval。也不需要 archlinux 上的包查询。它仍然在 gentoo 上使用 equery,如果尚未安装,可以从 app-portage/gentoolkit 安装。

Ohai.plugin(:PackageVersion) do
  provides 'package_version'

  depends 'platform_family'

  collect_data do
    list = case platform_family
          when 'debian'
            `dpkg-query -W -f='${Package} ${Version}\\n'`
          when 'rhel' || 'fedora'
            `rpm -qa --queryformat '%{NAME} %{VERSION}\\n'`
          when 'arch'
            `pacman -Q`
          when 'gentoo'
            `equery list --format='$name $version' '*'`
          end
    package_version Mash[list.lines.map(&:split)]
  end
end
于 2018-01-20T04:59:27.043 回答