创建 Facter 的自定义 fact

虽然 Facter 内置的 facts 很有用,但实际上添加你自己的 facts 也是很容易的。 例如,如果你的机器位于不同的数据中心或托管提供商,你可以为此目的添加一个 自定义 fact 以便让 Puppet 决定是否需要应用一些本地设置(例如,本地 DNS 服务器)。

准备工作

  1. 在配置文件 puppet.conf 中开启 pluginsync 选项:

    [main]
        pluginsync = true
    
  2. 为 fact 创建一个目录。此目录位于相应的模块目录中,目录名为 lib/facter。 例如,你可以使用目录 modules/admin/lib/facter。你创建的任何自定义 facts 都位于此目录下并且 Puppet 会将其同步到客户端。

操作步骤

  1. 创建一个名为 hello.rb 的包含如下内容的脚本文件:

    Facter.add(:hello) do
        setcode do
            "Hello, world"
        end
    end
    
  2. 在客户端运行 Puppet。这会将 fact 同步到客户机:

    # puppet agent --test
    info: Retrieving plugin
    
    notice: /File[/var/lib/puppet/lib/facter/hello.rb]/ensure: defined
    content as '{md5}7314e71d35db83b563a253e741121b1d'
    
    info: Loading downloaded plugin /var/lib/puppet/lib/facter/hello.rb
    info: Loading facts in hello
    info: Loading facts in hello
    info: Loading facts in hello
    info: Loading facts in hello
    info: Connecting to sqlite3 database: /var/lib/puppet/state/
    clientconfigs.sqlite3
    
    info: Caching catalog for cookbook.bitfieldconsulting.com
    info: Applying configuration version '1297258039'
    
    notice: Finished catalog run in 0.57 seconds
    
  3. 通过直接运行 Facter 命令的方式检测 fact:

    # facter hello
    Hello, world
    
  4. 现在你可以在一个 Puppet 的配置清单中应用这个自定义的 fact:

    notify { $hello: }
    
  5. 当你运行 Puppet,对自定义 fact 的引用将返回其对应的值:

    notice: Hello, world
    

工作原理

Facter 内置的 facts 与我们刚刚创建的自定义 fact 相同的方式定义。 这种架构使添加和修改 facts 更为方便,并为你提供了一种在配置清单中读取主机信息的标准方法。

Facts 可以包含任何 Ruby 代码,语句块 setcode do … end 中最后算出的值将作为 fact 的返回值。 例如,你可以做个更有用的 fact,下面的代码将返回当前登录的用户数:

Facter.add(:users) do
    setcode do
        %x{/usr/bin/who |wc -l}.chomp
    end
end

其输出是:

notice: 2 users logged in

更多用法

你可以扩展 facts 使用以创建一个完全 “无节点定义(nodeless)” 的 Puppet 配置: 换言之,Puppet 可以仅基于 facts 的结果决定将哪些资源应用到一台机器。 Jordan Sissel 写了篇介绍这种方法的文章: http://www.semicomplete.com/blog/geekery/puppet-nodeless-configuration.html

在网络上有许多可用的自定义 facts 的例子,包括 Cosimo Streppone 撰写的关于 “根据 IP 地址决定数据中心的位置” 的文章,网址为: http://my.opera.com/cstrep/blog/puppet-custom-facts-and-master-less-puppet-deployment