Search code examples
puppetfacter

Custom fact should run after a package is installed


I have a small custom fact in a my php module

Facter.add('php_extension_version') do
  setcode do
    Facter::Core::Execution.exec("php -i | awk '/^PHP Extension =>/ { print $4}'") || nil
  end
end

This obviously requires the php binary to be installed. However, I noticed that all facts are run once before applying the catalog, so this fact is invalid before php installed.

Is there any way of gathering the information after the module is installed? Is there perhaps another way of exposing this information except facter?

Update

I'm using the two facts to determine which of multiple .so files is the right one to install:

if $php_zts_enabled {
    $so_name = "newrelic-$php_extension_version.so"
} else {
    $so_name = "newrelic-$php_extension_version-zts.so"
}

file {"/usr/lib64/php5/extensions/newrelic.so":
    source => "file:///opt/newrelic-php5-$version-linux/agent/x64/$so_name",
    owner  => root,
    group  => root,
    mode   => 0644,
    notify => Service['apache'],
    require => Exec["extract-php-agent-$version"]
}

The files that are located in the agent/x64 directory can be

newrelic-20060613.so      newrelic-20090626-zts.so  newrelic-20121212.so      newrelic-20131226-zts.so
newrelic-20060613-zts.so  newrelic-20100525.so      newrelic-20121212-zts.so
newrelic-20090626.so      newrelic-20100525-zts.so  newrelic-20131226.so

Solution

  • You essentially have only two opportunities to execute code on the node:

    1. As part of a Facter fact. As you are aware, this happens before puppet applies a catalog, so any facts dependent on the results of the puppet run will not be useful until the next run.
    2. As part of a custom provider. You can create a custom type and provider for installing the extensions that checks the node state before deciding what to do. Providers execute on the node, and as long as you know the overall provider lifecycle you can make this happen after the PHP install. However, this is incredibly complex compared to normal puppet modules.

    Outside of those options, the normal way of doing this would be to enforce the version and configuration of php within your own manifests, and then pass that information to here. You should already know the version of PHP and its extensions based on what packages you have installed.