The Puppet Labs Issue Tracker has Moved: https://tickets.puppetlabs.com

This issue tracker is now in read-only archive mode and automatic ticket export has been disabled. Redmine users will need to create a new JIRA account to file tickets using https://tickets.puppetlabs.com. See the following page for information on filing tickets with JIRA:

Bug #4549

not all puppet functions are available in the template scope

Added by Peter Meier over 5 years ago. Updated about 3 years ago.

Status:ClosedStart date:08/17/2010
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:functions
Target version:2.7.6
Affected Puppet version:0.25.5 Branch:https://github.com/mmrobins/puppet/tree/ticket/2.7.x/4549-functions_in_templates
Keywords: customer

We've Moved!

Ticket tracking is now hosted in JIRA: https://tickets.puppetlabs.com


Description

I was looking for a way to call puppet function in templates (for example to evaluate a template in a template). According to http://serverfault.com/questions/34642/call-puppet-function-from-puppet-template it looks like this is possible. However it does not seem to work for all functions:

# cat foo.pp 
$a = inline_template("<%= scope.methods.select{|meth| meth =~ /^function_/ }.sort.join('\n')  %>")
notice $a
# puppet foo.pp 
notice: Scope(Class[main]): function_alert
function_crit
function_debug
function_emerg
function_err
function_info
function_inline_template
function_notice
function_warning
#

There was also a report about that on the users list with no answer: http://groups.google.com/group/puppet-users/browse_thread/thread/59a7ee977b26fc3d

In general we can ask: Is it the idea that puppet functions are available in templates?

If no, why is the inline_template function available? Besides that I think functions in general should be available. If yes, where are the missing functions and how can we call them?

Looking at the code doesn’t reveal how inline_teplate might be added in a special way to the scope, also it seems that the function creation code should register the functions and at least for the tests they seem to be registered.


Related issues

Related to Puppet - Bug #4915: scope.function_extlookup (in templates) takes an array pa... Closed 10/01/2010
Related to Puppet - Bug #5587: autoloading function fails inside of template Duplicate 12/17/2010
Related to Puppet - Bug #7991: Issue with using custom functions in templates. Closed 06/20/2011
Related to Puppet - Bug #7316: puppet face applications (subcommands) delivered via modu... Closed 05/02/2011

History

#1 Updated by Markus Roberts over 5 years ago

  • Status changed from Unreviewed to Accepted
  • Target version set to 52

I suspect that this is a consequence of making functions environment specific; they were moved to a base and a per-environment ruby module and it appears only the base module is getting included in the scope for the template.

#2 Updated by Markus Roberts over 5 years ago

I’m now doubting my snap diagnosis. The problem seems to be with autoloading the functions from within a template. For example:

notice sprintf('foo')
notice inline_template("<%= scope.methods.select{|meth| meth =~ /^function_/ }.sort.join('\n')  %>")

Produces:

notice: Scope(Class[main]): foo
notice: Scope(Class[main]): function_alert
function_crit
function_debug
function_emerg
function_err
function_info
function_inline_template
function_notice
function_sprintf
function_warning

(Note that sprintf is now “known” in the template).

#3 Updated by Markus Roberts over 5 years ago

  • Affected Puppet version changed from 2.6.1rc2 to 0.25.5

Two more observations: 1) this existed in 0.25.x as well, and thus is not new breakage and 2) you can hack around it by forcing the function to load (not recommend, but noted), e.g.:

notice inline_template("<%= Puppet::Parser::Functions.function('sprintf'); '' %><%= scope.function_sprintf(['foo']) %>")

What was the use case you had in mind?

#4 Updated by Peter Meier over 5 years ago

Markus Roberts wrote:

Two more observations: 1) this existed in 0.25.x as well, and thus is not new breakage

yeah, I’m now on running on 2.6.1.rc2++ and this is something completely new I wanted to try. So I couldn’t tell whether it have already been broken before or it already worked. But it looks like it have been broken the other mail I linked notes.

2) you can hack around it by forcing the function to load (not recommend, but noted), e.g.:

[…]

What was the use case you had in mind?

I have a couple of templates, which have their own stuff, but share also a lot of snippets. Furthermore, there are a like a dozen of such templates and it would get too complicated and even more messy than they already are to put them all together into one big template. Therefore I thought about putting the shared template code in snippets, so I define at least the shared parts only once. Therefore, I’d like to use the template function in templates. This is the main use case currently for me. And as I would use the template function within the template function it would already been there, so that works anyway.

I have to admit that I didn’t try to use the template function in a template, which should work according to your discovery. But what I did, was trying to use @fqdn_rand@ in the inline template as this was a quick test for me to see if I can really call functions that way and this didn’t work. So therefore I looked what kind of functions are around and they were all missing :/.

So in my opinion we have now a workaround, however it might be still good to have it simply working, because only documenting that workaround is imho rather ugly. Hence, I would propose to put another branch into the already existing @method_missing@ of the scope object. We would try to load the custom function there if the call looked like @function_@ and if that works we would delegate the call to the newly added function. This would only be a problem for the first time and all subsequent message sends to that function wouldn’t anymore land in @method_missing@.

#5 Updated by James Turnbull about 5 years ago

  • Target version deleted (52)

#6 Updated by Matt Robinson almost 5 years ago

  • Status changed from Accepted to Needs Decision
  • Assignee set to Nigel Kersten
  • Target version set to 2.7.x
  • Branch set to https://github.com/mmrobins/puppet/tree/ticket/2.7.x/4549-functions_in_templates

I’ve gone ahead and implemented Peter’s suggestion of method_missing on the scope and it seems to work pretty well. The attached branch has the code, still needs tests, but I’ll work on those right after this.

I’m assigning it to Nigel to make sure he’s happy with this solution going into 2.7.x.

#7 Updated by Matt Robinson almost 5 years ago

  • Status changed from Needs Decision to Merged - Pending Release
  • Assignee deleted (Nigel Kersten)

I talked to Nigel, and he’s good on this fix, so it’s merged commit:4f873f0ea8bc259b7ecd4f4a9920decad3339656

#8 Updated by James Turnbull over 4 years ago

  • Category set to functions
  • Target version changed from 2.7.x to 2.7.4

#9 Updated by Michael Stahnke over 4 years ago

  • Status changed from Merged - Pending Release to Closed
  • Target version changed from 2.7.4 to 2.7.6

´╗┐Released in 2.7.6rc1.

#10 Updated by Charlie Sharpsteen about 3 years ago

  • Keywords set to customer

Also available in: Atom PDF