Как узнать версию программного комплекса, установленного на узле?

Я адаптирую кулинарную книгу Apache для работы с Apache 2.4. В настоящее время кулинарная книга Opscode не работает, потому что она генерирует файл конфигурации с ключевым словом LockFile, которое исключено из списка ключевых слов Apache 2.4.

Я хочу сделать общее решение и заполнить свой файл конфигурации в зависимости от версии программного обеспечения. Для этого мне нужно узнать версию уже установленного программного обеспечения. Этот же вопрос беспокоил меня уже некоторое время, но мне удавалось избегать его. Поскольку я возвращаюсь к этому снова и снова, я хотел бы спросить:

Как узнать версию установленного пакета/программы, если поваренная книга не указывает ее, т.е. устанавливает последнюю доступную версию?

Примечание. Пожалуйста, не говорите мне передать команду базовой оболочке. Я хотел бы знать, есть ли лучший, более... Chefy способ? Может быть, что-то связанное с Охаем?

РЕДАКТИРОВАТЬ: Кажется, меня неправильно поняли. Я хотел знать, есть ли решение, которое абстрагирует уровень платформы (точно так же, как это делает Ohai), где я бы сказал что-то вроде gimme_version('apache') и получил установленную версию apache. Я хочу избежать написания case node['platform_family'] when... when... when со специфичным для платформы кодом внутри.


person Konzulic    schedule 04.03.2014    source источник
comment
Нет... И Охай в любом случае просто запускает команды оболочки под капотом   -  person sethvargo    schedule 05.03.2014
comment
да, но сверху это независимо от платформы, и это то, что мне нужно - независимое от платформы решение.   -  person Konzulic    schedule 05.03.2014
comment
В этом весь смысл Ohai — он запускает специфичные для платформы команды.   -  person sethvargo    schedule 05.03.2014
comment
См.: docs.opscode.com/community_plugin_ohai.html.   -  person Mark O'Connor    schedule 06.03.2014
comment
@sethvargo, Марк_О'Коннор, извините за беспокойство. Кажется, меня неправильно поняли. Я знаю, как работает Охай. Я прошу подход Ruby/Chef, который хранит специфичный для платформы код под капотом (или иным образом отделен) и делает мой рецепт красивым, чистым и независимым от платформы. Вы знаете что-то подобное? Спасибо!   -  person Konzulic    schedule 06.03.2014
comment
... Все кулинарные книги в opscode-cookbooks на GitHub. Вы хотите использовать операторы case и node['platform_family']   -  person sethvargo    schedule 06.03.2014
comment
@Konzula, ты помнишь, есть ли у тебя решение этой проблемы?   -  person david    schedule 15.04.2015
comment
@Давид, я сделал. Я отредактировал плагин сообщества Ohai (ссылка, размещенная выше Марком О'Коннором). Я сделаю все возможное, чтобы опубликовать свое решение здесь в течение следующих 24 часов.   -  person Konzulic    schedule 15.04.2015


Ответы (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>"], например. node["package_version"]["glibc"]. Я заставил его работать для 5 семейств платформ, но для Arch вам нужно убедиться, что у вас установлено package-query.

Важное примечание: Ohai загружается/заполняется до выполнения рецепта Chef. Это решение не автоматически обновляет Ohai, поэтому, если вы хотите получить доступ к данным недавно установленных/обновленных пакетов во время текущего запуска Chef, вам придется вручную перезагрузить Ohai. Для этого поместите следующий блок к вашему рецепту под блоком установки/обновления пакета, как показано ниже:

#example package instalation
package "whatever"

ohai "reload_ohai" do
  action :reload
end

Спасибо @markoconnor. Это решение основано на плагинах сообщества, на которые он указал. Таких уже нет в сети. Я настроил их для работы с Chef 11.0+, и вот они.

person Konzulic    schedule 29.08.2015
comment
@sethvargo, что вы скажете об этом решении? Эти плагины сообщества удалены по уважительной причине, то есть есть ли лучший способ сделать это в наши дни? - person Konzulic; 29.08.2015

Улучшение ответа @Konzula, избегающего использования eval. Также не требует package-query в archlinux. Он по-прежнему использует equery в gentoo, который можно установить из 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
person Bill    schedule 20.01.2018
comment
Спасибо @Bill :) Я рад, что кто-то изучил этот код. Я проверю это, как только найду время и передам вам принятый ответ... - person Konzulic; 01.02.2018