On 2015-23-05 24:39, Maura Dailey wrote:
Yes, I know this practice is discouraged in the documentation, but the
updated hiera 2.0 documentation also assures me that it's supported and
implies no changes to puppet 3.x manifests or templates are required.
This networking.erb file used to work in puppet 3.8 (this is a cruddy
example, I use callouts to hiera data EXTENSIVELY in dozens of much more
complicated configuration templates):
|
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=<%=@fqdn%>
GATEWAY=<%=scope.function_hiera(['gateway'])%>
NOZEROCONF=yes
|
Now in puppet 4.1, I get the following:
|
Info:Retrievingpluginfacts
Info:Retrievingplugin
Info:Loadingfacts
Error:Couldnotretrieve catalog fromremote server:Error400on
SERVER:EvaluationError:Errorwhileevaluating a FunctionCall,Failedto
parse templatenetworking/network.erb:
Filepath:/opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/parser/functions/fail.rb
Line:3
Detail:hiera()has been converted to 4xAPI
|
I checked the hiera 2.0 documentation on the names of functions
here: http://docs.puppetlabs.com/hiera/latest/puppet.html#hiera-lookup-functions
and the hiera 2.0 documention on how to call them from inside templates
here:
http://docs.puppetlabs.com/hiera/latest/puppet.html#using-the-lookup-functions-from-templates
What am I missing? I tried to read the Ruby source for hints, but I'm
more of a Python person and couldn't find any documentation on how to
call the 4x API functions correctly. Thanks in advance for any assistance.
You have unfortunately run into a problem with a puppet 3.x function
(template()) making a call to a function that have been migrated to the
4.x function API. In the new API functions are not called via scope, and
a 3x function does not have the needed information to do so easily.
You can get around the problem by using the new templating system EPP
where the logic is written in the Puppet Language. This is also the long
term direction (The more safe, and better specified EPP over ERB where
you are exposed to the internals of the puppet runtime).
The snippet you showed can be written like this in EPP:
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=<%= $fqdn %>
GATEWAY=<%= hiera('gateway') %>
NOZEROCONF=yes
I understand this may be a bit of work when you have many and
complicated templates esp. if you rely on the internals of Puppet.
For regular templates that only access variables, it should be as easy
as replacing a @varname with $varname).
I think a ticket should be logged regarding the difficulty of calling a
4x function (this has popped up in other contexts (where it was possible
to work around the issue more easily)).
What is needed is a calling mechanism that is agnostic; a function that
is written with the 4.x. API simply uses the method
'call_function(<NAME>, <ARG1>, <ARG2>, ...)' and it calls either a 3.x
or a 4.x function. A similar thing is needed in an accessible way from
within a 3.x. function or template (e.g. scope.call_function with the
same signature as in the 4.x API). The fix would entail something like
what I am describing below...
Alternatively, to get past the problem if you do not want to move to EPP
right away here is how to call a 4.x function (but this is not
considered API, as we are planning refactoring how calls are made - they
are done in several different ways atm):
# Note that this requires >= 3.8.1 with future parser or 4.1.0.
#
def call_function(name, args, scope, &block)
# Get the loader that serves the environment - i.e for a call that
# comes from within the environment. This makes all functions in the
# environment (all modules, and environment private function) visible)
# to the caller. (This is somewhat cheating wrt. visibility - i.e.
# 'private' functions which will be supported in a later version).
#
loader = scope.compiler.loaders.private_environment_loader
if loader && func = loader.load(:function, name)
return func.call(scope, *args, &block)
end
# the function was not found... deal with it
end
The above is a modified version of what is used in the puppet runtime,
and should be possible to use in a template - even as a one-liner (in
your case:
scope.compiler.loaders.private_environment_loader.load(:function,
'hiera').call(scope, 'gateway')
Note that the real implementation is also able to call 3.x functions,
and is written to support visibility rules (i.e. handling private
functions. See the method 'call_function' defined in
puppet/pops/evaluator/runtime3_support.rb) if you want to look at the
complete implementation).
Regards
- henrik
--
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 puppet-users+unsubscr...@googlegroups.com
<mailto:puppet-users+unsubscr...@googlegroups.com>.
To view this discussion on the web visit
https://groups.google.com/d/msgid/puppet-users/5b8e076a-6eb2-4640-89e0-96e64cb3101d%40googlegroups.com
<https://groups.google.com/d/msgid/puppet-users/5b8e076a-6eb2-4640-89e0-96e64cb3101d%40googlegroups..com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.
--
Visit my Blog "Puppet on the Edge"
http://puppet-on-the-edge.blogspot.se/
--
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 puppet-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/puppet-users/mk32bq%24u1s%241%40ger.gmane.org.
For more options, visit https://groups.google.com/d/optout.