Я написал пользовательский факт 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