我编写了一个自定义 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
声明,事实就会正确运行随后的运行。这里的困难在于这是我们初始配置过程的一部分。我们正在使用 kickstart 运行 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
答案1
据我所知,你不能。要么让它失败,要么检测并优雅地失败。我有许多只在 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
所以,你看,配置只有在事实处理很久之后才会应用,而且没有办法恢复。可能发生的情况是下一个运行现在将能够生成该事实。
另请参阅通用模块处理 Debian 上缺少 lsbrelease 的问题而不产生致命错误。
答案2
在事实代码本身中添加检查。在尝试运行 biosdevname 之前,检查它是否存在。如果不存在,则将值设置为 undef。在清单中使用 if 语句,要求该事实具有特定值。
答案3
您可以在插件中添加条件,以便在添加事实之前检查各种事物,此外,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