Назад | Перейти на главную страницу

Указываете предварительные условия для пользовательских фактов Puppet?

Я написал пользовательский факт Puppet, для которого требуется biosdevname инструмент для установки. Я не уверен, как правильно настроить, чтобы этот инструмент был установлен перед facter пытается создать экземпляр пользовательского факта.

Факты загружаются на ранней стадии процесса, поэтому я не могу просто package { biosdevname: ensure => installed } в манифесте, поскольку к тому времени, когда Puppet заходит так далеко, пользовательский факт уже не работает.

Мне было любопытно, смогу ли я решить эту проблему с помощью этапов запуска Puppet. Я попытался:

stage { pre: before => Stage[main] }
class { biosdevname: stage => pre }

И:

class biosdevname {
  package { biosdevname: ensure => installed }
}

Но это не работает ... Puppet загружает факты перед тем, как войти в pre этап:

info: Loading facts in physical_network_config
./physical_network_config.rb:33: command not found: biosdevname -i eth0
info: Applying configuration version '1320248045'
notice: /Stage[pre]/Biosdevname/Package[biosdevname]/ensure: created

И т.д. Есть ли способ заставить эту работу работать?

РЕДАКТИРОВАТЬ: Я должен прояснить, что понимаю, учитывая подходящий package заявление, что факт будет корректно работать на последующий бежит. Сложность здесь в том, что это часть нашего процесса начальной настройки. Мы запускаем Puppet без кикстарта и хотим, чтобы конфигурация сети была на месте до первой перезагрузки.

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

Также для Zoredache:

# This produces a fact called physical_network_config that describes
# the number of NICs available on the motherboard, on PCI bus 1, and on
# PCI bus 2.  The fact value is of the form <x>-<y>-<z>, where <x>
# is the number of embedded interfaces, <y> is the number of interfaces
# on PCI bus 1, and <z> is the number of interfaces on PCI bus 2.

em = 0
pci1 = 0
pci2 = 0

Dir['/sys/class/net/*'].each {
    |file| devname=File.basename(file)
    biosname=%x[biosdevname -i #{devname}]
    case 
    when biosname.match('^pci1')
        pci1 += 1
    when biosname.match('^pci2')
        pci2 += 1
    when biosname.match('^em[0-9]')
        em += 1
    end
}

Facter.add(:physical_network_config) do
    setcode do
        "#{em}-#{pci1}-#{pci2}"
    end
end

Насколько я знаю, нельзя. Либо позвольте ему потерпеть неудачу, либо обнаружите и выйдите изящно. У меня есть несколько плагинов, которые работают только в Debian, но не работают в Red Hat без последствий.

Также обратите внимание, что НЕВОЗМОЖНО оценивать факт ПОСЛЕ того, как была введена некоторая конфигурация. Архитектура просто не поддерживает это:

Client                               Server
Compute facts
Ask for catalog passing facts =>     Receive Catalog request
                                     Compute catalog using facts
                              <=     Return Catalog
Based on the dependency tree,
  For each configuration with satisfied dependencies
    Apply configuration
    Mark (or not) dependency as satisfied
Send report, if configured so

Итак, видите ли, конфигурация применяется только спустя долгое время после обработки фактов, и пути назад нет. Может случиться так, что следующий run теперь сможет создать этот факт.

См. Также трюк, используемый Общий модуль для обработки отсутствия lsbrelease в Debian без фатальных ошибок.

Добавьте проверку в сам код факта. Перед запуском проверьте, существует ли biosdevname. Если его не существует, установите значение undef. Используйте операторы if в своих манифестах, которые требуют, чтобы этот факт имел определенное значение.

Вы можете добавлять в свои плагины условия для проверки различных вещей перед добавлением фактов, и, кроме того, у Facter есть метод ограничения, который будет запускать обнаружение Facter только на основе условий в других фактах (например, поддержка Windows для Facter сильно зависит от Confine)

Пример условного факта:

if File.exists?("/usr/bin/mysql")
  Facter.add(:mysql_version) do
    %x[#{mysqlcmd} "SELECT VERSION()"].to_s.strip
  end
end

Пример ограничения:

# Packaging on OpenBSD.  Doesn't work anywhere else that I know of.
Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Package do
  desc "OpenBSD's form of `pkg_add` support."
  commands :pkginfo => "pkg_info", :pkgadd => "pkg_add", :pkgdelete => "pkg_delete"
  defaultfor :operatingsystem => :openbsd
  confine :operatingsystem => :openbsd