G'day.
I have encountered what I think is a problem with template expansion as
part of puppet, and wanted to confirm that my understanding is correct
that this is a bug -- or identify how to work around it.
So, I have created a class (with define) to represent a new
configuration file that I am managing. One of the options in the
configuration file is 'fork', for better or worse.
So, using define I have, roughly, the following:
test.pp:
define foo ($fork = "yes") {
file { "/tmp/output.txt": content => template("test.erb") }
}
node myhost { foo { "bar": } }
test.erb:
<%= fork.class %>
<%= fork %>
The output is 'Fixnum' and a PID on my machine, because ERB resolves the
variable into the kernel method 'fork', forks the puppet process, and
returns that PID to the parent. Ouch.
The same can be demonstrated with 'object_id' in the ERB file, which is
never resolved to an object_id variable no matter what.
Sadly, according to the puppet documentation this should all work, but
it doesn't. Worse, the root cause is the implementation of the template
wrapper, which is all ... exciting:
lib/puppet/parser/templatewrapper.rb:32 says:
# Ruby treats variables like methods, so we can cheat here and
# trap missing vars like they were missing methods.
def method_missing(name, *args)
Darn! This is never going to work if the ERB code is evaluated in an
environment where Kernel is visible, and I don't believe Ruby allows us
to create a new execution environment where that isn't the case. :?
(We could, in theory, clone the default Binding, excise everything from
it, then insert the ERB code and anything it depends on, including the
Kernel object, at which point we face the same problem. Yay!)
So, while I am happy to implement a solution to this I can see only a
limited number of relatively undesirable options:
1. I can contort my define to take arguments that don't conflict with
any Ruby method, ever, and do the same to my callers.
2. I can contort my define to rebind all arguments with a prefix, to
avoid the conflict. This roughly doubles my line count for a trivial
configuration file wrapper, which is painful.
Neither of those is terrible appealing, though the second is at least
theoretically future-proof. Not much fun, though.
There is also option 3, which I would be happy to work on implementing:
3. Expose puppet variables to ERB through some mechanism other than
implementing missing_method, so they are the closest lexical scope
value found.
Assuming that option three is desirable, any hints on how this should be
handled?
Regards,
Daniel
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Puppet Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/puppet-dev?hl=en
-~----------~----~----~----~------~----~------~--~---