loop over hash in defined order in ruby template

I have a ruby template (.erb) that I want to iterate over a hash. It should produce the same output file each time the puppet agent runs.

What I currently have is the following. This is my template (part of rsyslog config if anyone is wondering):

<% log_files.each do |log_file, tag| -%>
# <%= log_file %>
$InputFileName <%= log_file %>
$InputFileTag <%= tag %>:

This template is rendered with a hash that looks like this:

log_files => {
  '/root/apache_auth.local' => 'httpd',
  '/root/install.log' => 'hugo',
}, 

(Not real logfiles). This works and produces the config file I want. The problem with this is that each time I call the puppet agent, the order of the log files in the hash is changed, so the config file gets rewritten, and subsequently the daemon gets restarted. The functionality stays the same, but I would rather not have the config file rewritten and rsyslog restarted each time the puppet agent runs.

Now I assume that this is unsolvable with hashes, as their nature is that they do not have a defined order. What other options do I have to achieve what I want?


Since the scriptlets inside an ERB template consist of Ruby code, this is essentially a Ruby question. The possible answers therefore depend on which version of Ruby is running underneath your Puppet catalog compiler. However, although there may be better alternatives in newer Ruby, this variation on your code will work in any Ruby supported by Puppet since Puppet 2.7:

<% @log_files.sort.each do |log_file, tag| -%>
# <%= log_file %>
$InputFileName <%= log_file %>
$InputFileTag <%= tag %>:
<% end -%>

The key here (no pun intended) is the sort .

链接地址: http://www.djcxy.com/p/61428.html

上一篇: OS检测makefile

下一篇: 在ruby模板中按照定义的顺序循环散列