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.