On Jun 30, 6:15 am, Martijn Grendelman <mart...@iphion.nl> wrote: > Hi, > > Having installed Puppet 2.7.1 on my testserver yesterday, I am now bugged > by log messages, that tell me not to use dynamic variable lookups: > > Jun 29 13:31:09 os1 puppet-master[31910]: Dynamic lookup of > $ssh_permitrootlogin at /etc/puppet/templates/etc/ssh/sshd_config.erb:28 > is deprecated. Support will be removed in Puppet 2.8. Use a > fully-qualified variable name (e.g., $classname::variable) or > parameterized classes. > > Now, I have been reading up on variable scoping and trying to figure out > how to rewrite my manifests to embrace best practices, but I am confused > on how to proceed, and I can't really find any working examples, so I turn > here for help. > > My current setup is something like this: > > node basenode { > $somevar = "defaultvalue" > $someothervar = "anotherdefault" > > }
[...] > In any class or module I use $somevar and $someothervar as I please, and I > understand that this a) is not a recommended practice and b) will stop > working in Puppet 2.8. > > So, what should I do? It's not actually clear to me whether "top level" includes inside node declarations, but IMHO it should. If it does, and if you do not rely on defining different values for $somevar or $someothervar inside your classes (see below), then you should be able to solve your problem by changing all appearance of $somevar and $someothervar to $::somevar and $::someothervar (i.e. use their fully-qualified names as the warning suggests). It should be pretty easy to test whether that works for you. > Switching to parameterized classes sounds nice, but that would mean that > the 'generic' class would have to get /every/ variable I use as a > parameter and pass it on to subsequent classes where needed. That sounds > incredibly clumsy to me. As regulars here will know, I am not a big fan of parameterized classes. Puppetlabs likes them, and pushes them, but I think they are rarely the best tool for the job. Perhaps the thing that they are most appropriate for, however, is avoiding dynamic scoping. More on that below. You are right that for your manifest design, solving the problem via class parameterization would require your Class["generic"] to be parameterized with all the variables it uses directly plus all those needed by the classes it includes. I think this is one reason that Puppetlabs' style guide now recommends avoiding classes including other classes. Once your manifests become complex enough that that is painful, they suggest using an external node classifier. If you don't buy in to parameterized classes, however, then that advice does not stand up so well. > Inhttp://docs.puppetlabs.com/guides/scope_and_puppet.htmlI read: > > "If you re using dynamic scope to share resource defaults, there s no > way around it: you ll have to repeat yourself in each file that the > defaults apply to." > > Is this what's biting me here? Well, this sounds like something I can live > with, after all: it's not the default values I care about, it's the > overriding values. Forgive me for being didactic: In Puppet < 2.8.0, variables declared outside any class can be overridden by declarations of the same variable name within classes. Within a class that does so and any class it includes, recursively, the variable's unqualified name resolves to the class's definition, not the top-level one. Except that this nests, so that if an included class also defines a variable having the same simple name, then it and its included classes see *its* definition. This is called "dynamic scoping". Dynamic scoping presents at least two problems: 1) When a class refers to externally defined variables by their simple names, it is hard to know what definition of the variable you're going to get. That's not such a big deal, though, and it could even be considered an advantage -- the external variables a class uses can be considered de facto parameters for it. 2) Classes can be included multiple times, by more than one path, and there is no guarantee that the values they see for unqualified external variable names will be the same at each inclusion. This can result in unintended behavior, but the problem is not so much that dynamic scoping is inherently bad, but rather that it facilitates poor manifest design. Parameterized classes address problem (1) by formalizing class parameterization, and they address problem (2) by making it illegal to include a parameterized class more than once (even with the same parameters). One of my main objections to parameterized classes is that the latter is too far-reaching and constraining. > Further, it states: > > "If you need to apply resource defaults more broadly, you can still set > them at top scope in your primary site manifest. If you need the resource > defaults in a class to change depending on where the class is being > declared, you need parameterized classes." > > And we're back at parameterized classes. And what does 'top scope' mean > exactly? I assume that would be in 'site.pp', outside any class or node > definition? Outside any class or node definition and inside site.pp or any manifest 'import'ed by it is certainly top-level. Surely someone else around here knows offhand whether anywhere else, such as inside node definitions, is also top-level. Or you can test: the fully-qualified name of a top-level variable $somevar is $::somevar. > To make a long question short: what is the recommended way to override > values for certain nodes or groups of nodes (by inheritance)? And I'd > /really/ prefer to do that without having to pass on each and every value > as a parameter to the next included class... Things to consider: 1) I personally recommend avoiding deep node inheritance hierarchies. In fact, I recommend no more than two levels to your node inheritance tree. This may or may not help with your present problem. 2) As I mentioned above, you may be able to just change to fully- qualified variable names. That would be quick and relatively painless. 3) There is another built-in alternative to dynamically-scoped variables: the extlookup() function. Using extlookup() to retrieve data for your resources can allow you to minimize the number of parameters you need to pass, or even to avoid class parameterization altogether. I think this is a great way to go, but Puppetlabs's style guide disfavors 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.