Clay Caviness
2011-Apr-15 19:10 UTC
[Puppet Users] ERB strangness, or ruby/puppet internals I don''t understand
Let''s say I have a very simple template template.erb: <% if not has_variable?("foobar") then foobar = "undefined" end -%> foobar: <%= foobar %> class: <%= foobar.class %> And a basic manifest: template.pp: $mytemp = template(''template.erb'') notice($mytemp) And then I apply the manifest, with an undefined foobar (no foobar fact): $ puppet apply ~/template.pp notice: Scope(Class[main]): foobar: undefined class: String notice: Finished catalog run in 0.01 seconds Looking good. So now I apply the manifest, but with a defined value for foobar (via the FACTER_FOOBAR environment variable): $ FACTER_FOOBAR=''foo'' puppet apply ~/template.pp notice: Scope(Class[main]): foobar: class: NilClass notice: Finished catalog run in 0.01 seconds Er, what? How on earth did foobar go from a String to NilClass? I can''t fathom how this is expected, or correct... The reason I was doing this sort of thing is to give a possibly missing fact a default value. I ended up using a second variable, like this: <% foo = has_variable?("foobar") ? foobar.to_s : "false" -%> -- 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+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Felix Frank
2011-Apr-18 12:52 UTC
Re: [Puppet Users] ERB strangness, or ruby/puppet internals I don''t understand
On 04/15/2011 09:10 PM, Clay Caviness wrote:> Let''s say I have a very simple template > template.erb: > <% if not has_variable?("foobar") then foobar = "undefined" end -%> > foobar: <%= foobar %> > class: <%= foobar.class %> > > And a basic manifest: > template.pp: > $mytemp = template(''template.erb'') > notice($mytemp) > > And then I apply the manifest, with an undefined foobar (no foobar fact): > $ puppet apply ~/template.pp > notice: Scope(Class[main]): foobar: undefined > class: String > > notice: Finished catalog run in 0.01 seconds > > Looking good. So now I apply the manifest, but with a defined value > for foobar (via the FACTER_FOOBAR environment variable): > $ FACTER_FOOBAR=''foo'' puppet apply ~/template.pp > notice: Scope(Class[main]): foobar: > class: NilClass > > notice: Finished catalog run in 0.01 seconds > > Er, what? How on earth did foobar go from a String to NilClass? I > can''t fathom how this is expected, or correct... > > The reason I was doing this sort of thing is to give a possibly > missing fact a default value. I ended up using a second variable, like > this: > <% foo = has_variable?("foobar") ? foobar.to_s : "false" -%> >Hi, does this work better if you set $foobar in your manifest? Looks like a bug you may want to report either way. Regards, Felix -- 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+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
jcbollinger
2011-Apr-18 14:00 UTC
[Puppet Users] Re: ERB strangness, or ruby/puppet internals I don''t understand
On Apr 15, 2:10 pm, Clay Caviness <ccavin...@gmail.com> wrote:> Let''s say I have a very simple template > template.erb: > <% if not has_variable?("foobar") then foobar = "undefined" end -%> > foobar: <%= foobar %> > class: <%= foobar.class %> > > And a basic manifest: > template.pp: > $mytemp = template(''template.erb'') > notice($mytemp) > > And then I apply the manifest, with an undefined foobar (no foobar fact): > $ puppet apply ~/template.pp > notice: Scope(Class[main]): foobar: undefined > class: String > > notice: Finished catalog run in 0.01 seconds > > Looking good. So now I apply the manifest, but with a defined value > for foobar (via the FACTER_FOOBAR environment variable): > $ FACTER_FOOBAR=''foo'' puppet apply ~/template.pp > notice: Scope(Class[main]): foobar: > class: NilClass > > notice: Finished catalog run in 0.01 seconds > > Er, what? How on earth did foobar go from a String to NilClass? I > can''t fathom how this is expected, or correct...It looks like the variable is defined, and has the (Ruby) value nil. This could be because the variable was previously assigned a (possibly different) value when a different catalog was compiled, but not assigned a value for the current catalog. And THAT might be because Ruby and shell variable names are both case-sensitive. Does it work better if you write FACTER_foobar=''foo'' puppet apply ~/template.pp ?> > The reason I was doing this sort of thing is to give a possibly > missing fact a default value. I ended up using a second variable, like > this: > <% foo = has_variable?("foobar") ? foobar.to_s : "false" -%>If I have analyzed the problem correctly, then you should also be able to do it this way: <% if not has_variable?("foobar") or foobar.nil then foobar "undefined" end -%> 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+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
Thomas Bellman
2011-Apr-20 11:34 UTC
Re: [Puppet Users] ERB strangness, or ruby/puppet internals I don''t understand
On 2011-04-15 21:10, Clay Caviness wrote:> Let''s say I have a very simple template > template.erb: > <% if not has_variable?("foobar") then foobar = "undefined" end -%> > foobar: <%= foobar %> > class: <%= foobar.class %> > > And a basic manifest: > template.pp: > $mytemp = template(''template.erb'') > notice($mytemp) > > And then I apply the manifest, with an undefined foobar (no foobar fact): > $ puppet apply ~/template.pp > notice: Scope(Class[main]): foobar: undefined > class: String > > notice: Finished catalog run in 0.01 seconds > > Looking good. So now I apply the manifest, but with a defined value > for foobar (via the FACTER_FOOBAR environment variable): > $ FACTER_FOOBAR=''foo'' puppet apply ~/template.pp > notice: Scope(Class[main]): foobar: > class: NilClass > > notice: Finished catalog run in 0.01 seconds > > Er, what? How on earth did foobar go from a String to NilClass? I > can''t fathom how this is expected, or correct...This happens because the Puppet variables are not exposed to ERB as real Ruby variables. Instead, Puppet uses some magic to catch references to non-existing variables. When the Ruby compiler sees that you are assigning to foobar in your code, *anywhere* in your code, it will create that variable for you, regardless of whether the assignment is actually executed or not. Since the variable now exists, that will shadow Puppet''s magic. That was at least what I found out when I investigated this when running 0.24.something, and I don''t *think* they have changed how Puppet variables are exposed to ERB since then.> The reason I was doing this sort of thing is to give a possibly > missing fact a default value. I ended up using a second variable, like > this: > <% foo = has_variable?("foobar") ? foobar.to_s : "false" -%>That is probably the best workaround. /Bellman -- 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+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.