Writing static facts is fairly easy even with a low level of Ruby skills. Below is an example of a fact that returns true or false depending on whether the node has a /boot partition:
Facter.add(:has_bootfs) do
setcode do
if Facter.value(:mountpoints)['/boot'].nil?
false
else
true
end
end
end
As you can see above the required information was already inside the "mountpoints" fact of Facter.
Using the fact is easy:
$ facter -p has_bootfs
true
Even though no new data is created in the above example, you can create custom facts from dynamic content using the same strategy. In the below code, I created a separate fact ("user_<username>_is_present") for each user of the *NIX system excluding the system users:
require 'etc'
Etc.passwd do |entry|
# Normal users have IDs in this range in /etc/login.defs
if entry.uid >= 1000 and entry.uid <= 60000
Facter.add("user_#{entry.name}_is_present") do
setcode do
true
end
end
end
end
Using the dynamically created facts is easy:
$ facter -p user_john_is_present
true
$ facter -p user_jack_is_present
$ facter -p user_jane_is_present
true
The only limitation is that a fact cannot be created from non-existing data. In the above example, the fact for user "jack" (who doesn't exist) gets an empty value (undef/nil) instead of returning actual boolean false. This doesn't in practice affect how the fact can be used.