Putting it all together

Reading this far, you might have gotten the impression that this chapter is a rather odd mix of topics. While types and providers do belong closely together, the whole introduction to Facter might seem out of place in this context. This is deceptive, however; facts do play a vital role in the type/provider structure. They are essential for Puppet to make good choices among providers.

Let's look at an example from the Extending Facter with custom facts section once more. It was about fstab entries and the difference of Solaris, which uses /etc/vfstab instead of /etc/fstab. That section suggested a manifest that adapts according to a fact value. As you have learned, Puppet has a resource type to manage fstab content: the mount type. However, for the small deviation of a different file path, there is no dedicated mount provider for Solaris. There is actually just one provider for all platforms, but on Solaris, it behaves differently. It does this by resolving Facter's osfamily value. The following code example was adapted from the actual provider code:

case Facter.value(:osfamily)
when"Solaris"
  fstab = "/etc/vfstab"
else
  fstab = "/etc/fstab"
end

In other cases, Puppet should use thoroughly different providers on different platforms, though. Package management is a classic example. On a Red Hat-like platform, you will want Puppet to use the yum provider in virtually all cases. It can be sensible to use rpm, and even apt might be available. However, if you tell Puppet to make sure a package is installed, you expect it to install it using yum, if necessary.

This is obviously a common theme. Certain management tasks need to be performed in different environments, with very different toolchains. In such cases, it is quite clear which provider would be best suited. To make this happen, a provider can declare itself the default if a condition is met. In the case of yum, it is the following:

defaultfor :operatingsystem => [:fedora, :centos, :redhat]

The conditions are based around fact values. If the operatingsystem value for a given agent is among the listed, yum will consider itself the default package provider.

Tip

The operatingsystem and osfamily facts are the most popular choices for such queries in providers, but any fact is eligible.

In addition to marking themselves as being default, there is more filtering of providers that relies on fact values. Providers can also confine themselves to certain combinations of values. For example, the yum alternative, zypper, confines itself to SUSE Linux distributions:

confine :operatingsystem => [:suse, :sles, :sled, :opensuse]

This provider method works just like the confine method in Facter, which was discussed earlier in this chapter. The provider will not even be seen as valid if the respective facts on the agent machine have none of the white-listed values.

Note

If you find yourself looking through code for some core providers, you will notice confinement (and even declaring default providers) on feature values, although there is no Facter fact of that name. These features are not related to provider features either. They are from another layer of introspection similar to Facter, but hardcoded into the Puppet agent. These agent features are a number of flags that identify some system properties that need not be made available to manifests in the form of facts. For example, the posix provider for the exec type becomes the default in the presence of the corresponding feature:

defaultfor :feature => :posix

You will find that some providers forgo the confine method altogether, as it is not mandatory for correct agent operation. Puppet will also identify unsuitable providers when looking for their necessary operating system commands. For example, the pw provider for certain BSD flavors does not bother with a confine statement. It only declares its one required command:

commands :pw => "pw"

Agents that find no pw binary in their search path will not try and use this provider at all.

This concludes the little tour of the inner workings of types and providers with the help of Facter. For a complete example of building a provider for a type, and using the internal tools that you have now learned about, you can refer to Chapter 5, Extending Your Puppet Infrastructure with Modules.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset