创建 Facter 的自定义 fact
虽然 Facter 内置的 facts 很有用,但实际上添加你自己的 facts 也是很容易的。 例如,如果你的机器位于不同的数据中心或托管提供商,你可以为此目的添加一个 自定义 fact 以便让 Puppet 决定是否需要应用一些本地设置(例如,本地 DNS 服务器)。
准备工作
在配置文件
puppet.conf
中开启pluginsync
选项:[main] pluginsync = true
为 fact 创建一个目录。此目录位于相应的模块目录中,目录名为
lib/facter
。 例如,你可以使用目录modules/admin/lib/facter
。你创建的任何自定义 facts 都位于此目录下并且 Puppet 会将其同步到客户端。
操作步骤
创建一个名为
hello.rb
的包含如下内容的脚本文件:Facter.add(:hello) do setcode do "Hello, world" end end
在客户端运行 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
通过直接运行 Facter 命令的方式检测 fact:
# facter hello Hello, world
现在你可以在一个 Puppet 的配置清单中应用这个自定义的 fact:
notify { $hello: }
当你运行 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 。