On Friday, September 11, 2015 at 4:31:40 PM UTC-5, Julian Meier wrote: > > Hi all > > I’ve got three classes (example): > > ``` > class mymodule ( > $user = 'foobar', > ) {} > > class mymodule::classone ( > $foo = 'bar', > ) inherits ::mymodule::classone::params { > require mymodule > notify { "username: ${::mymodule::user}": } > } > > class mymodule::classtwo ( > $foo = 'bar', > ) inherits ::mymodule::classtwo::params { > require mymodule > notify { "username: ${::mymodule::user}": } > } > > class mymodule::classone::params {} > class mymodule::classtwo::params {} > ``` > > My idea is to have a class `mymodule` with parameters used by any other > class. If someone would like to change the default parameters of `mymodule` > he can do it like (or with hiera and autolookup): > ``` > class { ::mymodule: user => 'foo', } > class { ::mymodule::classone: } > ``` > And for `classtone` and `classtwo` there is a specific `params.pp` > (inherits)… > > My problem: the declaration above can cause dependency cycles… If > `classone` gets used before class `mymodule`. :-( > >
What you are observing is not a dependency cycle, it is an evaluation-order dependency. > Do you have a better idea or design? > Yes: never use a resource-like class declaration <http://docs.puppetlabs.com/puppet/4.2/reference/lang_classes.html#include-like-vs-resource-like> to declare any public class of any module. A "public class" is one that is intended to be declared from outside the module, which appears to include at least classes ::Mymodule and ::Mymodule::Classone in your example. Do not use a resource-like class declaration for such a class either outside its module or inside. Instead use include-like declarations for such classes, and rely on automated data binding via Hiera to assign non-default class parameter values to them. The particular problem in this case is that if the catalog builder evaluates a resource-like declaration of a given class, that declaration must be the very first declaration of the given class it sees. The 'require mymodule' appearing in ::Mymodule::Classone and ::Mymodule::Classtwo is an include-like declaration of class ::Mymodule, and it is evaluated as part of evaluating the declaration of either of those classes. When a resource-like declaration of the same class is encountered later, the catalog builder objects. This constraint is basically about determining the applicable class parameter values: Puppet permits the same class to be declared multiple times, with the second and subsequent ones being no-ops. Class parameter values must be determined at the first declaration. And that's why you must avoid resource-like declarations of public classes -- it is very difficult to predict where another declaration of such a class may be (since it's public), or the relative order in which such a declaration may be evaluated. As a secondary design consideration, it rarely makes sense to have one public class of a module that depends on another public class of the same module. Many modules have only a single public class, and a few have multiple, independent public classes, but I can't name any off the top of my head that use the type of pattern you presented, with dependent public classes. Those I can think of that have something like that provide defined resource types instead of dependent public classes. Indeed, it may be that your Mymodule::Classone and Mymodule::Classtwo really want to be different instances of one defined type. That's not going to get you around a class-declaration issue such as the one you presented, however. John -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/3ab543f5-1b7b-412d-b942-1edf1f5d5c66%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.