Puppet class inheritance confusion
Puppet does not support this kind of configuration, but the restriction can be easily bypassed. The reason is in two basic puppet "rules":
- A class can be included only once (subsequent include -statements will do nothing)
- The order of execution is not strictly defined and can even be random
er-dev
and er-bce-dev
both include the class er
. But the class cannot be included two times, so er
class is executed only with the default $venvname = "er"
, or with overridden $venvname = "er-dev"
, but not both.
The solution: Change er
class to a definition (see "Definitions" from Puppet Language Tutorial (http://docs.puppetlabs.com/guides/language_tutorial.html)):
modules/django-env/manifests/er.pp
# Create new er resource definition
define django-env::er($vpath="/home/django/virtualenvs", $vname="er") {
file { "$vpath/$vname" :
ensure => directory
}
# etc ...
}
We do not need the $venvname
and $venvpath
variables, they are specified as default values in the definition. The name django-env::er
adds the definition into django-env
namespace and allows automatic import (see below).
Import and Include
The difference between import
and include
statemens is:
import
works with files, and does not execute classesinclude
executes classes- files must be imported before the classes can be included
Note: there is a very strong exception to the last rule: Puppet module lookup. include
statement does automatic imports in many situations. Here are some of them:
include foo
tries to import the filemodule_dir/foo/manifests/init.pp
include foo::bar
importsmodule_dir/foo/manifests/bar.pp
With these automatic imports and the resource definition, you can define multiple virtual environments very easily. Change node 'centos-dev'
:
node 'centos-dev' imports default {
include django-env
# The er resource with default values:
django-env::er { 'er-bce': }
# Another er resource with different environment name:
django-env::er { 'er-bce-dev': vname => 'bce-dev'}
}
And you can remove basically all import
statements considering django-env
module.
Happy Puppeting!