指定 Puppet 自定义事实的先决条件?

指定 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声明,事实就会正确运行随后的运行。这里的困难在于这是我们初始配置过程的一部分。我们正在使用 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

相关内容