Puppet has two main ways to declare classes: include-like and resource-like.
Note: These two behaviors should not be mixed for a given class. Puppet’s behavior when declaring or assigning a class with both styles is undefined, and will sometimes work and sometimes cause compilation failures.
--
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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/f2766983-529b-4fd7-a3c0-6f48efd45f25%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Oh My God!you mean that "it's not a bug, it is a feature" ?
http://docs.puppetlabs.com/puppet/latest/reference/lang_classes.html#declaring-classes
Include-Like vs. Resource-LikePuppet has two main ways to declare classes: include-like and resource-like.Note: These two behaviors should not be mixed for a given class. Puppet’s behavior when declaring or assigning a class with both styles is undefined, and will sometimes work and sometimes cause compilation failures.
> Agree with John that you want to completely avoid using the parameterized style declaration of classes. Better to use 'include' statements and set all of your params in Hiera.That's an interesting discussion,but that's not the point of this post.the point of this post, as I understand it from my colleague,is that there is a bug in puppet.on the very least, if that is not a bug,puppet should complain with a clear error message of the type "Error: class 'c1' mixes include-like and resource-like declarations",
instead of the incomprehensible error message: "Error: Duplicate declaration: Class[C1] is already declared; cannot redeclare at /vagrant/files/aa.pp:4".
About this note:http://docs.puppetlabs.com/puppet/latest/reference/lang_classes.html#declaring-classes
Include-Like vs. Resource-LikePuppet has two main ways to declare classes: include-like and resource-like.Note: These two behaviors should not be mixed for a given class. Puppet’s behavior when declaring or assigning a class with both styles is undefined, and will sometimes work and sometimes cause compilation failures.I think that the result of class { java: } and include java are semantically equivalent.I cannot think of any conceptual reason why these two behaviours could not be mixed for a given class.Do you have any conceptual reason of why that can be a problem?
I can only think that this is a technical problem in the puppet implementation, that could be fixed.what prevents puppet to allow mixing these two behaviours for a given class?(a part from a refactoring of the code...)
I didn't know about this evaluation-order dependency.Why does this "evaluation-order dependency" exists in puppet?
Is it done in purpose, or it is a technical problem of the puppet implementation?
Do you have an example where we would want to use this evaluation-order dependency?
Or could puppet completely remove this concept?
about the other part of your post, if I understand your post correctly, you are saying:1- avoid using parameterized classes
2- but yes, sometimes you need parameterized classes
3- but that's not a problem, because the class can take the parameter values from hiera
well, 1 and 2 are in contradiction, isn't it?
and about 3, hiera is not the ultimate solution for data store.what if you need to compute the parameter values programmatically?
Ok, I see.Thanks for all this discussion!> No, you never need to use parameterized classes.> If you are determined to avoid resource-like class declarations,> then you can replace each parameterized class in your manifest set with a non-parameterized version that obtains its data via direct hiera() calls.you mean replacing:class tomcat (port = hiera('tomcat_port', 7070)ssl_port = hiera('tomcat_port', 7071)) {notice $portnotice $ssl_port}by:class tomcat {$port = hiera('tomcat_port', 7070)$ssl_port = hiera('tomcat_port', 7071)notice $portnotice $ssl_port}?
for a java/scala software developer like me, this does not look a good,because it makes it more difficult to unit test.
maybe with puppet it is easy to build and pass different hiera data for unit testing?
> Hiera's YAML back end is not the ultimate solution, but the Hiera framework can be.> You can plug in pretty much any kind of data lookup or computation.Ok. I didn't know about this neither. I'll take a look.so, one specific example,someone (not me) implemented a class tomcat with parameters port and ssl_port.I want to use that class,and I want that the ssl_port is always port + 1 (I don't want this to be configurable in hiera)
so, in my hiera data, I will specify port, and then I have my class:class application ($port) {class {tomcat:port => $portssl_port => $port+1}class {nginx:...}# configuration files...}how would you do this without using resource-like class declaration?
> Or you can make exactly one class responsible for performing any needed computations and declaring the> class for which you want to use a resource-like declaration, and any node or other class must declare the> wrapper class instead (using 'include' or one of its brethren).I see. similar to the example42 params pattern. you mean something like:class parameters {$port = hiera("port")$ssl_port = $port + 1}
class tomcat {include parametersnotice $parameters::portnotice $parameters::ssl_port}
so, one specific example,someone (not me) implemented a class tomcat with parameters port and ssl_port.I want to use that class,and I want that the ssl_port is always port + 1 (I don't want this to be configurable in hiera)
so, in my hiera data, I will specify port, and then I have my class:
class application ($port) {class {tomcat:port => $portssl_port => $port+1}class {nginx:...}# configuration files...}how would you do this without using resource-like class declaration?
At the present time, I think I would need to write a custom hiera back end that served keys 'tomcat::port' and 'tomcat::ssl_port' with values having the desired relationship, and to insert that into my hiera configuration at higher priority than the YAML back end. The class 'application' then declares class 'tomcat' as "include 'tomcat'". Really, though, that's a heck of a PITA for such a small constraint. Why not just declare both parameters in the normal YAML back end, and verify the proper ports via functional testing?
But you could do this:
class parameters ($port) {
$ssl_port = $port +1
}
class tomcat {include parametersnotice $parameters::portnotice $parameters::ssl_port}
And then the rest of class 'tomcat' uses $parameters::port and $parameters::ssl_port for the HTTP and HTTPS ports? Ok, but that requires you to modify the 'tomcat' class. If you're willing to do that, then why introduce a new class as a data intermediary?
so, one specific example,someone (not me) implemented a class tomcat with parameters port and ssl_port.I want to use that class,and I want that the ssl_port is always port + 1 (I don't want this to be configurable in hiera)so, in my hiera data, I will specify port, and then I have my class:class application ($port) {class {tomcat:port => $portssl_port => $port+1}class {nginx:...}# configuration files...}how would you do this without using resource-like class declaration?
At the present time, I think I would need to write a custom hiera back end that served keys 'tomcat::port' and 'tomcat::ssl_port' with values having the desired relationship, and to insert that into my hiera configuration at higher priority than the YAML back end. The class 'application' then declares class 'tomcat' as "include 'tomcat'". Really, though, that's a heck of a PITA for such a small constraint. Why not just declare both parameters in the normal YAML back end, and verify the proper ports via functional testing?that's the point. I don't think this is a "small" constraint. I often find this dependency injection use case,and I don't see an easy solution with puppet.