Namespaces and autoloading
Class and defined type names can be broken up into segments called namespaces which enable the autoloader to find the class or defined type in your modules.
Syntax
Puppetclass and defined type names
can consist of any number of namespace segments separated by the double colon (::
) namespace separator, analogous to the slash (/
) in a file path.
class apache { ... } class apache::mod { ... } class apache::mod::passenger { ... } define apache::vhost { ... }
Autoloader behavior
When a class or defined resource is declared, Puppet uses
its full name to find the class or defined type in your modules. Every class and defined
type must be in its own file in the module’s manifests
directory, and each file must have the .pp
file
extension.
Names map to file locations as follows:
The first segment in a name, excluding the empty top namespace, identifies the module. If this is the only segment, the file name is
init.pp
.The last segment identifies the file name, minus the
.pp
extension.Any segments between the first and last are subdirectories under the
manifests
directory.
As a result, every class or defined type name maps directly to a file path within Puppet’s modulepath
:
Name | File path |
---|---|
apache | <MODULE DIRECTORY>/apache/manifests/init.pp |
apache::mod | <MODULE DIRECTORY>/apache/manifests/mod.pp |
apache::mod::passenger | <MODULE
DIRECTORY>/apache/manifests/mod/passenger.pp |
init.pp
file always contains a class
or defined type with the same name as the module, and any other .pp
file contains a class or defined type with at least two namespace
segments. For example, apache.pp
would contain a class
named apache::apache
. This means you can’t name a class
<MODULE NAME>::init
.Nested definitions and missing files
If a class or defined type is defined inside another class or defined type definition, its name goes under the outer definition’s namespace.
This causes its real name to be something other than the name it was defined with. For
example, in the following code, the interior class's real name is first::second
:
class first { class second { ... } }However, searching your code for that real name returns nothing. Also, it causes class
first::second
to be defined in the wrong file.
Avoid structuring your code like this.
If the manifest file that corresponds to a name doesn’t exist, Puppet continues to look for the requested class or defined
type. It does this by removing the final segment of the name and trying to load the
corresponding file, continuing to fall back until it reaches the module’s init.pp
file.
Puppet loads the first file it finds like this, and raises an error if that file doesn’t contain the requested class or defined type.
This behavior allows you to put a class or defined type in the wrong file and still have it work. But structuring things this way is not recommended.