Question

I'm adapting Apache cookbook to work with 2.4 Apache. Opscode cookbook is currently failing because it's generating conf file with LockFile keyword that is excluded from the list of the Apache 2.4 keywords.

I want to make a general solution, and populate my conf file depending on the version of software. To do so, I have to find out what's the version of already installed software. This same question has been bothering me for about a time now, but I've been managing to avoid it. Since I'm getting to it over and over again, I'd like to ask:

How to find out version of installed package/software, if cookbook doesn't specify it, i.e. installs latest available one?

Note: Please don't tell me to pass the command to the underlying shell. I'd like to know if there is a better, more... Chefy way? Maybe something related to Ohai?

EDIT: Seems I'm misunderstood. I wanted to know if there's a solution that abstracts the platform layer (just like Ohai does), where I'd say something like gimme_version('apache') and get the installed apache version. I want to avoid writing case node['platform_family'] when... when... when with platform specific code inside.

Was it helpful?

Solution

I created Ohai plugin that solves the issue for me. Place the following code into a .rb file, and put the file into ohai/plugin/linux folder. (Cannot provide absolute path since it varies depending on the platform and installation type)

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    

Next time you run Chef, package version information will be in node["package_version"]["<package_name>"] e.g. node["package_version"]["glibc"]. I made it work for 5 platform families, but for Arch you'll have to make sure you have package-query installed.

Important note: Ohai is loaded/populated before Chef recipe execution. This solution will not automatically update Ohai, so if you want to access data of the newly installed/upgraded packages, during current Chef run, you'll have to manually reload Ohai. To do it, place following block to your recipe under the package installation/upgrade block, just like shown below:

#example package instalation
package "whatever"

ohai "reload_ohai" do
  action :reload
end

Thanks to @markoconnor. This solution is based on community plugins he pointed out. Those are no longer online. I adjusted them to work with Chef 11.0+ and here they are.

OTHER TIPS

An improvement on @Konzula's answer avoiding the use of eval. Also doesn't require package-query on archlinux. It does still make use of equery on gentoo, which can be installed from app-portage/gentoolkit if it is not already installed.

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top