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 puppet-users+unsubscr...@googlegroups.com.
To post to this group, send email to puppet-users@googlegroups.com.
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