How to find out version of software package installed on the node?
Asked Answered
Y

2

6

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.

Your answered 4/3, 2014 at 17:45 Comment(8)
No... And Ohai just runs shell commands under the hood anywayCallow
yup, but from up above it is platform independent, and that's what I need - platform independent solution.Your
That's the whole point of Ohai though - it runs platform-specific commandsCallow
See: docs.opscode.com/community_plugin_ohai.htmlBabin
@sethvargo, Mark_O'Connor, sorry to bother. It seems I'm misunderstood. I know how Ohai functions. I'm asking for a Ruby/Chef approach that's keeping platform specific code under the hood (or otherwise separated), and make my recipe nice, clean and platform independent. Do you know something like that? Thanks!Your
... All of the cookbooks in opscode-cookbooks on GitHub. You want to use case statements and node['platform_family']Callow
@Konzula do you remember if you got a workaround to this problem?Grenada
@david, I did. I edited Ohai community plugin (link posted above by Mark O'Connor). I'll give my best to post my solution here within next 24 hours.Your
Y
3

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.

Your answered 29/8, 2015 at 2:10 Comment(1)
@sethvargo, what do you say about this solution? Are those community plugins moved away for a good reason, i.e. is there a better way to do it these days?Your
M
1

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
Municipalize answered 20/1, 2018 at 4:59 Comment(1)
Thanks @Municipalize :) I'm happy someone took a look into this code. I'll check this as soon as I find some time and pass accepted answer to you...Your

© 2022 - 2024 — McMap. All rights reserved.