On Apr 27, 6:40 am, Andre Nathan <andre...@gmail.com> wrote:
> Hello
>
> I have some code that works like the simplified clase shown below. The idea
> is to have a define "foo" that includes a class "foo::pre" which contains
> resources that need to be executed before the define is called. The define
> can be called multiple times but the initialization has to be done only
> once, which is why it's implemented as a class:
>
> class foo::pre {
>   notice("foo::pre")}
>
> define foo() {
>   include 'foo::pre'
>   notice("foo")}
>
> class x {
>   notice("x")
>   foo { 'x foo':
>   }}
>
> class y {
>   notice("y")
>   foo { 'y foo':
>   }}
>
> include x
> include y


Great, no problem.


> The issue is that now I need to parametrize foo::pre so that its behavior
> depends on a variable that exists in foo:
>
> class foo::pre($blah) {
>   notice("foo::pre")}
>
> define foo() {
>   class { 'foo::pre':
>     blah => 1,
>   }
>   notice("foo")}
>
> class x {
>   notice("x")
>   foo { 'x foo':
>   }}
>
> class y {
>   notice("y")
>   foo { 'y foo':
>   }}
>
> include x
> include y
>
> With this code I get "Duplicate definition: Class[Foo::Pre] is already
> defined". This seems weird to me because I thought the "class { 'myclass':}" 
> syntax was semantically equivalent to "include myclass". Puppet,
>
> however, complains that it's being defined twice, even though there's no
> definition happening there, just inclusion.


This is one of the several drawbacks of Puppet's implementation of
parameterized classes. It may be that "class { 'myclass':}" is
semantically equivalent to "include 'myclass'", but that's beside the
point.  Unlike ordinary classes, parameterized classes can only be
included / declared once.  It's not necessarily the declaration syntax
that makes the difference, but rather the nature of the class being
declared.


> So, is there a way to redesign this to match the original behavior? I know
> the current trend is to keep this kind of thing in hiera but this is
> already a fairly large code base that can't be changed quickly...


I know it's not what you want to hear, but Hiera is your best bet.  I
don't think the code base size is relevant, because I don't think the
time and effort to implement an Hiera-based class data source is
likely to differ much from what parameterizing all the same classes
would require.  Or to put it a different way, solving your problem via
class parameterization would require *at least* as much shakeup of
your code base as would implementing an hiera-based solution.

If you insist on using parameterized classes, then you have to come up
with a way to ensure that they are declared exactly once if they are
needed.  If it is harmless to declare them when they are unneeded,
then you could declare them unconditionally for every node; otherwise
you have a mess to sort out.  It is my impression that people with
that sort of mess usually end up relying on a complex ENC to deal with
it.


John

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To post to this group, send email to puppet-users@googlegroups.com.
To unsubscribe from this group, send email to 
puppet-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-users?hl=en.

Reply via email to