On Tuesday, April 23, 2013 4:52:11 PM UTC-5, Mike Power wrote:
>
> I have been backed into a corner, by they way puppet works, but some third 
> party module.
>
> Basically I have two resources defined:
>
> a {$somevar:}
> b::b {$somrvar:}
>
> both have code that looks something like this:
>     if (!defined(File[$name])) {
>         file { $name:
> ...
>     }
>
> According to the documentation 'defined' is dependent on parse order.  So 
> resource definition 'a' should be parsed first and win.



This is not a characteristic to manipulate, but rather a strong reason to 
avoid defined() altogether.  I cannot say this more strongly: DO NOT USE IT.

 

>   But it doesn't, no matter how I order 'a' and 'b::b', resource 
> definition 'b::b' always defines the file.  I even tried puppet version 
> 3.1.1.  Same problem.  My problem is that resource "b::b" does it horribly 
> wrong.  It causes the runtime of my manifest to balloon out from 2mins to 
> over 10 minutes.  It uses the wrong group.  That would be okay if I could 
> just put 'a' first and have 'b::b' go silent.
>
> Does anyone know why this is happening?  How is "b::b" being parsed first 
> even though "a" is ahead in the file?
>


The *declaration* of resource A[$somevar] is surely parsed before the 
declaration of B::B[$somevar], but that's not at all the same thing as the 
body of defined type 'a' being parsed before the body of defined type 
'b::b'.  It's pretty much irrelevant why the parse order you see happens -- 
Puppet guarantees parse order only within each manifest file, so manifests 
that depend on parse order across multiple files are flawed.  Even if you 
found a magic formulation that achieved the order you want on a given 
version of Puppet, there is no guarantee that it would continue to work 
even in the next maintenance release.

As I say here from time to time, your manifests should not attempt to query 
Puppet about what has already been declared.  There are a number of 
techniques by which that is possible, but generally they can be described 
as using "data-driven" approaches to manifest and manifest-set design.  As 
an over-simplified example, you could set a boolean node variable 
$i_will_use_a, and then change the condition in b::b like so

define b::b (...) {
  if ! $i_will_use_a {
    file { $name:
      ...
    }
  }
  ...
}

There are a host of other ways to do essentially the same thing.


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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/puppet-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to